angulartypescriptangular-abstract-control

How do you create a Custom Validator that displays a custom error message?


I have an Angular front-end that uses a custom validator to enforce that a component in a p-dialog needs to have a value between 0 and 10.

The validator works just fine as far as it prevents the user from submitting the form if the field contains a value that is not between 0 and 10. If the user inputs a value of 11, for example, the field turns red and the submit button is disabled.

However, I would also like to display a message to the user of why they can't submit. Something like "You must enter a value between 0 and 10"

This is the HTML code:

<p-dialog header="My Dialog">
  <form [formGroup]="createForm">
    <ng-container>
  
      <input
        id="age"
        pInputText
        maxlength="30"
        formControlName="age"
        [style]="{width: '25vw'}">

    </ng-container>
  </form>
</p-dialog>

This is my ngOnInit function:

ngOnInit() {
    super.ngOnInit();
    this.createForm = this.fb.group({
      'age' : new FormControl(null, [this.ageRangeValidator])
    });
}

And this is my validator function:

ageRangeValidator(control: AbstractControl): { [key: string]: boolean } | null {

    if (control.value !== undefined && (isNaN(control.value) || control.value < 0 || control.value > 10)) {
        return { 'ageRange': true };
    }
    return null;
}

Solution

  • The simplistic way would be something like:

    <p-dialog header="My Dialog">
      <form [formGroup]="createForm">
        <ng-container>
      
          <input
            id="age"
            pInputText
            maxlength="30"
            formControlName="age"
            [style]="{width: '25vw'}">
          <span *ngIf="age.errors?.ageRange">Age Range Specific Error Message</span>
        </ng-container>
      </form>
    </p-dialog>
    

    After you validation is run, the age FormControl should then set a ValiationErrors to the errors property.

    Sometimes this leads to asking, how do I not show this error message until the user has tried to change it's value:

          <span *ngIf="age.dirty && age.errors?.ageRange">Your Error Message</span>
    

    (this assumes you expose the control directly on your component:)

    public age: FormControl;
    ngOnInit() {
        super.ngOnInit();
        this.age = new FormControl(null, [this.ageRangeValidator]); 
        this.createForm = this.fb.group({
          'age' : this.age,
        });
    }