Why we need Forms?
Forms are the main building blocks of any type of application. When we use forms for login, registration, submission. Help request, etc., it is necessary that whatever forms we are developing, they should be user friendly. And it should have the indication of what went wrong by display user friendly message, etc.
Ensuring proper data[input] from user is called "validation"
eg: username cannot be blank
mobile requires 10 digit number
*Angular is providing built-in support[code] for validations, this makes developer
job easy and faster
*Angular supports 2 types of validations
1.MDF[Model Driven Form] validations
2.TDF[Template Driven Form] validations
MDF validations:
----------------
*Validations applied to model properties with in a component class is called
"MDF validations"
*MDF will separate validations from UI, this makes unit testing validations easy
and provides programming flexibility
*programming flexibility means dynamic controls creation with validation[s] is possible and validations can be referenced | verified from router guards[comes later in the routing]
*MDF validations is also called "ReactiveForm Validations"
*Angular is providing ReactiveFormsModule with @angular/forms package with set of classes to work with MDF validations.
For this, first, we need to create the model using Agular's inbuilt classes like formGroup and formControl and then we need to bind that model to the HTML form.
1.Form Control class--this is used to declare a model property to set | get
form control data by applying validation
2 Form Group class --this is used to build a model with collection of props.
3.FormArray class --this is used to create an array of form controls (or) form groups
(or) nested form array
->formgroup will be serialized into an object
formarray will be serialized into an array
->formgroup doesn't support dynamic controls creation
formarray supports dynamic controls creation
In order to use Reactive Forms, you need to import ReactiveFormsModule into the applications root module i.e. app.module.ts
4.Validators class--this is providing collection of static methods to perform
different types of validations
i. required- this will validate whether input is provided or not
[applied for mandatory fields]
ii. minlength(n)-this will validate user input for minimum no of chars
iii.maxlength(n)-this will validate user input for maximum no of chars.
iv.email--this will validate user input for an email id.
v.pattern(expression)--this will validate user input against an
expression
eg:
[0-9]{10} --expression | pattern to accept 10 digit number
[A-Za-z.\\s]{1,} --expression to accept a string with lower |upper |dot |spaces with 1 to any
Form Group, Form Array and Form Control props | methods:
--------------------------------------------------
AbstractClass --> base class
[valid|invalid|..-->props]
|
FormGroup FormArray FormControl --> derived classes
class class class
1.valid-it will return true | false
true-validation[s] is success
2.invalid-it will return true | false
true-validation[s] is failed
3.touched-it will return true | false
true-focus to control
4.untouched-it will return true | false
true-no focus to control
5.pristine-it will return true | false
true-control is not edited
6.dirty-it will return true | false
true-control is edited
7.value-it will provide model props data
<modelname | formgroupname>.value.<propname>
8.hasError('validationname')-it will return true|false
true-validation is failed
mobile--required validation
pattern is 10 digit
<span *ngIf="usermodel.controls['mobile'].invalid">
error message-->common for required and pattern
</span>
(or)
<span *ngIf="usermodel.controls['mobile'].hasError('required')">
...
</span>
<span *ngIf="usermodel.controls['mobile'].hasError('pattern')">
...
</span>
steps to work with mdf:
-----------------------
1.create|build a model with collection of props
syntax:
this.<modelname>=new FormGroup({
<propname1>:new FormControl(initialvalue,[validation[s]]),
...
},{updateOn:'change|blur|submit'});
this.userModel=new FormGroup(
{
firstname:new FormControl("",[Validators.required]),
lastname:new FormControl("",[Validators.required]),
emailid:new FormControl("xyz@gmail.com",[Validators.email])
},{updateOn:'change'}
);
2.bind model and props to template
syntax:
<form [formGroup]="modelname" ..>
<input formControlName="propname">
..
</form>
<form [formGroup]="userModel" (ngSubmit)="register()">
firstname:<input formControlName="firstname">
<span *ngIf="userModel.controls['firstname'].invalid">
enter firstname
</span>
3.place|import ReactiveFormsModule into AppModule
Features of Reactive Forms:
- More flexible, but need a lot of practice
- Handles any complex scenarios.
- No data binding is done (Immutable data model preferred by most developers).
- More component code and less HTML Markup.
- Easier unit testing.
- Reactive transformations can be made possible such as
- Handling a event based on a denounce time.
- Handling events when the components are distinct until changed.
- Adding elements dynamically.