3

I am working on a small project written in Angular 8 and Angular Material.

I have a number field where I want to specify min and max values, however I couldn't find any documentation on how to do that in the matInput documentation.

Question: Does matInput support min/max validations? What is the best way of validation number fields in Angular Material?

So far I tried the standard html5 min and max properties which unfortunately are not caught by the validation engine. I also tried some examples from the internet which turned to be not working in Angular 8.

1

6 Answers 6

4

In order to validate the content of a matInput you can wrap it in a mat-form-field like so:

<form class="example-form"> <mat-form-field class="example-full-width"> <input matInput [formControl]="numberFormControl"> <mat-error *ngIf="numberFormControl.hasError('min')"> The value is lower than the minimum </mat-error> <mat-error *ngIf="numberFormControl.hasError('max')"> The value is greater than the maximum </mat-error> </mat-form-field> </form> 

And use form control for the validators:

import {Component} from '@angular/core'; import {FormControl, Validators} from '@angular/forms'; @Component({ selector: 'input-errors-example', templateUrl: 'input-errors-example.html', styleUrls: ['input-errors-example.css'], }) export class InputErrorsExample { numberFormControl = new FormControl('', [ Validators.min(3), Validators.max(6), ]); } 

This works for minimum and maximum values, you can use the minlength and maxlength validators in the same fashion, the documentation is here:

https://angular.io/api/forms/Validators

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you (+1). How to use this approach in combination with [(ngModel)]?
The cool thing about FormControl is you have everything (value and validation of the input field) centralized in one object instance. Now if you still need to use [(ngModel)], you can just use it in the input field like so: <input matInput [formControl]="numberFormControl" [(ngModel)]="yourVariable"> and then check the formGroup for validity. This should tell you whether the value in the input field is valid or not this.numberFormControl.valid.
But remember you can always access the value of the formControl without using [(ngModel)] with this.numberFormControl.value, and it even has an observable that will trigger everytime the value changes in this.numberFormControl.valueChanges I hope that helped.
3

You can use the reactive approach for creating forms. These might seem to be scary in the first time, but in the end it will be super helpful in setting up different validators.

Step 1: Import dependencies

import { ReactiveFormsModule } from '@angular/forms'; @NgModule({ imports: [ // other imports ... ReactiveFormsModule ], }) export class AppModule { } 

Step 2: Create a new FormObject

import { Component } from '@angular/core'; import { FormGroup, FormControl } from '@angular/forms'; @Component({ selector: 'app-profile-editor', templateUrl: './profile-editor.component.html', styleUrls: ['./profile-editor.component.css'] }) export class ProfileEditorComponent { profileForm = new FormGroup({ firstName: new FormControl(''), lastName: new FormControl(''), }); } 

Step 3: Create the template

<form [formGroup]="profileForm"> <label> First Name: <input type="text" formControlName="firstName"> </label> <label> Last Name: <input type="text" formControlName="lastName"> </label> </form> 

Step 4: Add validators

import { Component } from '@angular/core'; import { FormGroup, FormControl } from '@angular/forms'; @Component({ selector: 'app-profile-editor', templateUrl: './profile-editor.component.html', styleUrls: ['./profile-editor.component.css'] }) export class ProfileEditorComponent { profileForm = new FormGroup({ firstName: ['', Validators.required, Validators.min(3)], lastName: ['', Validators.required, Validators.min(3)] }); } 

Comments

3

I recommend you use Reactive Forms as it will make your business logic stay in the ts code, keeping your templates easier to read and maintain.

sampleForm = new FormGroup({}) // Instantiating our form constructor(private fb: FormBuilder){ // Injecting the ReactiveForms FormBuilder. this.sampleForm = fb.group({ // Adding the "age" input to our FormGroup along with its min-max Validators. 'age': ['', [Validators.min(5), Validators.max(10)]] }) } 

And your html

<form [formGroup]="sampleForm "> <label for="age">Age</label> <!-- formControlName will bind the age field declared in the ts code. --> <input type='number' id="age" formControlName="age"> </form> 

Comments

1

Angular template-driven forms are not able to Validate the min and max HTML5 validation by default - It's a framework issue. Either you write a directive to solve this issue or else a simpler solution is to validate the form on submit.

the problem I am stating can be seen and tested here https://stackblitz.com/edit/angular-input-min-max?file=src/app/app.component.html

A few directives are available, one I was able to find but its has some issues as well. Try yourself

https://www.concretepage.com/angular-2/angular-4-min-max-validation#Template-driven

the other possible and clean approach is to use a Reactive form and not template-driven forms in your code :)

Comments

0
editForm: FormGroup = this.fb.group({ quantity: [] }); changeMaxValue(val: number): void { this.maxValue = val; this.editForm.get('quantity')?.setValidators(Validators.max(val)); } 

and in html,You can set custom mat-error.

 <mat-form-field appearance="outline"> <mat-label>Quantity</mat-label> <input matInput formControlName="quantity" type="text"> <mat-error *ngIf="editForm.get('quantity')!.invalid"> <span *ngIf="editForm.get(['quantity'])!.hasError('max')">{{'entity.validation.max' | translate: { max: maxValue } }}</span> </mat-error> </mat-form-field> 

and in translate json file,You can set as below

{ "entity": { "validation": { "max": "This field cannot be more than {{ max }}." } } } 

Comments

-2

Try:

minlength and maxlength

But the type should not be a number, Like:

<input matInput placeholder="Test" minlength="3" maxlength="3"> 

Demo

4 Comments

@hastrb where do I stated it?
The original question is "Angular Material: How to validate min and max values on a number field?" Why do you suggest to work with minlength and maxlength which are intended for limit a length of string? LoL.
@hastrb there's also mentioned that min and max is not working for OP..hope you had read it! Addition to that..there are other answers which with min and max..and mine one is with minlength and maxlength which is working absolutely fine!
You have to provide what OP requested... not what you know completely different from the main question lol

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.