1
votes

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?

1
add some code to see what is the situation!Aniruddha Das
I added two approaches which does not work out for my use caseuser3287019

1 Answers

0
votes

I don't understand why you need two form groups. Just use one which is merging both validations?

This should do the job:

this.form = new FormGroup({
 controlA: this.controlA,
 controlB: this.controlB,
 controlC: this.controlC
}, Validators.compose([this.validateAB, this.validateBC]);