Angular custom validators and some weird ones
Marko Berger
Posted on November 27, 2019
After some time I'm at it again. I want to share something with YOU. So that you don’t bang your head on the table as I have. I'm working on an angular & angular material project. So we have basic validation on a numeric input field.
<div class="example-container">
<mat-form-field>
<input matInput
type="number"
placeholder="Some number ..."
[(ngModel)]="someNumber"
#someVal="ngModel"
min="0" max="10">
</mat-form-field>
</div>
Nothing special here. Right? We want to enter a value from 0 to 10. If we use arrows on the control, no problem. But we can input value by hand. So if we enter -2. We would expect to see mat-error message. Wrong. Validator min is not registering that -2 is lower than 0 and by that, it is not throwing an invalid. The same thing is happening if we enter 12. Why?
I don’t know. But I really think it is an issue with min and max validators.
Why should it be easy when it can be complicated.
We need to write some validators.
First, we are going to write a top border value validator.
import { Directive, Input } from '@angular/core';
import { NG_VALIDATORS, Validator, ValidatorFn, AbstractControl, ValidationErrors } from '@angular/forms';
@Directive({
selector: '[maxValueValidator]',
providers: [{provide: NG_VALIDATORS, useExisting: MaxValueValidatorDirective, multi: true}]
})
export class MaxValueValidatorDirective implements Validator{
// our limit value
@Input('maxValueValidator') maxValue: string;
validator: ValidatorFn;
numValue: number;
constructor() { this.numValue = +this.maxValue}
//needed by the Validator interface
validate(control: AbstractControl): ValidationErrors {
return this.maxValueValidator()(control);
}
// If value is valid it will return null
// if it's not it will return {'maxValueValidator': { value: control.value}}
maxValueValidator(): ValidatorFn {
return (control: AbstractControl): {[key: string]: any} | null => {
return control.value > this.maxValue ? {'maxValueValidator': { value: control.value}} : null;
};
}
}
Simple right. (Now you can write the lower border value) .
Custom validators are cool! Right.
<div class="example-container">
<mat-form-field>
<input matInput
type="number"
placeholder="Some number ..."
[(ngModel)]="someNumber"
#someVal="ngModel"
min="0" max="10" minValueValidator="0" maxValueValidator="10">
<mat-error *ngIf="someVal.hasError('minValueValidator')">Number must be positive value!</mat-error>
<mat-error *ngIf="someVal.hasError('maxValueValidator')">Number must be under 10!</mat-error>
</mat-form-field>
</div>
You can view and try this example here. Enjoy.
Posted on November 27, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.