Angular Custom Form Validation


Angular Custom Validator

In this tutorials, we will learn how to create custom validators in Angular Reactive Forms. Here, we will see how to use built in and custom validators.

Custom Validators

For example, Suppose you want the age range to be from 20 to 40 for a employee. Angular does not provide any range validation. So you need to create a custom validator for this. That is called custom validator. To do that you need to create a function and pass a parameter named AbstractControl which returns an object of key value pair if the validation fails.

AbstractControl

AbstractControl class, which is the base class for FormControls, FormGroups, and FormArrays. This allows access to the value of the FormControl and pass to the custom validator function. It provides some of the shared behavior that all controls and groups of controls have, like running validators, calculating status, and resetting state. It also defines the properties that are shared between all sub-classes, like value, valid, and dirty. It shouldn't be instantiated directly. The validator itself is just a function that accepts an AbstractControl and returns an Object containing the validation error or null.

Now create a function  which defines the range of age between min and max value.

ageMinMaxValidator(min: number, max: number): ValidatorFn {
return (control: AbstractControl): { [key: string]: boolean } | null => {
if (control.value !== undefined && (isNaN(control.value) || control.value < min || control.value > max)) {
return { 'ageRangeVal': true };
}
return null;
};
}

In the above function, the custom validator returns either of the following:

  1. If the validation fails, it returns an object, which contains a key value pair. Key is the name of the error and the value is always Boolean true.
  2. If the validation does not fail, it returns null.
  3. ValidatorFn - The return type of the factory function should be ValidatorFn which is part of @angular/forms.

Step 1: Add Reactive Forms Module

When we start working with reactive forms, firstly add ReactiveFormsModle in the App Module as shown in the below image.

Import reactive Module

Step 2: Import Required module in Component

After first step we import as required reactive forms classes such as FormGroup, FormControl, FormArray in the components class. After importing the classes, your code will look something like this.

Import reactive Module

import { Component, OnInit } from '@angular/core';
import { Validators, FormBuilder, ValidatorFn, AbstractControl } from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
   EmployeeForm: any; 
  min=20;
  max=40;
  constructor(private fb: FormBuilder) { }
  ngOnInit(): void {
    
    this.EmployeeForm = this.fb.group({
      firstname: ['', [
        Validators.required,
        Validators.minLength(5),
        Validators.maxLength(8)
      ]],
      lastname: ['', [
        Validators.required,
        Validators.minLength(5),
        Validators.maxLength(8)
      ]],
      email: ['', [
        Validators.required,
        Validators.minLength(5),
        Validators.maxLength(8)
      ]],
      gender: ['', Validators.required],
      age: ['', [this.ageMinMaxValidator(this.min, this.max)]],      
    });
  }   
  EmployeeRegister() {   
    console.log(this.EmployeeForm.value);
  }
   ageMinMaxValidator(min: number, max: number): ValidatorFn {
    return (control: AbstractControl): { [key: string]: boolean } | null => {
        if (control.value !== undefined && (isNaN(control.value) || control.value < min || control.value > max)) {
            return { 'ageRangeVal': true };
        }
        return null;
    };
  }
}

Now Use ageRangeVal on template to check age range and show message

<div class="alert alert-danger" *ngIf="EmployeeForm.get('age').touched && EmployeeForm.get('age').errors && EmployeeForm.get('age').errors.ageRangeVal">
<span style="color: red;"> Age should be in between 20 to 40 years</span>
</div>

Step 3: Template Code

<form (ngSubmit)='EmployeeRegister()' [formGroup]='EmployeeForm' novalidate>
<p>employee Form</p>

<label for="firstname">First Name</label>
<input type="text" name="firstname" formControlName="firstname"> 
<div *ngIf="EmployeeForm.get('firstname').touched && EmployeeForm.get('firstname').invalid">
<div *ngIf="EmployeeForm.get('firstname').errors.required">
<span style="color: red;">Please Enter firstname.</span> 
</div>
<div *ngIf="EmployeeForm.get('firstname').errors.minlength">
<span style="color: red;"> Password must be at least 5 characters</span> 
</div>
<div *ngIf="EmployeeForm.get('firstname').errors.maxlength">
<span style="color: red;"> Username must not exceed 8 characters</span> 
</div> 
</div>
<p>
<label for="lastname">Last Name</label>
<input type="text" name="lastna me" formControlName="lastname">
</p>
<div *ngIf="EmployeeForm.get('lastname').touched && EmployeeForm.get('lastname').invalid">
<div *ngIf="EmployeeForm.get('lastname').errors.required">
<span style="color: red;">Please Enter lastname.</span>
</div>
<div *ngIf="EmployeeForm.get('lastname').errors.minlength">
<span style="color: red;"> lastname must be at least 5 characters</span> 
</div>
<div *ngIf="EmployeeForm.get('lastname').errors.maxlength">
<span style="color: red;"> lastname must not exceed 8 characters</span> 
</div> 
</div> 
<p>
<label for="email">Email </label>
<input type="text" id="email" name="email" formControlName="email">
</p>

<div *ngIf="EmployeeForm.get('email').touched && EmployeeForm.get('email').invalid">
<div *ngIf="EmployeeForm.get('email').errors.required">
<span style="color: red;">Please Enter email.</span>
</div>
<div *ngIf="EmployeeForm.get('email').errors.minlength">
<span style="color: red;"> email must be at least 5 characters</span> 
</div>
<div *ngIf="EmployeeForm.get('email').errors.maxlength">
<span style="color: red;"> email must not exceed 8 characters</span> 
</div> 
</div>

<p>
<label for="Age">Employee Age </label>
<input type="text" id="email" name="age" formControlName="age">
</p>
<div class="alert alert-danger" *ngIf="EmployeeForm.get('age').touched && EmployeeForm.get('age').errors && EmployeeForm.get('age').errors.ageRangeVal">
<span style="color: red;"> Age should be in between 20 to 40 years</span> 
</div> 
<p>
<label for="gender">Geneder</label>
<input type="radio" value="male" name="gender" formControlName="gender"> Male
<input type="radio" value="female" name="gender1" formControlName="gender"> Female
</p>
<div *ngIf="EmployeeForm.get('gender').untouched && EmployeeForm.get('gender').invalid">
<div *ngIf="EmployeeForm.get('gender').errors.required"><span style="color: red;">Gender is required.</span></div></div>
<p>
<button type="submit" [disabled]="!EmployeeForm.valid">Submit</button>
</p>
</form>
<router-outlet></router-outlet>

Now run the application.

Import reactive Module

Now enter the age not in range 20 to 40. it will show error message.

Import reactive Module


Prev Next