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.

Sasha Shpota
  • 9,436
  • 14
  • 75
  • 148

5 Answers5

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

David G.
  • 1,255
  • 9
  • 16
  • Thank you (+1). How to use this approach in combination with `[(ngModel)]`? – Sasha Shpota Oct 22 '19 at 12:34
  • 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: `` 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`. – David G. Oct 22 '19 at 13:50
  • 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. – David G. Oct 22 '19 at 13:50
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>
dom.macs
  • 776
  • 7
  • 15
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)]
  });
}
Ling Vu
  • 4,740
  • 5
  • 24
  • 45
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 :)

Abdeali Chandanwala
  • 8,449
  • 6
  • 31
  • 45
-2

Try:

minlength and maxlength

But the type should not be a number, Like:

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

Demo

Prashant Pimpale
  • 10,349
  • 9
  • 44
  • 84
  • @hastrb where do I stated it? – Prashant Pimpale Apr 22 '20 at 03:43
  • 2
    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 Apr 22 '20 at 06:39
  • @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! – Prashant Pimpale Apr 23 '20 at 03:55
  • 1
    You have to provide what OP requested... not what you know completely different from the main question lol – hastrb Apr 23 '20 at 09:14