From f7696aef74d54727aa1e3f415926f7cd5bd641eb Mon Sep 17 00:00:00 2001 From: Robert Duda Date: Tue, 1 Apr 2025 14:49:23 +0200 Subject: [PATCH] AAE-33449 HXPMNT-748 Hidden dropdown validation (#10760) --- .../dropdown/dropdown-cloud.widget.spec.ts | 56 ++++++++++++++----- .../widgets/dropdown/dropdown-cloud.widget.ts | 30 +++++++--- .../components/widgets/dropdown/validators.ts | 2 +- 3 files changed, 65 insertions(+), 23 deletions(-) diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.spec.ts b/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.spec.ts index af1564ad46..7335b4bb96 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.spec.ts +++ b/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.spec.ts @@ -18,7 +18,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { of, throwError } from 'rxjs'; -import { DropdownCloudWidgetComponent } from './dropdown-cloud.widget'; +import { DEFAULT_OPTION, DropdownCloudWidgetComponent } from './dropdown-cloud.widget'; import { FormFieldModel, FormModel, FormService, FormFieldEvent, FormFieldTypes } from '@alfresco/adf-core'; import { FormCloudService } from '../../../services/form-cloud.service'; import { ProcessServiceCloudTestingModule } from '../../../../testing/process-service-cloud.testing.module'; @@ -375,22 +375,52 @@ describe('DropdownCloudWidgetComponent', () => { expect(element.querySelector('.adf-invalid')).toBeFalsy(); }); - it('should be valid when field is hidden with empty value', () => { - widget.field.isVisible = false; - fixture.detectChanges(); + describe('and visible', () => { + beforeEach(() => { + widget.field.isVisible = true; + }); - expect(widget.field.isValid).toBeTrue(); - expect(widget.dropdownControl.valid).toBeTrue(); - expect(widget.field.validationSummary.message).toBe(''); + it('should be invalid with no option selected', () => { + fixture.detectChanges(); + + expect(widget.field.isValid).toBeFalse(); + expect(widget.dropdownControl.valid).toBeFalse(); + expect(widget.field.validationSummary.message).toBe('FORM.FIELD.REQUIRED'); + }); + + it('should be invalid with default option selected', () => { + widget.field.hasEmptyValue = true; + widget.field.value = DEFAULT_OPTION; + fixture.detectChanges(); + + expect(widget.field.isValid).toBeFalse(); + expect(widget.dropdownControl.valid).toBeFalse(); + expect(widget.field.validationSummary.message).toBe('FORM.FIELD.REQUIRED'); + }); }); - it('should be invalid when field is hidden with empty value', () => { - widget.field.isVisible = true; - fixture.detectChanges(); + describe('and NOT visible', () => { + beforeEach(() => { + widget.field.isVisible = false; + }); - expect(widget.field.isValid).toBeFalse(); - expect(widget.dropdownControl.valid).toBeFalse(); - expect(widget.field.validationSummary.message).toBe('FORM.FIELD.REQUIRED'); + it('should be valid with no option selected', () => { + fixture.detectChanges(); + + expect(widget.field.isValid).toBeTrue(); + expect(widget.dropdownControl.valid).toBeTrue(); + expect(widget.field.validationSummary.message).toBe(''); + }); + + it('should be valid with default option selected', () => { + widget.field.hasEmptyValue = true; + widget.field.value = DEFAULT_OPTION; + fixture.detectChanges(); + + expect(widget.field.isValid).toBeTrue(); + expect(widget.dropdownControl.valid).toBeTrue(); + expect(widget.field.validationSummary.message).toBe(''); + }); }); }); diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.ts b/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.ts index 36b4e2bd5b..df3b5eadca 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.ts +++ b/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.ts @@ -199,20 +199,32 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI } private updateFormControlState(): void { - const isFieldRequired = this.isRequired(); + this.updateDropdownValidationRules(); + this.updateDropdownReadonlyRules(); + this.dropdownControl.updateValueAndValidity({ emitEvent: false }); + } - this.dropdownControl.setValidators(isFieldRequired && this.field?.isVisible ? [Validators.required] : []); + private updateDropdownValidationRules() { + this.dropdownControl.setValidators([]); - const addSelectDefaultOptionValidator = isFieldRequired && this.field.hasEmptyValue; - if (addSelectDefaultOptionValidator) { - this.dropdownControl.addValidators([defaultValueValidator(this.field)]); + if (!this.field?.isVisible) { + return; } - this.field?.readOnly || this.readOnly - ? this.dropdownControl.disable({ emitEvent: false }) - : this.dropdownControl.enable({ emitEvent: false }); + if (this.isRequired()) { + this.dropdownControl.addValidators([Validators.required]); + if (this.field.hasEmptyValue) { + this.dropdownControl.addValidators([defaultValueValidator(this.field)]); + } + } + } - this.dropdownControl.updateValueAndValidity({ emitEvent: false }); + private updateDropdownReadonlyRules() { + if (this.field?.readOnly || this.readOnly) { + this.dropdownControl.disable({ emitEvent: false }); + } else { + this.dropdownControl.enable({ emitEvent: false }); + } } private handleErrors(): void { diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/validators.ts b/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/validators.ts index 3769d75a2d..d3f153a08b 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/validators.ts +++ b/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/validators.ts @@ -23,7 +23,7 @@ export const defaultValueValidator = (filed: FormFieldModel): ValidatorFn => (control: AbstractControl): ValidationErrors | null => { const optionsWithNoDefaultValue = filed.options.filter((dropdownOption) => { - const isDefaultValue = dropdownOption.id === DEFAULT_OPTION.id && dropdownOption.name === DEFAULT_OPTION.name; + const isDefaultValue = dropdownOption.id === DEFAULT_OPTION.id; return !isDefaultValue; });