So the min
and max
constraints on number field in your template based form aren’t working? Users can type in out of range values and the form is still valid. What’s happening?
Let’s say you’ve got a form, named myform
, with this input:
<input type="number" [(ngModel)]="model.count" name="count" #count="ngModel" required min="0">
With Angular’s FormsModule
, you get the validation on the required
attribute basically for free. With no further code, if the user doesn’t fill in this input then count.hasError('required')
is true and myform.valid
is false. It’s the same with other attributes like pattern
, maxLength
etc.
However, you don’t get this with min
or max
.
This actually depends on your version of Angular. Angular 4 briefly had it, but it was removed in version 4.2.3). Apparently was a breaking change for some, but not for me, so let’s get it back.
The angular/forms
package still has all the validation code we need, all we have to do is create our own directive. Here it is:
import { Directive, Input, forwardRef } from "@angular/core";
import {
Validator, AbstractControl, NG_VALIDATORS, Validators, ValidatorFn
} from "@angular/forms";
@Directive({
selector: "[min][formControlName],[min][formControl],[min][ngModel]",
providers: [
{ provide: NG_VALIDATORS,
useExisting: forwardRef(() => MinDirective),
multi: true }
]
})
export class MinDirective implements Validator {
private _validator: ValidatorFn;
@Input() public set min(value: string) {
this._validator = Validators.min(parseInt(value, 10));
}
public validate(control: AbstractControl): { [key: string]: any } {
return this._validator(control);
}
}
Create another one for max
, add it into the declarations in your module, and you’re all set.