Angular: Trigger a form control validation on change of another form control

Abhinandan Khilari picture Abhinandan Khilari · Apr 18, 2019 · Viewed 9.8k times · Source

Please refer the project in a stackblitz here.

As can be seen, I have reactive form with controls as firstNumber, secondNumber and thirdNumber. I need to have validation for form control thirdNumber such that its value should not be greater than the value of the form control which is having minimum value among firstNumber and secondNumber.

The custom validator validateThirdNumber which is there in the component works fine whenever form control thirdNumber changes, but I need fire its validation on changes of form controls firstNumber and secondNumber too as the validation logic can change on changes of form controls firstNumber and secondNumber.

For that purpose, I have added an event on change of form controls firstNumber and secondNumber where I am marking the form control thirdNumber as touched but its validation did not seem to be triggered.

So, how to fire the validation for form control thirdNumber on changes of form controls firstNumber and secondNumber?

Also, why is this.myFormGroup is undefined some times in custom validator (refer logs in app.componen.ts at line:22) even after binding this to its form control declaration and this.myFormGroup is defined in the constructor?

Answer

Mohamed chiheb Ben jemaa picture Mohamed chiheb Ben jemaa · Apr 18, 2019

the best choice for you is to create your own custom global validator.

class ValidateThirdNumber {
    static validate(control: AbstractControl) {
          console.log(control);
        if(control) {
           const firstNumber = control.get('firstNumber').value;
           const secondNumber = control.get('secondNumber').value;
           const thirdnumber = control.get('thirdNumber').value;
        if (firstNumber > secondNumber) {
          if (thirdnumber > secondNumber) {
            control.get('thirdNumber').setErrors( {greaterThanSecondNumber: true} );   
          }
        } else if (firstNumber < secondNumber) {
          if (thirdnumber > firstNumber) {
              control.get('thirdNumber').setErrors( {greaterThanFirstNumber: true} ); 
          }
        }
        }
        return null;
        }
}

the initialization of form group should be:

 this.myFormGroup = this.fb.group({
      firstNumber: [0],
      secondNumber: [0],
      thirdNumber: [0]
    }, {validator: [ValidateThirdNumber.validate] });

you don't need the touched attribute any more

<span *ngIf="myFormGroup.get('thirdNumber').errors?.greaterThanFirstNumber">
  Third number cannot be greater than First Number
 </span>
    <span *ngIf=" myFormGroup.get('thirdNumber').errors?.greaterThanSecondNumber">
  Third number cannot be greater than Second Number
 </span>

also you don't need the (change) events remove them