I tried many ways to implement the use case, but none of solutions success.
What I am trying to achieve is (using reactive forms in angular2) a form with two cross field validations:
- Validation of A & B
- Validation of B & C
I tried to create two FormGroups which has references to A & B and B & C FormControls. Each FormGroup has its own validator which validates only it's children. It does not work, because the shared FormControl is the problem: when the value changes, only one validator triggers.
First Try:
this.controlA = new FormControl();
this.controlB = new FormControl();
this.controlC = new FormControl();
this.form = new FormGroup({
ab: new FormGroup({
controlA: this.controlA,
controlB: this.controlB
}, this.validateAB ),
bc: new FormGroup({
controlB: this.controlB,
controlC: this.controlC
}, this.validateBC);
// Validators methods returns a ValidatorFn (which returns null if everything fine or an error object, if validation fails)
Does not work properly.
Try 2:
this.controlA = new FormControl();
this.controlB = new FormControl();
this.controlC = new FormControl();
this.form = new FormGroup({
ab: new FormGroup({
controlA: this.controlA,
controlB: this.controlB
}),
bc: new FormGroup({
controlB: this.controlB,
controlC: this.controlC
});
this.setABValidator(<FormGroup>this.form.get('ab'));
this.setBCValidator(<FormGroup>this.form.get('bc'));
// similar für setBCValidator which triggers this.validateBC(form)
private setABValidator(form: FormGroup): void {
if (form) {
const aCtrl = form.get('controlA');
const bCtrl = form.get('controlB');
if (aCtrl && bCtrl ) {
aCtrl.valueChanges.subscribe((value: any) => {
this.validateAB(form);
});
bCtrl.valueChanges.subscribe((value: any) => {
this.validateAB(form);
});
}
}
}
private validateAB(formGroup: FormGroup): void {
const aCtrl = formGroup.get('controlA');
const bCtrl = formGroup.get('controlB');
const errorKey = 'ERR.AB';
if (aCtrl && bCtrl ) {
if (condition fails) {
ThisCLass.setValidationError(aCtrl , errorKey);
ThisCLass.setValidationError(bCtrl , errorKey);
} else {
ThisCLass.removeValidationError(aCtrl, errorKey);
ThisCLass.removeValidationError(bCtrl, errorKey);
formGroup.updateValueAndValidity();
}
}
}
Its works, but the overall validity of the form is not correct. Do you think its possible in a nice way?