In this tutorial, let’s implement the following angular 2 inbuilt validations and create a custom validation using
angular 2 validate
interface
- Required - The form field is mandatroy
- Maxlength - Maximum number of characters in the field.
- Minlength - Minimum number of characters in the field.
- Pattern - Regular expression to match the input values and validate.
- Custom Validator - Writing custom validation function to match password and confirm password fields.
Getting Started
Lets create a form component. I used angular CLI to generate the folder structure and created a form folder for component files. To style we are using bootstrap. The folder structure should look like this :
Create Form Component
Following code creates a form component with the input fields. In the next steps, let see how we can apply validations on each of these fields. View Live Demo
- import { Component,Directive, forwardRef,
- Attribute,OnChanges, SimpleChanges,Input } from '@angular/core';
- import { NG_VALIDATORS,Validator,
- Validators,AbstractControl,ValidatorFn } from '@angular/forms';
- import { User } from './user';
- @Component({
- moduleId: module.id,
- selector: 'login-form',
- templateUrl: './login-form.component.html',
- styleUrls: ['./login-form.component.css']
- })
- export class LoginFormComponent {
- powers = ['Really Smart', 'Super Flexible',
- 'Super Hot', 'Weather Changer'];
- model = new User('','',null,'','','');
- submitted = false;
- onSubmit() { this.submitted = true; }
- newHero() {
- // this.model = new User('','');
- }
- }
- <div class="col-md-6">
- <h3>Angular 2 Form Validations Demo</h3>
- <form (ngSubmit)="onSubmit()" #loginForm="ngForm">
- <div class="form-group">
- <label for="name">Name</label>
- <input type="text" class="form-control" id="name" #name="ngModel">
- </div>
- <div class="form-group">
- <label for="name">Email Address</label>
- <input type="text" class="form-control" id="emailaddress" #email="ngModel">
- </div>
- <div class="form-group">
- <label for="name">Mobile Number</label>
- <input type="text" class="form-control" id="mobilenumber" #mobile="ngModel">
- </div>
- <div class="form-group">
- <label for="name">Password</label>
- <input type="password" class="form-control" id="password" #password="ngModel">
- </div>
- <div class="form-group">
- <label for="name">Confirm Password</label>
- <input type="password" class="form-control" id="confirmPassword" #confirmPassword="ngModel">
- </div>
- <button type="submit" class="btn btn-success btn-block" [disabled]="!loginForm.form.valid">Submit</button>
- </form>
- </div>
- import { Directive, forwardRef, Attribute } from '@angular/core';
- import { NG_VALIDATORS,Validator,
- Validators,AbstractControl,ValidatorFn } from '@angular/forms';
- @Directive({
- selector: '[validateEqual][formControlName],[validateEqual][formControl],
- [validateEqual][ngModel]',
- providers: [
- { provide: NG_VALIDATORS,
- useExisting: forwardRef(() => EqualValidator),
- multi: true }
- ]
- })
- export class EqualValidator implements Validator {
- constructor( @Attribute('validateEqual') public validateEqual: string) {}
- validate(c: AbstractControl): { [key: string]: any } {
- // self value (e.g. retype password)
- let v = c.value;
- // control value (e.g. password)
- let e = c.root.get(this.validateEqual);
- // value not equal
- if (e && v !== e.value) return {
- validateEqual: false
- }
- return null;
- }
- }
- export class User{
- constructor(
- public name:string,
- public email: string,
- public mobile: number,
- public gender: string,
- public password: any,
- public confirmPassword: any
- ){}
- }
Once we have created the form, it looks like something below.
Now it’s time for us to apply the validations on each field.
First Name Validation
Requirement - Required and only alphabets allowed in the name field.
required
attribute on input tag ensures that the filed value is mandatory.pattern="[a-zA-Z][a-zA-Z ]+"
attribute take aregex
to check for only characters in the field.[a-zA-Z][a-zA-Z ]+
is the regular expression to check for only alphabets.name.valid
is a boolean value to check if the field has any error on the validation attributes.name.hasError('required')"
returns true if the value is not entered.name.hasError('pattern')"
return true if the entered value does not match with the regular expression.
Based on the type of error, whether on required
or on pattern
attributes, the error messages are shown and hidden.
- <div class="form-group">
- <label for="name">Name</label>
- <input type="text" class="form-control" id="name"
- required
- pattern="[a-zA-Z][a-zA-Z ]+"
- [(ngModel)]="model.name" name="name"
- #name="ngModel">
- <div [hidden]="name.valid || name.pristine"
- class="alert alert-danger">
- <div [hidden]="!name.hasError('required')">Name is required</div>
- <div [hidden]="!name.hasError('pattern')">Only alphabetsallowed</div>
- </div>
- </div>
Email Address Validation
Requirement - Validate the email format joe@gmail.com
. Entered email should be having valid email with @, .co or.com.
required
attribute on input tag ensures that the filed value is mandatory.pattern="^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$"
takes regular expression^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$
to check for valid email.
- <div class="form-group">
- <label for="name">Email Address</label>
- <input type="text" class="form-control" id="emailaddress"
- required
- [(ngModel)]="model.email" name="email"
- pattern="^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$"
- #email="ngModel">
- <div [hidden]="email.valid || email.pristine"
- class="alert alert-danger">
- <div [hidden]="!email.hasError('required')">Email is required</div>
- <div [hidden]="!email.hasError('pattern')">Email format should be
- <small><b>joe@abc.com</b></small>
- </div>
- </div>
Mobile Number Validation
Requirement - Should be only numbers and should have 10 digits only.
required
attribute on input tag ensures that the filed value is mandatory.pattern="[0-9]*"
take regular expression[0-9]*
to allow only numbers.minlength="10"
minlength of the input value should be 10.maxlength="10"
max length of the input value should be 10. Based on the type of error in each of the attributes above, the error messages are shown.
- <div class="form-group">
- <label for="name">Mobile Number</label>
- <input type="text" class="form-control" id="mobilenumber"
- required
- [(ngModel)]="model.mobile" name="mobilenumber"
- pattern="[0-9]*"
- minlength="10"
- maxlength="10"
- #mobile="ngModel">
- <div [hidden]="mobile.valid || mobile.pristine"
- class="alert alert-danger">
- <div [hidden]="!mobile.hasError('minlength')">Mobile should be 10digit</div>
- <div [hidden]="!mobile.hasError('required')">Mobile is required</div>
- <div [hidden]="!mobile.hasError('pattern')">Mobile numberr should be only numbers</div>
- </div>
- </div>
Password Matching Validation
Angular 2 does not provide any inbuilt validator to match password. We need to write a custom directive to validate password match.
Let’s write the directive using the validator
interface.
- import { Directive, forwardRef, Attribute } from '@angular/core';
- import { NG_VALIDATORS,Validator,
- Validators,AbstractControl,ValidatorFn } from '@angular/forms';
- @Directive({
- selector: '[validateEqual][formControlName],[validateEqual][formControl],[validateEqual][ngModel]',
- providers: [
- { provide: NG_VALIDATORS, useExisting: forwardRef(() => EqualValidator), multi: true }
- ]
- })
- export class EqualValidator implements Validator {
- constructor( @Attribute('validateEqual') public validateEqual: string) {}
- validate(c: AbstractControl): { [key: string]: any } {
- // self value (e.g. retype password)
- let v = c.value;
- // control value (e.g. password)
- let e = c.root.get(this.validateEqual);
- // value not equal
- if (e && v !== e.value) return {
- validateEqual: false
- }
- return null;
- }
- }
The EqualValidator
directive needs to be added to the html code as shown below.
validateEqual="password"
in whichpassword
is the name of the field whose value is to be matched.
- <div class="form-group">
- <label for="name">Password</label>
- <input type="password" class="form-control" id="password"
- required
- [(ngModel)]="model.password" name="password"
- #password="ngModel">
- <div [hidden]="password.valid || password.pristine"
- class="alert alert-danger">
- Password is required
- </div>
- </div>
- <div class="form-group">
- <label for="name">Confirm Password</label>
- <input type="password" class="form-control" id="confirmPassword"
- required
- validateEqual="password"
- [(ngModel)]="model.confirmPassword" name="confirmPassword"
- #confirmPassword="ngModel">
- <div [hidden]="confirmPassword.valid || confirmPassword.pristine"
- class="alert alert-danger">
- Passwords did not match
- </div>
- </div>
That’s all folks !!