From 6e4179f6454d7ffbd1b5161689927856f0f65006 Mon Sep 17 00:00:00 2001 From: erdemcaygor Date: Thu, 9 Oct 2025 16:59:06 +0300 Subject: [PATCH] reset form function added --- .../dynamic-form-field.component.html | 169 +++++++++--------- .../dynamic-form-field.component.ts | 37 ++-- .../src/dynamic-form.component.html | 2 +- .../src/dynamic-form.component.ts | 37 ++-- .../dynamic-form/src/dynamic-form.models.ts | 2 +- .../dynamic-form/src/dynamic-form.service.ts | 22 ++- 6 files changed, 155 insertions(+), 114 deletions(-) diff --git a/npm/ng-packs/packages/components/dynamic-form/src/dynamic-form-field/dynamic-form-field.component.html b/npm/ng-packs/packages/components/dynamic-form/src/dynamic-form-field/dynamic-form-field.component.html index a1044eba17..b2b95a5e3c 100644 --- a/npm/ng-packs/packages/components/dynamic-form/src/dynamic-form-field/dynamic-form-field.component.html +++ b/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') { - -
- - - @if (isInvalid) { - - } -
- } @else if (field().type === 'select') { - -
- - + @if (isInvalid) { + } - - @if (isInvalid) { - - } -
- } @else if (field().type === 'checkbox') { - -
- - - @if (isInvalid) { - - } -
- } @else if (field().type === 'email') { - -
- - - @if (isInvalid) { - - } -
- } @else if (field().type === 'textarea') { - -
- - - @if (isInvalid) { - - } -
- } + @if (isInvalid) { + + } + + } + } diff --git a/npm/ng-packs/packages/components/dynamic-form/src/dynamic-form-field/dynamic-form-field.component.ts b/npm/ng-packs/packages/components/dynamic-form/src/dynamic-form-field/dynamic-form-field.component.ts index d7f0e2ecec..0d820a1711 100644 --- a/npm/ng-packs/packages/components/dynamic-form/src/dynamic-form-field/dynamic-form-field.component.ts +++ b/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(); visible = input(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 = () => {}; } diff --git a/npm/ng-packs/packages/components/dynamic-form/src/dynamic-form.component.html b/npm/ng-packs/packages/components/dynamic-form/src/dynamic-form.component.html index c71afcf646..303365d960 100644 --- a/npm/ng-packs/packages/components/dynamic-form/src/dynamic-form.component.html +++ b/npm/ng-packs/packages/components/dynamic-form/src/dynamic-form.component.html @@ -1,5 +1,5 @@
-
+
@for (field of sortedFields; track field.key) {
diff --git a/npm/ng-packs/packages/components/dynamic-form/src/dynamic-form.component.ts b/npm/ng-packs/packages/components/dynamic-form/src/dynamic-form.component.ts index 573335b638..e0a149e025 100644 --- a/npm/ng-packs/packages/components/dynamic-form/src/dynamic-form.component.ts +++ b/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([]); submitButtonText = input('Submit'); submitInProgress = input(false); showCancelButton = input(false); - formSubmit = output(); + onSubmit = output(); formCancel = output(); 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); + }); } }); } diff --git a/npm/ng-packs/packages/components/dynamic-form/src/dynamic-form.models.ts b/npm/ng-packs/packages/components/dynamic-form/src/dynamic-form.models.ts index 9ba75484c5..8323a84ade 100644 --- a/npm/ng-packs/packages/components/dynamic-form/src/dynamic-form.models.ts +++ b/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; } diff --git a/npm/ng-packs/packages/components/dynamic-form/src/dynamic-form.service.ts b/npm/ng-packs/packages/components/dynamic-form/src/dynamic-form.service.ts index 4399e8822d..d5c90bc70a 100644 --- a/npm/ng-packs/packages/components/dynamic-form/src/dynamic-form.service.ts +++ b/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; }