Abhinandan Khilari
Abhinandan Khilari

Reputation: 1077

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

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?

Upvotes: 5

Views: 18451

Answers (2)

Lloyd Nicholson
Lloyd Nicholson

Reputation: 484

I have created a simpler option if you want to use it. No form control validation used.

<div>
  <form [formGroup]="myFormGroup" #formRef="ngForm">
    First number:<input #firstNum type="number" formControlName="firstNumber"><br/>
    Second number:<input #secondNum type="number" formControlName="secondNumber"><br/>
    Third number:<input #thirdNum type="number" formControlName="thirdNumber"><br/>
    <span *ngIf="firstNum && thirdNum && (thirdNum.value > firstNum.value)">
      Third number cannot be greater than First Number
    </span>
    <hr>
    <span *ngIf="secondNum && thirdNum && (thirdNum.value > secondNum.value)">
      Third number cannot be greater than Second Number
    </span>
  </form>
</div>

And delete all validation in your .ts file.

If you start creating larger components then the form validation option would be best.

Upvotes: 0

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

Upvotes: 1

Related Questions