Form Validations in Angular: A Comprehensive Guide

Kruti Dave
Vedity
Published in
4 min readMar 11, 2022

Enhancing Form Validation in Angular: Combining Custom Rules with Fundamental Checks

When working with forms, there are often fundamental validations that need to be in place, such as mandatory field validation, maximum and minimum length checks, and even restrictions on spaces within textboxes. In an Angular application, custom validations can be seamlessly integrated, enhancing form control.

For instance, consider a scenario where the requirement is to prevent the inclusion of spaces in a master code field. Traditionally, one might think of using conditional statements or the trim function to accomplish this. However, upon closer inspection, an elegant solution emerges using a custom validator within a FormControl, all within the realm of Angular's reactive forms framework. This capability is available from Angular 6 and onwards.

In my recent experience, I encountered a need to disallow spaces within a master code field. Rather than resorting to conventional methods like conditional checks or trimming functions, I delved into the world of FormGroup and FormControl. By creating a custom validator tailored to eliminate spaces from input fields, I was able to achieve this requirement in a more efficient and structured manner. Let’s explore this concept by crafting a new custom validator that ensures input fields remain free of spaces.

Let's check it by creating new custom validator which will not contain space on input field.

We will need an Angular application;

1. create new angular demo application if you already have then skip it.

ng new demo-custom-validator

2. If created a new application you need to install packages.

npm i or npm install

3. Since we are creating Forms module we need to add/ import it into app.module.ts file.

Route to src/app/app.module.ts

import { BrowserModule } from '@angular/platform-browser';import { NgModule } from '@angular/core';import { AppRoutingModule } from './app-routing.module';import { AppComponent } from './app.component';import { ReactiveFormsModule } from '@angular/forms';@NgModule({declarations: [AppComponent],imports: [BrowserModule,AppRoutingModule,ReactiveFormsModule],providers: [],bootstrap: [AppComponent]})export class AppModule { }

4. Html File with FormGroup as userForm

<div class="header row"><span class="col-4"> User Management</span><span class="col-2 text-right"></span></div><div class="mt-15"><form [formGroup]="userForm"><div class="row col mt-15"><div class="form-group pr-20"><label class="form-label">User Name</label><input class="form-control material-form-input-box text-field" formControlName="userName"placeholder="Enter User Name" type="text" /></div><div class="form-group pr-10"><label class="form-label">User Email ID</label><input class="form-control" formControlName="emailId"placeholder="Enter Email" type="text" /></div><div class="form-group "><label class="form-label">User Phone Number</label><input class="form-control" formControlName="phoneNo"placeholder="Enter Phone Number" type="text" /></div><div class="form-group "><label class="form-label">User Code</label><input class="form-control" formControlName="userCode"placeholder="Enter User Code" type="text" /></div><div class="form-group top-margin"><button type="button" class="btn btn-primary text-uppercase" (click)="submit()"[disabled]="!userForm.valid">SUBMIT</button><button type="button" class="btn-cancel" (click)="cancel()">CANCEL</button></div>
</div>
</form>
</div>

5. Custom validator file :

Here , by checking index of ‘ ‘ (space) validation a value and returning boolean value.

import { AbstractControl, ValidationErrors } from '@angular/forms';export class SpaceValidator {static validateSpace(control: AbstractControl): ValidationErrors | null {if ((control.value as string).indexOf(' ') >= 0) {return { validateSpace: true }}
return null;
}
}

6. TS File

Here created userForm and created FormControls. Few validations added for each fields for some references.

So, SpaceValidator used in userCode where I dont want user to add any spaces.

Also added some validations on Email and Phone controls by applying patterns for each along with required validation.

Check below code file for the reference :

import { Component, OnInit } from '@angular/core';import { FormControl, FormGroup, Validators } from '@angular/forms';import { SpaceValidator } from '../space.validator';@Component({selector: 'app-user',templateUrl: './user.component.html',styleUrls: ['./user.component.scss']})export class UserComponent implements OnInit {constructor() { }ngOnInit(): void {}userForm = new FormGroup({userName: new FormControl("", [Validators.required]),emailId: new FormControl("", [Validators.required,Validators.pattern("^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$")]), //Email PatternphoneNo: new FormControl("", [Validators.required,Validators.pattern("^((\\+91-?)|0)?[0-9]{10}$")]), // can also provide patternuserCode: new FormControl("", [Validators.required,SpaceValidator.validateSpace]), //custom validator created.});submit() {
console.log(this.userForm.value);
}
cancel() {
this.userForm.reset();
}
}

7. run application :

 ng serve 

if you want to run on specific port :

 ng serve — port 4202

8. Screenshots attached

In the context of the first attachment, the unsuccessful validations result in the deactivation of the SUBMIT button. Conversely, the second image demonstrates successful validations, leading to the activation of the SUBMIT button.

However, the next step involves enhancing user interaction by providing real-time visual cues in the event of validation failures. A prime example is when an incorrect email address is provided. In such cases, the implementation of visual indicators, such as a red border or error messages denoting invalid input, becomes crucial. This particular aspect hasn’t been addressed in the current setup and warrants attention.

I trust you’re enjoying the content of the blog. Feel free to continue reading and stay connected for more insights.

--

--

Kruti Dave
Vedity
Writer for

Experienced in Microservices using (Spring Boot and Spring Modules), Angular, Data Engineering (Python | Hadoop | PySpark | Hive | Airflow | ETL), AWS Services