From b91eab5c996fe12f5f007caaa0ff208c88de99de Mon Sep 17 00:00:00 2001 From: Wouter Willems Date: Tue, 2 Jul 2024 14:43:41 +0200 Subject: [PATCH] support formLevel errors --- .../demo/src/app/demo/demo.component.html | 15 +++++++++++ projects/demo/src/app/demo/demo.component.ts | 23 ++++++++++++++-- .../klippa/ngx-enhancy-forms/package.json | 2 +- .../form-element/form-element.component.html | 1 + .../form-element/form-element.component.ts | 3 +++ .../src/lib/form/form.component.ts | 27 +++++++++++++++++++ .../klippa/ngx-enhancy-forms/src/lib/types.ts | 1 + 7 files changed, 69 insertions(+), 3 deletions(-) diff --git a/projects/demo/src/app/demo/demo.component.html b/projects/demo/src/app/demo/demo.component.html index 1830311..2df4902 100644 --- a/projects/demo/src/app/demo/demo.component.html +++ b/projects/demo/src/app/demo/demo.component.html @@ -193,3 +193,18 @@ This can be ANYTHING. Look at me me, i am BOLD AND GREEN + +simple form with form level errors + + + + + + + + + + + + Save + diff --git a/projects/demo/src/app/demo/demo.component.ts b/projects/demo/src/app/demo/demo.component.ts index d0a7e3f..2032e0f 100644 --- a/projects/demo/src/app/demo/demo.component.ts +++ b/projects/demo/src/app/demo/demo.component.ts @@ -10,6 +10,7 @@ import {AppSelectOptions, SelectComponent} from '@klippa/ngx-enhancy-forms'; export class DemoComponent { @ViewChild('myFancyTemplate') myFancyTemplate: TemplateRef; public formWarnings = new Map>(); + public formErrors = new Map(); constructor(private fb: FormBuilder) { setTimeout(() => { @@ -79,7 +80,7 @@ export class DemoComponent { show = false; isChecked: boolean = undefined; - private nameConfig = ['', [Validators.required, Validators.minLength(4)], + private nameConfig = ['', [], [(e) => { if (e.value?.length > 5) { return Promise.resolve(); @@ -93,7 +94,7 @@ export class DemoComponent { if (e.value?.length > 2) { return Promise.resolve({async: 'daapaaa aaaaaaap aaaaap'}); } - return Promise.resolve({async: 'aapaaa '}); + return Promise.resolve({}); }] ]; @@ -123,6 +124,11 @@ export class DemoComponent { radioOption: null }); + public simpleFormWithFormLevelErrors = this.fb.group({ + firstName: ['', [Validators.required]], + lastName: [''], + }); + subForms = []; options: AppSelectOptions = [ {id: 1, name: 'dra'}, @@ -234,6 +240,19 @@ export class DemoComponent { await new Promise(resolve => setTimeout(resolve, 1000)); throw new Error('some error'); } + public saveSimple = async () => { + console.log('saving simple form'); + console.log(this.simpleFormWithFormLevelErrors.get('firstName').errors); + this.formErrors.clear(); + await new Promise((resolve, reject) => { + setTimeout(resolve, 1200); + }); + if (new Date().getMilliseconds() > 500) { + this.formErrors.set(this.simpleFormWithFormLevelErrors.get('firstName'), 'Your first name is not cool enough'); + } + this.formErrors.set(this.simpleFormWithFormLevelErrors.get('lastName'), 'Your last name makes no sense'); + console.log(this.simpleFormWithFormLevelErrors.get('firstName').errors); + }; blurry() { console.log('blurr'); diff --git a/projects/klippa/ngx-enhancy-forms/package.json b/projects/klippa/ngx-enhancy-forms/package.json index aa255d0..51369cf 100644 --- a/projects/klippa/ngx-enhancy-forms/package.json +++ b/projects/klippa/ngx-enhancy-forms/package.json @@ -1,6 +1,6 @@ { "name": "@klippa/ngx-enhancy-forms", - "version": "14.20.5", + "version": "14.21.0", "publishConfig": { "access": "public" }, diff --git a/projects/klippa/ngx-enhancy-forms/src/lib/form/form-element/form-element.component.html b/projects/klippa/ngx-enhancy-forms/src/lib/form/form-element/form-element.component.html index 075876b..db80a64 100644 --- a/projects/klippa/ngx-enhancy-forms/src/lib/form/form-element/form-element.component.html +++ b/projects/klippa/ngx-enhancy-forms/src/lib/form/form-element/form-element.component.html @@ -68,6 +68,7 @@
{{getErrorMessage("matchPassword")}}
{{getErrorMessage("date")}}
{{attachedControl.errors.message.value}}
+
{{getErrorMessage("formLevel")}}
diff --git a/projects/klippa/ngx-enhancy-forms/src/lib/form/form-element/form-element.component.ts b/projects/klippa/ngx-enhancy-forms/src/lib/form/form-element/form-element.component.ts index 17ff7a5..ee87f4a 100644 --- a/projects/klippa/ngx-enhancy-forms/src/lib/form/form-element/form-element.component.ts +++ b/projects/klippa/ngx-enhancy-forms/src/lib/form/form-element/form-element.component.ts @@ -193,6 +193,9 @@ export class FormElementComponent implements AfterViewInit { } getErrorMessage(key: keyof FormErrorMessages): string { + if (key === 'formLevel') { + return this.attachedControl.errors?.formLevel; + } return this.customMessages?.[key]?.() ?? this.errorMessages[key]; } diff --git a/projects/klippa/ngx-enhancy-forms/src/lib/form/form.component.ts b/projects/klippa/ngx-enhancy-forms/src/lib/form/form.component.ts index f1f900f..3add587 100644 --- a/projects/klippa/ngx-enhancy-forms/src/lib/form/form.component.ts +++ b/projects/klippa/ngx-enhancy-forms/src/lib/form/form.component.ts @@ -37,6 +37,7 @@ export class FormComponent implements OnInit, OnDestroy, OnChanges { @Input() public errorMessageLocation: 'belowCaption' | 'rightOfCaption' = 'belowCaption'; @Input() public formGroup: UntypedFormGroup; @Input() public warnings: Map> = new Map>(); + @Input() public errors: Map = new Map(); @Input() public patchValueInterceptor: (values: any) => Promise; @Output() public onInjected = new EventEmitter>(); @@ -93,6 +94,9 @@ export class FormComponent implements OnInit, OnDestroy, OnChanges { if (isValueSet(simpleChanges.warnings?.currentValue)) { this.patchFormWarningsMap(); } + if (isValueSet(simpleChanges.errors?.currentValue)) { + this.patchFormErrorsMap(); + } } ngOnDestroy(): void { @@ -130,6 +134,29 @@ export class FormComponent implements OnInit, OnDestroy, OnChanges { }; } + private patchFormErrorsMap(): void { + const setFn = this.errors.set; + this.errors.set = (key: AbstractControl, value: string): Map => { + const prevVal = this.errors.get(key); + const result = setFn.call(this.errors, key, value); + key.setErrors({ ...key.errors, formLevel: value}); + if (prevVal !== value) { + this.getFormElementByFormControl(key)?.determinePopupState(); + } + return result; + }; + + const deleteFn = this.errors.delete; + this.errors.delete = (key: AbstractControl): boolean => { + const newErrorsObject = key.errors; + delete newErrorsObject.formLevel; + key.setErrors(newErrorsObject); + const result = deleteFn.call(this.errors, key); + this.getFormElementByFormControl(key)?.determinePopupState(); + return result; + }; + } + private addSupportForPatchValueInterceptor(): void { const fn = this.formGroup.patchValue; const newFn = ( diff --git a/projects/klippa/ngx-enhancy-forms/src/lib/types.ts b/projects/klippa/ngx-enhancy-forms/src/lib/types.ts index c726c56..9da888a 100644 --- a/projects/klippa/ngx-enhancy-forms/src/lib/types.ts +++ b/projects/klippa/ngx-enhancy-forms/src/lib/types.ts @@ -10,6 +10,7 @@ export interface FormErrorMessages { pattern: string; matchPassword: string; date: string; + formLevel?: string; } export type CustomErrorMessages = Record string>;