When filling out a form with four fields, I have encountered a specific requirement. Two of the fields are mandatory, which is straightforward. However, the other two must either both be empty or both have a value - essentially resembling an XNOR logic state.
s1_male s1_female s1_male_valid s1_female_valid
empty empty true true
value empty false false
empty value false false
value value true true
Although the code below functions correctly, it does not update the UI appropriately. For example, if I input a value in 's1_male', it marks as invalid but 's1_female' remains unflagged. Even after entering a value in 's1_female', it still appears valid while 's1_male' is indicated as invalid. In such cases, I find myself going back to 's1_male' and either modifying or deleting the value to resolve the issue.
I attempted calling updateValueAndValidity()
on both fields within the provided function, yet this action triggers an endless loop causing Chrome to eventually terminate.
formGroup.addControl('rx_male', new FormControl('', Validators.required));
formGroup.addControl('rx_female', new FormControl('', Validators.required));
formGroup.addControl('s1_male', new FormControl('', this.scaleOptionValidator(formGroup)));
formGroup.addControl('s1_female', new FormControl('', this.scaleOptionValidator(formGroup)));
// these line cause endless loop
formGroup.controls.s1_male.valueChanges.subscribe(value => {
formGroup.controls.s1_female.updateValueAndValidity();
});
formGroup.controls.s1_female.valueChanges.subscribe(value => {
formGroup.controls.s1_male.updateValueAndValidity();
});
...
private scaleOptionValidator(formGroup: FormGroup): ValidatorFn {
return (control: AbstractControl): { [key: string]: boolean } | null => {
let isValid = false;
const female = formGroup.controls.s1_female;
const male = formGroup.controls.s1_male;
if (male && female) {
if ((male.value && female.value) || (!male.value && !female.value)) {
isValid = true;
}
return isValid ? null : { scalseNotValid: true };
}
return null;
};
}
Any suggestions would be greatly appreciated.
UPDATE: It seems that the formgroup approach is effective, however, I am also using Ionic here where, frustratingly, the ng-invalid class is applied but the ion-valid class overrides the UI styling until selecting and then deselecting the input field.