Angular Min Max Validation

By Arvind Rai, March 05, 2020
This page will walk through Angular Min and Max validation example. In reactive form we can use Validators.min and Validators.max for min and max validation respectively while creating FormGroup. We can also create custom min and max validator using Angular Validator interface. In our example we will create our custom min and max validator and use in template-driven form with ngModel. We can also use our custom min and max validator with formControlName in reactive form.
Angular 4 uses novalidate attribute by default in its form element at run time and hence while submitting form, HTML 5 validation will not work. Here in our example we will provide min and max validation example for template-driven form as well as reactive form. Now find the complete example step by step.

Technologies Used

Find the technologies being used in our example.
1. Angular 9.0.2
2. Angular CLI 9.0.3
3. Node.js 12.5.0

Project Structure

Find the project structure of our demo application.
angular-demo
|
|--src
|   |
|   |--app 
|   |   |
|   |   |--user.ts
|   |   |--user-service.ts
|   |   |--custom-min-validator.directive.ts
|   |   |--custom-max-validator.directive.ts
|   |   |--reactive-form.component.ts
|   |   |--reactive-form.component.html
|   |   |--template-driven-form.component.ts
|   |   |--template-driven-form.component.html
|   |   |
|   |   |--app.component.ts
|   |   |--app.module.ts 
|   | 
|   |--main.ts
|   |--index.html
|   |--styles.css
|
|--node_modules
|--package.json 

Validators.min and Validators.max in Reactive Form

Angular 4 has added Validators.min and Validators.max to validate min and max number in a reactive form. They can be used as given below.
userForm = this.formBuilder.group({
     num1: ['', Validators.min(15)],
     num2: ['', Validators.max(50)]
}); 
Find the code snippet of HTML template.
<input formControlName="num1">
<input formControlName="num2"> 
We can show validation error message as following.
<div *ngIf="num1.errors?.min">
      Minimum required number is 15.
</div> 
<div *ngIf="num2.errors?.max">
      Maximum number can be 50.
</div> 

Create Custom Min Validator

We will create custom validator for min number validation. We are creating a directive with selector customMin
custom-min-validator.directive.ts
import { Directive, Input } from '@angular/core';
import { NG_VALIDATORS, Validator, FormControl } from '@angular/forms';

@Directive({
  selector: '[customMin][formControlName],[customMin][formControl],[customMin][ngModel]',
  providers: [{provide: NG_VALIDATORS, useExisting: CustomMinDirective, multi: true}]
})
export class CustomMinDirective implements Validator {
  @Input()
  customMin: number;
  
  validate(c: FormControl): {[key: string]: any} {
      let v = c.value;
      return ( v < this.customMin)? {"customMin": true} : null;
  }
} 
We can use customMin with formControlName, formControl and ngModel attributes.

Create Custom Max Validator

Find the custom validator for max number validation. The selector name of our directive is customMax.
custom-max-validator.directive.ts
import { Directive, Input } from '@angular/core';
import { NG_VALIDATORS, Validator, FormControl } from '@angular/forms';

@Directive({
  selector: '[customMax][formControlName],[customMax][formControl],[customMax][ngModel]',
  providers: [{provide: NG_VALIDATORS, useExisting: CustomMaxDirective, multi: true}]
})
export class CustomMaxDirective implements Validator {
  @Input()
  customMax: number;
  
  validate(c: FormControl): {[key: string]: any} {
      let v = c.value;
      return ( v > this.customMax)? {"customMax": true} : null;
  }
} 
We can use customMax with formControlName, formControl and ngModel attributes.

Using Custom Min and Max Validator in Template-driven Form

We will use our custom min and max validator in template-driven form. For min number validation we have customMin attribute and for max number validation we have customMax attribute. Now find the code snippet for validation.
<input name="num1" [ngModel]="user.num1" customMin="15" #numberOne="ngModel">
<input name="num2" [ngModel]="user.num2" customMax="50"  #numberTwo="ngModel"> 
We can show validation error messages as following.
<div *ngIf="numberOne.errors?.customMin"> 
     Minimum required number is 15.
</div>	
<div *ngIf="numberTwo.errors?.customMax"> 
     Maximum number can be 50.
</div> 
To assign min and max number we can also use property biding. Suppose we have following component properties.
minNum = 15;
maxNum = 50; 
Now use property binding for customMin and customMax as following.
<input name="num1" [ngModel]="user.num1" [customMin]="minNum" #numberOne="ngModel">
<input name="num2" [ngModel]="user.num2" [customMax]="maxNum"  #numberTwo="ngModel"> 

Using Custom Min and Max Validator in Reactive Form

We will use our custom min and max number validation in reactive form with formControlName attribute. For min number validation we have customMin attribute and for max number validation we have customMax attribute. Now find the code snippet for validation.
<input formControlName="num1" customMin="15">
<input formControlName="num2" customMax="50"> 
We will show validation error messages as following.
<div *ngIf="num1.errors?.customMin">
      Minimum required number is 15.
</div> 
<div *ngIf="num2.errors?.customMax">
      Maximum number can be 50.
</div> 
We can also use property binding with customMin and customMax. Suppose we have following component properties.
minNum = 15;
maxNum = 50; 
Now use property binding for validation as following.
<input formControlName="num1" [customMin]="minNum">
<input formControlName="num2" [customMax]="maxNum"> 

Example-1: Reactive Form Min and Max Validation

user.ts
export class User {
    num1: number;
    num2: number;
	num3: number;
} 
user-service.ts
import { Injectable } from '@angular/core';
import { User } from './user';

@Injectable()
export class UserService {
   createUser(user: User) {
         console.log('Number-1: ' + user.num1);
	 console.log('Number-2: ' + user.num2);
	 console.log('Number-3: ' + user.num3);	 
   }
} 
reactive-form.component.ts
import { Component, OnInit } from '@angular/core';
import { FormControl, FormBuilder, Validators } from '@angular/forms';
import { UserService } from './user-service';
import { User } from './user';

@Component({
   selector: 'app-reactive',
   templateUrl: './reactive-form.component.html'
})
export class ReactiveFormComponent implements OnInit {
  isValidFormSubmitted = null;
  minNum = 15;
  maxNum = 50;
  userForm = this.formBuilder.group({
     num1: ['', [Validators.required, Validators.min(this.minNum)]],
     num2: ['', [Validators.required, Validators.max(this.maxNum)]],
     num3: ['', [Validators.required, Validators.min(this.minNum), Validators.max(this.maxNum)]]
  });
  user = new User();
  constructor(private formBuilder:FormBuilder, private userService: UserService) {
  }
  ngOnInit() {
  }
  onFormSubmit() {
     this.isValidFormSubmitted = false;
     if (this.userForm.invalid) {
        return;
     }
     this.isValidFormSubmitted = true;
     this.user = this.userForm.value;
     this.userService.createUser(this.user);
     this.userForm.reset();
  }
  get num1() {
     return this.userForm.get('num1');
  }
  get num2() {
     return this.userForm.get('num2');
  }  
  get num3() {
     return this.userForm.get('num3');
  }    
} 
reactive-form.component.html
<h3>Reactive Form</h3>
<p *ngIf="isValidFormSubmitted && userForm.pristine" [ngClass] = "'success'">
    Form submitted successfully.
</p>
<form [formGroup]="userForm" (ngSubmit)="onFormSubmit()">
  <table>
	 <tr> 
	   <td>Number-1: </td>
	   <td> 
	       <input formControlName="num1">
	       <div *ngIf="num1.errors && isValidFormSubmitted != null && !isValidFormSubmitted" [ngClass] = "'error'"> 
		   <div *ngIf="num1.errors.required">
                       Enter your number.
		   </div> 
		   <div *ngIf="num1.errors.min">
                       Minimum required number is {{minNum}}.
		   </div> 
	       </div>
	   </td>
	 </tr> 
	 <tr> 
	   <td>Number-2: </td>
	   <td> 
	       <input formControlName="num2">
	       <div *ngIf="num2.errors && isValidFormSubmitted != null && !isValidFormSubmitted" [ngClass] = "'error'"> 
		   <div *ngIf="num2.errors.required">
                      Enter your number.
		   </div> 
		   <div *ngIf="num2.errors.max">
                      Maximum number can be {{maxNum}}.
		   </div> 
	       </div>
	   </td>
	 </tr> 
	 <tr> 
	   <td>Number-3: </td>
	   <td> 
	       <input formControlName="num3">
	       <div *ngIf="num3.errors && isValidFormSubmitted != null && !isValidFormSubmitted" [ngClass] = "'error'"> 
		   <div *ngIf="num3.errors.required">
                       Enter your number.
		   </div> 
		   <div *ngIf="num3.errors.min || num3.errors.max">
                       Number must be between {{minNum}} and {{maxNum}}.
		   </div> 
	       </div>
	   </td>
	 </tr> 	 
	 <tr> 	  
	   <td colspan="2">
	      <button>Submit</button>
	   </td>
	 </tr>	   
  </table>  
</form> 


Example-2: Template-driven Form Min and Max Validation

template-driven-form.component.ts
import { Component, OnInit } from '@angular/core';
import { NgForm } from '@angular/forms';
import { UserService } from './user-service';
import { User } from './user';

@Component({
   selector: 'app-template',
   templateUrl: './template-driven-form.component.html'
})
export class TemplateDrivenFormComponent implements OnInit {
  isValidFormSubmitted = false;
  minNum = 15;
  maxNum = 50;
  user = new User();
  constructor(private userService: UserService) {
  }
  ngOnInit() {
  }
  onFormSubmit(form: NgForm) {
     this.isValidFormSubmitted = false;
     if (form.invalid) {
        return;
     }
     this.isValidFormSubmitted = true;
     this.user = form.value;
     this.userService.createUser(this.user);
     this.user = new User();
     form.resetForm();
  }
} 
template-driven-form.component.html
<h3>Template-driven Form</h3>
<p *ngIf="isValidFormSubmitted" [ngClass] = "'success'">
    Form submitted successfully.
</p>
<form #userForm="ngForm" (ngSubmit)="onFormSubmit(userForm)">
  <table>
	 <tr> 
	   <td>Number-1:</td>
	   <td> 
	       <input name="num1" [ngModel]="user.num1" required [customMin]="minNum" #numberOne="ngModel">
	       <div *ngIf="numberOne.errors && userForm.submitted && !isValidFormSubmitted" [ngClass] = "'error'"> 
	          <div *ngIf="numberOne.errors.required"> 
		     Enter your number.
		  </div>			   
	          <div *ngIf="numberOne.errors.customMin"> 
		     Minimum required number is {{minNum}}.
		  </div>	
	       </div>
	   </td>
	 </tr> 
	 <tr> 
	   <td>Number-2:</td>
	   <td> 
	       <input name="num2" [ngModel]="user.num2" required [customMax]="maxNum"  #numberTwo="ngModel">
	       <div *ngIf="numberTwo.errors && userForm.submitted && !isValidFormSubmitted" [ngClass] = "'error'"> 
	         <div *ngIf="numberTwo.errors.required"> 
		     Enter your number.
		 </div>			 		   
	         <div *ngIf="numberTwo.errors.customMax"> 
		     Maximum number can be {{maxNum}}.
		 </div>	
	       </div>
	   </td>
	 </tr> 	 
	 <tr> 
	   <td>Number-3:</td>
	   <td> 
	       <input name="num3" [ngModel]="user.num3" required [customMin]="minNum" [customMax]="maxNum"  #numberThree="ngModel">
	       <div *ngIf="numberThree.errors && userForm.submitted && !isValidFormSubmitted" [ngClass] = "'error'"> 
	         <div *ngIf="numberThree.errors.required"> 
		     Enter your number.
		 </div>			   
	         <div *ngIf="numberThree.errors.customMin || numberThree.errors.customMax"> 
		     Number must be between {{minNum}} and {{maxNum}}.
		 </div>	
	       </div>
	   </td>
	 </tr> 	 	 
	 <tr> 	  
	   <td colspan="2">
	      <button>Submit</button>
	   </td>
	 </tr>	   
  </table>  
</form> 
app.component.ts
import { Component } from '@angular/core';

@Component({
   selector: 'app-root',
   template: `
		<app-reactive></app-reactive>
		<app-template></app-template>				
             `
})
export class AppComponent {
} 
styles.css
table {
    border-collapse: collapse;
}
table, th, td {
    border: 1px solid black;
}
.error {
    color: red;
}
.success {
    color: green;
} 
app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { ReactiveFormComponent } from './reactive-form.component';
import { TemplateDrivenFormComponent } from './template-driven-form.component';
import { UserService } from './user-service';
import { CustomMinDirective } from './custom-min-validator.directive';
import { CustomMaxDirective } from './custom-max-validator.directive';

@NgModule({
  imports: [
      BrowserModule,
      FormsModule,
      ReactiveFormsModule
  ],
  declarations: [
      AppComponent,
      ReactiveFormComponent,
      TemplateDrivenFormComponent,
      CustomMinDirective,
      CustomMaxDirective	  
  ],
  providers: [
      UserService
  ],
  bootstrap: [
      AppComponent
  ]
})
export class AppModule { } 

Run Application

To run the application, find following steps.
1. Download source code using download link given below on this page.
2. Use downloaded src in your Angular CLI application. To install Angular CLI, find the link.
3. Run ng serve using command prompt.
4. Now access the URL http://localhost:4200
When we enter invalid data and click on submit button, we will get following output.
Angular Min Max Validation

References

Angular Validators Class
Angular Validator Interface

Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI







©2024 concretepage.com | Privacy Policy | Contact Us