Introduction To Angular Forms And Form Validation

In this article, I will explain about validating user inputs using Angular forms. Generally speaking, , forms are used to handle user’s input! With the help of forms, we can do CRUD operations such as create, read, update, delete. Basically, speaking of forms in Angular, Angular forms are classified into two types, such as Reactive forms and Template-driven method. Both types of forms are being used to collect input from the user. Before getting started with form validation we can take an overview of both Reactive and Template-driven method.
 

Reactive Forms

 
The reactive forms are also called Model-driven forms, the reactive forms provide an approach for UI to handle the input towards the component variable. It can be used with complex forms with a greater number of form fields but it requires multiple complex validations in which custom validations are involved in it. The reactive forms require the JSON structure to be sent with values in the form.
 

Template Driven Method

 
The template-driven method is very useful in using simple forms like login forms, the template-driven method uses two-way data binding, so with the help of two-way data binding, we can assign a value to a variable from the UI. This type of form is used in very basic forms and requires simple logic.
 

Difference between Reactive and Template-driven method

 
Reactive Forms Template-Driven Method
Reactive forms are created in the component class. Template-driven forms are created by using directives.
Reactive forms are structured by the data model. The template-driven method is unstructured in the data model.
The predictability is synchronous in reactive forms. The predictability is asynchronous in template driven.
The level of scalability in reactive form has low-level API access The level of scalability in the template-driven method has the abstraction of the top API’s
Form validation is done by using functions Form validation is done by using directives
 
So, in this article, we will be seeing about designing a form and performing form validation using the template-driven method, in addition to that I have uploaded source code containing some additional files such as config.JSON, EmployeeService.ts service file and as well as a model class file named as employee.ts. This article's source code will be continued in the next article, where we will see about pushing input values from a form to a list. Now in this article, we are about to use third-party libraries like bootstrap and you can find more information about bootstrap from the following link; also the main point is we can track the control state and validity with the model.
 
By using ngModel in a form, the ngModel directive doesn’t just track only the state, it will also update the controls in an angular class state like:
 
State Class if it is true Class if it is false
If the control has been visited ng-touched ng-untouched
If the value of the control is changed ng-dirty ng-pristine
If the value of the control is valid ng-valid ng-invalid
 
Now coming to the main process, let’s start by creating a new Angular application by using the following command
 
ng new register
 
After creating a new Angular application now, we can add bootstrap to the project by using the following command.
 
npm install bootstrap –save
 
after adding bootstrap to the library function open index.html add the following code inside of the head tag.
 
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
 
After that now we can create a form and perform validation using the template-driven method. Create a new component using the following command
 
ng generate component employee
 
Here I have created a new component name as employee; now open employee.component.html and replace the following code as mentioned below.
  1. <div class="container-fluid">  
  2. <div *ngIf="(showmode=='Register')">  
  3. <form #frmEmployee="ngForm" (ngSubmit)="frmEmployee.form.valid && OnSubmit(frmEmployee)">  
  4. <div class="row">  
  5. <div class="col-md-12">  
  6. <strong>  
  7. <h5>Personal Details </h5>  
  8. </strong>  
  9. </div>  
  10. <div class=" col-md-4 form-group" *ngIf="(ObjConfiguration.showname)">  
  11. <label>Name</label>  
  12. <input type="text" class=" form-control text-uppercase" [(ngModel)]="objEmp.PersonalDetails.Name" name="Username"  
  13. id="Username" maxlength="50" #Username="ngModel" required>  
  14. <small class="text-danger" *ngIf="Username.invalid && (Username.touched || frmEmployee.submitted)"> Name is required</small>  
  15. </div>  
  16. <div class=" col-md-4 form-group" *ngIf="(ObjConfiguration.showdob)">  
  17. <label>DOB</label>  
  18. <input type="date" class="form-control" [(ngModel)]="objEmp.PersonalDetails.Dob" name="Dob" id="Dob"  
  19. #Dob="ngModel" (blur)="OnDate($event)" required >  
  20. <small class="text-danger" *ngIf="Dob.invalid && (frmEmployee.submitted || Dob.touched)">Dob is required!</small>  
  21. <small class="text-danger" *ngIf="Dob.valid && !IsMinDate">Date should be minimum 2019-01-01</small>  
  22. <small class="text-danger" *ngIf="Dob.valid && !IsMaxDate">Date should be maximum 2025-01-01</small>  
  23. </div>  
  24. <div class="col-md-4 form-group" *ngIf="(ObjConfiguration.showmobile)">  
  25. <label>Mobile</label>  
  26. <input type="text" maxlength="10" class="form-control" [(ngModel)]="objEmp.PersonalDetails.Mobile" name="Mobile" id="Mobile"  
  27. #Mobile="ngModel" pattern="^\d{10}$" required>  
  28. <div *ngIf="Mobile.invalid && (frmEmployee.submitted || Mobile.touched)">  
  29. <small class="text-danger" *ngIf="Mobile.errors.required">Mobile Number is required</small>  
  30. <small class="text-danger" *ngIf="Mobile.errors.pattern">Mobile number must be 10 digits</small>  
  31. </div>  
  32. </div>  
  33. <div class="col-md-4 form-group" *ngIf="(ObjConfiguration.showemail)">  
  34. <label>Email ID</label>  
  35. <input type="email" class="form-control" [(ngModel)]="objEmp.PersonalDetails.Email" name="Email" id="Email"  
  36. #Email="ngModel" pattern="^([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$" required>  
  37. <div *ngIf="Email.invalid && (frmEmployee.submitted || Email.touched) ">  
  38. <small class="text-danger" *ngIf="Email.errors.required">Email is required</small>  
  39. <small class="text-danger" *ngIf="Email.errors.pattern">Email must be proper format like @ ,.com</small>  
  40. </div>  
  41. </div>  
  42. <div class="col-md-4 form-group" *ngIf="(ObjConfiguration.showgender )">  
  43. <label>Gender</label>  
  44. <select name="Gender" class="form-control" #Gender="ngModel" [(ngModel)]="objEmp.PersonalDetails.Gender"  
  45. required>  
  46. <option *ngFor="let item of Genders" [value]="item">  
  47. {{item}}  
  48. </option>  
  49. </select>  
  50. <small class="text-danger" *ngIf="Gender.invalid && (Gender.touched || frmEmployee.submitted)">Gender is required</small>  
  51. </div>  
  52. </div>  
  53. <hr class="line">  
  54. <div class="row" *ngIf="(ObjConfiguration.showcommdetails)">  
  55. <h5 class="ml-2 col-md-12 mb-3"><strong>Communication Details</strong></h5>  
  56. <div class="col-md-4 form-group" *ngIf="(ObjConfiguration.IsStreet)">  
  57. <label>Street</label>  
  58. <input type="text" class=" form-control text-uppercase" [(ngModel)]="objEmp.CommunicationDetails.Street" name="Street"  
  59. id="Street" maxlength="50" #Street="ngModel" required>  
  60. <small class="text-danger"  
  61. *ngIf="Street.invalid && (Street.touched || frmEmployee.submitted) && ObjConfiguration.IscommMandatory">Street is required</small>  
  62. </div>  
  63. <div class="col-md-4 form-group" *ngIf="(ObjConfiguration.IsArea)" >  
  64. <label>Area</label>  
  65. <input type="text" class=" form-control text-uppercase" [(ngModel)]="objEmp.CommunicationDetails.Area" name="Area" id="Area"  
  66. #Area="ngModel" maxlength="50" required>  
  67. <small class="text-danger" *ngIf="Area.invalid && (Area.touched || frmEmployee.submitted) && ObjConfiguration.IscommMandatory">Area is  
  68. required</small>  
  69. </div>  
  70. <div class="col-md-4 form-group " *ngIf="(ObjConfiguration.IsDistrict)" >  
  71. <label>District</label>  
  72. <input type="text" class="form-control text-uppercase" [(ngModel)]="objEmp.CommunicationDetails.District" name="District"  
  73. id="District" maxlength="50" #District="ngModel" required>  
  74. <small class="text-danger"  
  75. *ngIf="District.invalid && (District.touched || frmEmployee.submitted) && ObjConfiguration.IscommMandatory">District is  
  76. required</small>  
  77. </div>  
  78. <div class="col-md-4 form-group" *ngIf="(ObjConfiguration.IsState)">  
  79. <label>State</label>  
  80. <input type="text" class="form-control text-uppercase" [(ngModel)]="objEmp.CommunicationDetails.State" name="State"  
  81. id="State" maxlength="50" #State="ngModel" required>  
  82. <small class="text-danger" *ngIf="State.invalid && (State.touched || frmEmployee.submitted) && ObjConfiguration.IscommMandatory">State  
  83. is required</small>  
  84. </div>  
  85. <div class="col-md-4 form-group" *ngIf="(ObjConfiguration.IsPincode)" >  
  86. <label>Pincode</label>  
  87. <input type="text" class=" form-control" [(ngModel)]="objEmp.CommunicationDetails.pincode" name="pincode"  
  88. id="pincode" maxlength="6" #pincode="ngModel" required>  
  89. <small class="text-danger"  
  90. *ngIf="pincode.invalid && (pincode.touched || frmEmployee.submitted) && ObjConfiguration.IscommMandatory">pincode is required</small>  
  91. </div>  
  92. <hr class="line">  
  93. </div>  
  94. <div class="text-right m-2 ">  
  95. <button class="btn btn-primary " type="submit">Submit</button>  
  96. <button class="btn btn-danger ml-2" style="float:right" type="reset">Reset</button>  
  97. </div>  
  98. </form>  
  99. </div>  
  100. </div>  
And open employee.component.css and place the following code as given below.
  1. hr {  
  2. background-colorred;  
  3. height1px;  
  4. border3;  
  5. }  
  6. .buttons {  
  7. display:flex;  
  8. justify-content:flex-end;  
  9. align-items:right;  
  10. }  
Create a class file named as employee.ts, and then open model file and replace the following code inside in it.
  1. export class PersonalDetails {  
  2. public Name: string;  
  3. public Dob: string;  
  4. public Mobile: string;  
  5. public Email: string;  
  6. public Gender: string;  
  7. }  
  8. export class CommunicationDetails {  
  9. public Street: string;  
  10. public Area: string;  
  11. public District: string;  
  12. public State: string;  
  13. public pincode: string;  
  14. }  
  15. export class Employee {  
  16. public PersonalDetails: PersonalDetails = new PersonalDetails();  
  17. public CommunicationDetails: CommunicationDetails = new CommunicationDetails();  
  18. }  
  19. export class Configuration {  
  20. public Isname: boolean;  
  21. public showcommdetails: boolean;  
  22. public IsStreet: boolean;  
  23. public IsArea: boolean;  
  24. public IsDistrict: boolean;  
  25. public IsState: boolean;  
  26. public IsPincode: boolean;  
  27. }  
Create a service file named as EmployeeService, open employeeservice.ts file and replace the following code as mentioned below
  1. import { Injectable } from '@angular/core';  
  2. import { Employee, Configuration } from '../employee';  
  3. import { HttpClient } from '@angular/common/http';  
  4. import { Observable } from 'rxjs';  
  5. @Injectable({  
  6. providedIn: 'root'  
  7. })  
  8. export class EmployeeService {  
  9. public objEmployee = new Employee();  
  10. public Url = '/assets/config.json';  
  11. constructor(private http: HttpClient) {  
  12. }  
  13. public getConfig(): Observable<Configuration> {  
  14. return this.http.get<Configuration>(this.Url);  
  15. }  
  16. }  
Then open employee.component.ts file and add the following code. This article is for form validation alone and with the next article we will see how to push data from form to a list.
  1. import { Component, OnInit } from '@angular/core';  
  2. import { EmployeeService } from '../employee.service';  
  3. import { Employee, Configuration } from 'src/employee';  
  4. @Component({  
  5. selector: 'app-employee',  
  6. templateUrl: './employee.component.html',  
  7. styleUrls: ['./employee.component.css']  
  8. })  
  9. export class EmployeeComponent implements OnInit {  
  10. public showmode: string;  
  11. public objEmp: Employee;  
  12. public ObjConfiguration: Configuration;  
  13. Genders = ['Male''Female'];  
  14. constructor(private srvEmployee: EmployeeService) {  
  15. this.showmode = 'Register';  
  16. this.objEmp = new Employee();  
  17. this.ObjConfiguration = new Configuration();  
  18. }  
  19. ngOnInit() {  
  20. this.srvEmployee.getConfig().subscribe(data => this.ObjConfiguration = data);  
  21. }  
  22. }  
Create a json file in assets folder by right click-> assets-> create a new file.
 
Name the new file as config.JSON and open the JSON file and replace the following code as mentioned below.
  1. {  
  2. "Isname"true,  
  3. "showcommdetails"true,  
  4. "IsStreet":false,  
  5. "IsArea":true,  
  6. "IsDistrict"true,  
  7. "IsState":true,  
  8. "IsPincode"true,  
  9. "showname"true,  
  10. "showdob"true,  
  11. "showmobile"true,  
  12. "showemail" : true,  
  13. "showgender":true,  
  14. "IsnameMandatory"true,  
  15. "IsdobMandatory"true,  
  16. "IsmobileMandatory":true,  
  17. "IsemailMandatory":true,  
  18. "IsgenderMandatory"true,  
  19. "IscommMandatory":true  
  20. }  
Finally, run the Angular application by using the command
 
ng serve -open
 
 
 
Now we can see the output of the application, touch any input field in the form application, for example, touch the input field “name” and we can see the state is changed to name, which is required when the control has been touched.
 
 
The next step is click-> submit button and you can see that input fields are required and the form validation has been done using the template-driven method.
 
 
 
 
I hope this article will be useful for you and in the next article, we can see the pushing of form inputs into a list.