Browse Source

reset form function added

pull/24547/head
erdemcaygor 11 months ago
parent
commit
6e4179f645
  1. 169
      npm/ng-packs/packages/components/dynamic-form/src/dynamic-form-field/dynamic-form-field.component.html
  2. 37
      npm/ng-packs/packages/components/dynamic-form/src/dynamic-form-field/dynamic-form-field.component.ts
  3. 2
      npm/ng-packs/packages/components/dynamic-form/src/dynamic-form.component.html
  4. 37
      npm/ng-packs/packages/components/dynamic-form/src/dynamic-form.component.ts
  5. 2
      npm/ng-packs/packages/components/dynamic-form/src/dynamic-form.models.ts
  6. 22
      npm/ng-packs/packages/components/dynamic-form/src/dynamic-form.service.ts

169
npm/ng-packs/packages/components/dynamic-form/src/dynamic-form-field/dynamic-form-field.component.html

@ -1,92 +1,89 @@
@if (visible()) {
@if (field().type === 'text') {
<!-- Text Input -->
<div class="form-group">
<ng-container [ngTemplateOutlet]="labelTemplate" />
<input
[id]="field().key"
[placeholder]="field().placeholder || ''"
[ngModel]="value"
(ngModelChange)="onValueChange($event)"
[class.is-invalid]="isInvalid"
class="form-control">
@if (isInvalid) {
<ng-container [ngTemplateOutlet]="errorTemplate"/>
}
</div>
} @else if (field().type === 'select') {
<!-- Select Dropdown -->
<div class="form-group">
<ng-container [ngTemplateOutlet]="labelTemplate" />
<select
[id]="field().key"
[ngModel]="value"
(ngModelChange)="onValueChange($event)"
[class.is-invalid]="isInvalid"
class="form-control">
<option value="">Please select...</option>
@for (option of field().options; track option.key) {
<option
[value]="option.key">
{{ option.value }}
</option>
<div [formGroup]="fieldFormGroup">
@if (field().type === 'text') {
<!-- Text Input -->
<div class="form-group">
<ng-container [ngTemplateOutlet]="labelTemplate" />
<input
[id]="field().key"
[placeholder]="field().placeholder || ''"
formControlName="value"
[class.is-invalid]="isInvalid"
class="form-control">
@if (isInvalid) {
<ng-container [ngTemplateOutlet]="errorTemplate"/>
}
</select>
@if (isInvalid) {
<ng-container [ngTemplateOutlet]="errorTemplate"/>
}
</div>
} @else if (field().type === 'checkbox') {
<!-- Checkbox -->
<div class="form-group form-check">
<input
type="checkbox"
[id]="field().key"
[ngModel]="value"
(ngModelChange)="onValueChange($event)"
[class.is-invalid]="isInvalid"
class="form-check-input">
<label class="form-check-label" [for]="field().key">
{{ field().label | abpLocalization }}
</label>
@if (isInvalid) {
<ng-container [ngTemplateOutlet]="errorTemplate"/>
}
</div>
} @else if (field().type === 'email') {
<!-- Email Input -->
<div class="form-group">
<label [for]="field().key">{{ field().label }}</label>
<input
type="email"
[id]="field().key"
[ngModel]="value"
(ngModelChange)="onValueChange($event)"
[placeholder]="field().placeholder || ''"
[class.is-invalid]="isInvalid"
class="form-control">
@if (isInvalid) {
<ng-container [ngTemplateOutlet]="errorTemplate"/>
}
</div>
} @else if (field().type === 'textarea') {
<!-- Textarea -->
<div class="form-group">
<label [for]="field().key">{{ field().label }}</label>
<textarea
[id]="field().key"
[ngModel]="value"
(ngModelChange)="onValueChange($event)"
[placeholder]="field().placeholder || ''"
[class.is-invalid]="isInvalid"
rows="4"
class="form-control">
</div>
} @else if (field().type === 'select') {
<!-- Select Dropdown -->
<div class="form-group">
<ng-container [ngTemplateOutlet]="labelTemplate" />
<select
[id]="field().key"
formControlName="value"
[class.is-invalid]="isInvalid"
class="form-control">
<option value="">Please select...</option>
@for (option of field().options; track option.key) {
<option
[value]="option.key">
{{ option.value }}
</option>
}
</select>
@if (isInvalid) {
<ng-container [ngTemplateOutlet]="errorTemplate"/>
}
</div>
} @else if (field().type === 'checkbox') {
<!-- Checkbox -->
<div class="form-group form-check">
<input
type="checkbox"
[id]="field().key"
formControlName="value"
[class.is-invalid]="isInvalid"
class="form-check-input">
<label class="form-check-label" [for]="field().key">
{{ field().label | abpLocalization }}
</label>
@if (isInvalid) {
<ng-container [ngTemplateOutlet]="errorTemplate"/>
}
</div>
} @else if (field().type === 'email') {
<!-- Email Input -->
<div class="form-group">
<label [for]="field().key">{{ field().label }}</label>
<input
type="email"
[id]="field().key"
formControlName="value"
[placeholder]="field().placeholder || ''"
[class.is-invalid]="isInvalid"
class="form-control">
@if (isInvalid) {
<ng-container [ngTemplateOutlet]="errorTemplate"/>
}
</div>
} @else if (field().type === 'textarea') {
<!-- Textarea -->
<div class="form-group">
<label [for]="field().key">{{ field().label }}</label>
<textarea
[id]="field().key"
formControlName="value"
[placeholder]="field().placeholder || ''"
[class.is-invalid]="isInvalid"
rows="4"
class="form-control">
</textarea>
@if (isInvalid) {
<ng-container [ngTemplateOutlet]="errorTemplate"/>
}
</div>
}
@if (isInvalid) {
<ng-container [ngTemplateOutlet]="errorTemplate"/>
}
</div>
}
</div>
}
<ng-template #labelTemplate>

37
npm/ng-packs/packages/components/dynamic-form/src/dynamic-form-field/dynamic-form-field.component.ts

@ -12,12 +12,15 @@ import {
import { FormFieldConfig } from '../dynamic-form.models';
import {
ControlValueAccessor,
FormBuilder,
FormControl,
FormControlName,
FormGroupDirective,
FormsModule,
NG_VALUE_ACCESSOR,
NgControl
NgControl,
FormGroup,
ReactiveFormsModule,
} from '@angular/forms';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { NgTemplateOutlet } from '@angular/common';
@ -42,32 +45,36 @@ const DYNAMIC_FORM_FIELD_CONTROL_VALUE_ACCESSOR = {
host: { class: 'abp-dynamic-form-field' },
exportAs: 'abpDynamicFormField',
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [FormsModule, NgTemplateOutlet, LocalizationPipe],
imports: [FormsModule, NgTemplateOutlet, LocalizationPipe, ReactiveFormsModule],
})
export class DynamicFormFieldComponent implements OnInit, ControlValueAccessor {
field = input.required<FormFieldConfig>();
visible = input<boolean>(true);
disabled = false;
value: any;
control!: FormControl;
fieldFormGroup: FormGroup;
readonly changeDetectorRef = inject(ChangeDetectorRef);
readonly destroyRef = inject(DestroyRef);
private injector = inject(Injector);
private formBuilder = inject(FormBuilder);
constructor() {
this.fieldFormGroup = this.formBuilder.group({
value: [{ value: '' }]
});
}
ngOnInit() {
const ngControl = this.injector.get(NgControl, null);
if (ngControl) {
this.control = this.injector.get(FormGroupDirective).getControl(ngControl as FormControlName);
}
}
onValueChange(value: any) {
this.onChange(value);
this.changeDetectorRef.markForCheck();
this.value.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(value => {
this.onChange(value);
});
}
writeValue(value: any[]): void {
this.value = value;
this.value.setValue(value || '');
this.changeDetectorRef.markForCheck();
}
@ -80,7 +87,11 @@ export class DynamicFormFieldComponent implements OnInit, ControlValueAccessor {
}
setDisabledState(isDisabled: boolean): void {
this.disabled = isDisabled;
if (isDisabled) {
this.value.disable();
} else {
this.value.enable();
}
this.changeDetectorRef.markForCheck();
}
@ -109,7 +120,9 @@ export class DynamicFormFieldComponent implements OnInit, ControlValueAccessor {
});
}
}
get value() {
return this.fieldFormGroup.get('value');
}
private onChange: (value: any) => void = () => {};
private onTouched: () => void = () => {};
}

2
npm/ng-packs/packages/components/dynamic-form/src/dynamic-form.component.html

@ -1,5 +1,5 @@
<div class="form-wrapper">
<form [formGroup]="dynamicForm" (ngSubmit)="onSubmit()" class="dynamic-form">
<form [formGroup]="dynamicForm" (ngSubmit)="submit()" class="dynamic-form">
<div class="row">
@for (field of sortedFields; track field.key) {
<div [ngClass]="'col-md-' + (field.gridSize || 12)">

37
npm/ng-packs/packages/components/dynamic-form/src/dynamic-form.component.ts

@ -6,10 +6,9 @@ import {
inject,
OnInit,
DestroyRef,
effect,
ChangeDetectorRef,
ChangeDetectorRef
} from '@angular/core';
import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms';
import { FormGroup, ReactiveFormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { DynamicFormService } from './dynamic-form.service';
@ -22,15 +21,15 @@ import { DynamicFormFieldComponent } from './dynamic-form-field';
styleUrls: ['./dynamic-form.component.scss'],
host: { class: 'abp-dynamic-form' },
changeDetection: ChangeDetectionStrategy.OnPush,
exportAs: 'abpDynamicForm',
imports: [CommonModule, DynamicFormFieldComponent, ReactiveFormsModule],
})
export class DynamicFormComponent implements OnInit {
fields = input<FormFieldConfig[]>([]);
submitButtonText = input<string>('Submit');
submitInProgress = input<boolean>(false);
showCancelButton = input<boolean>(false);
formSubmit = output<void>();
onSubmit = output<any>();
formCancel = output<void>();
private dynamicFormService = inject(DynamicFormService);
readonly destroyRef = inject(DestroyRef);
@ -47,9 +46,10 @@ export class DynamicFormComponent implements OnInit {
return this.fields().sort((a, b) => (a.order || 0) - (b.order || 0));
}
onSubmit() {
submit() {
console.log(this.dynamicForm.valid, this.dynamicForm.value);
if (this.dynamicForm.valid) {
this.formSubmit.emit(this.dynamicForm.value);
this.onSubmit.emit(this.dynamicForm.getRawValue());
} else {
this.markAllFieldsAsTouched();
}
@ -70,9 +70,22 @@ export class DynamicFormComponent implements OnInit {
return this.fieldVisibility[field.key] !== false;
}
resetForm() {
const initialValues: { [key: string]: any } = this.dynamicFormService.getInitialValues(
this.fields(),
);
this.dynamicForm.reset({...initialValues});
this.dynamicForm.markAsUntouched();
this.dynamicForm.markAsPristine();
this.changeDetectorRef.markForCheck();
}
private initializeFieldVisibility() {
this.fields().forEach(field => {
this.fieldVisibility = { ...this.fieldVisibility, [field.key]: !field.conditionalLogic?.length };
this.fieldVisibility = {
...this.fieldVisibility,
[field.key]: !field.conditionalLogic?.length,
};
});
}
@ -83,9 +96,11 @@ export class DynamicFormComponent implements OnInit {
const dependentControl = this.dynamicForm.get(rule.dependsOn);
if (dependentControl) {
this.evaluateConditionalLogic(field.key);
dependentControl.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
this.evaluateConditionalLogic(field.key);
});
dependentControl.valueChanges
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(() => {
this.evaluateConditionalLogic(field.key);
});
}
});
}

2
npm/ng-packs/packages/components/dynamic-form/src/dynamic-form.models.ts

@ -14,7 +14,7 @@ export interface FormFieldConfig {
}
export interface ValidatorConfig {
type: 'required' | 'email' | 'minLength' | 'maxLength' | 'pattern' | 'custom';
type: 'required' | 'email' | 'minLength' | 'maxLength' | 'pattern' | 'custom' | 'min' | 'max' | 'requiredTrue';
value?: any;
message: string;
}

22
npm/ng-packs/packages/components/dynamic-form/src/dynamic-form.service.ts

@ -1,5 +1,5 @@
import {Injectable} from '@angular/core';
import {FormControl, FormGroup, ValidatorFn, Validators} from '@angular/forms';
import {Injectable, inject} from '@angular/core';
import {FormControl, FormGroup, ValidatorFn, Validators, FormBuilder} from '@angular/forms';
import {FormFieldConfig, ValidatorConfig} from './dynamic-form.models';
@Injectable({
@ -8,6 +8,8 @@ import {FormFieldConfig, ValidatorConfig} from './dynamic-form.models';
export class DynamicFormService {
private formBuilder = inject(FormBuilder);
createFormGroup(fields: FormFieldConfig[]): FormGroup {
const group: any = {};
@ -21,7 +23,15 @@ export class DynamicFormService {
}, validators);
});
return new FormGroup(group);
return this.formBuilder.group(group);
}
getInitialValues(fields: FormFieldConfig[]): any {
const initialValues: any = {};
fields.forEach(field => {
initialValues[field.key] = this.getInitialValue(field);
});
return initialValues;
}
private buildValidators(validatorConfigs: ValidatorConfig[]): ValidatorFn[] {
@ -37,6 +47,12 @@ export class DynamicFormService {
return Validators.maxLength(config.value);
case 'pattern':
return Validators.pattern(config.value);
case 'min':
return Validators.min(config.value);
case 'max':
return Validators.max(config.value);
case 'requiredTrue':
return Validators.requiredTrue;
default:
return Validators.nullValidator;
}

Loading…
Cancel
Save