When it to comes to large data oriented forms, complexity increases while validating the controls and so it becomes necessary to use a better and efficient approach to validate them.
One of the most efficient approach is decorator based validation, the benefit of using it is you can use model based strategy to construct angular reactive forms in which you just need to add a decorator @alpha()
,@required()
on the class property, you don't need to add any extra code in HTML or create any custom validation function in the component
Let's make it happen in a few steps:
1) Install @rxweb/reactive-form-validators
npm install @rxweb/reactive-form-validators
2) You also need import RxReactiveFormsModule
in the app.module.
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule,ReactiveFormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { RxReactiveFormsModule } from "@rxweb/reactive-form-validators"
@NgModule({
imports: [ BrowserModule,
FormsModule,ReactiveFormsModule,RxReactiveFormsModule ],
declarations: [AppComponent],
bootstrap: [ AppComponent]
})
export class AppModule { }
3) Create User Model:
Let's create a user model class and create properties like firstName, lastName and username, password and confirmPassword into it and pass the respective validation decorators.
import { required, compare, alpha, minLength } from "@rxweb/reactive-form-validators";
export class User {
@required()
firstName:string;
@required()
lastName:string;
@required()
@alpha()
userName:string;
@required()
@minLength({value:8})
password:string;
@required()
@compare({fieldName:'password'})
confirmPassword:string;
}
4) Create user component:
Now, Let's create a user component for building the reactive form based upon our model class. for that you need to import RxFormBuilder
and create the formGroup object with the use of the user model class.
import { Component, OnInit } from '@angular/core';
import { FormGroup } from "@angular/forms"
import { RxFormBuilder } from '@rxweb/reactive-form-validators';
import { User } from './user.model';
@Component({
selector: 'app-user',
templateUrl: './user.component.html'
})
export class UserComponent implements OnInit {
userFormGroup: FormGroup
constructor(
private formBuilder: RxFormBuilder
) { }
ngOnInit()
{
let user = new User();
this.userFormGroup = this.formBuilder.formGroup(user);
}
}
5) Create user form:
Create a user form and inside the formGroup
element define all the properties as formControl
<h1 class="bd-title" id="content">User Registration Form</h1>
<br/>
<form *ngIf="userFormGroup" [formGroup]="userFormGroup">
<div class="form-group">
<label>First Name</label>
<input type="text" formControlName="firstName" class="form-control" />
<small class="form-text text-danger" *ngIf="userFormGroup.controls.firstName.errors">{{userFormGroup.controls.firstName.errors.required.message}}<br/></small>
</div>
<div class="form-group">
<label>Last Name</label>
<input type="text" formControlName="lastName" class="form-control" />
<small class="form-text text-danger" *ngIf="userFormGroup.controls.lastName.errors">{{userFormGroup.controls.lastName.errors.required.message}}<br/></small>
</div>
<div class="form-group">
<label>User Name</label>
<input type="text" formControlName="userName" class="form-control" />
<small class="form-text text-danger" *ngIf="userFormGroup.controls.userName.errors && userFormGroup.controls.userName.errors.required">{{userRegistrationFormGroup.controls.userName.errors.required.message}}<br/></small>
<small class="form-text text-danger" *ngIf="userFormGroup.controls.userName.errors && userFormGroup.controls.userName.errors.alpha">{{userFormGroup.controls.userName.errors.alpha.message}}<br/></small>
</div>
<div class="form-group">
<label>Password</label>
<input type="password" formControlName="password" class="form-control" />
<small class="form-text text-danger" *ngIf="userFormGroup.controls.password.errors && userFormGroup.controls.password.errors.required">{{userFormGroup.controls.password.errors.required.message}}</small>
<small class="form-text text-danger" *ngIf="userFormGroup.controls.password.errors && userFormGroup.controls.password.errors.minLength">{{userFormGroup.controls.password.errors.minLength.message}}<br/></small>
</div>
<div class="form-group">
<label>Confirm Password</label>
<input type="password" formControlName="confirmPassword" class="form-control" />
<small class="form-text text-danger" *ngIf="userFormGroup.controls.confirmPassword.errors && userFormGroup.controls.confirmPassword.errors.compare">{{userFormGroup.controls.confirmPassword.errors.compare.message}}<br/></small>
</div>
<button [disabled]="!userFormGroup.valid" class="btn btn-primary">Submit</button>
</form>
6) Configure validation messages globally
For displaying the validation messages if the formControl
becomes invalid. you need to configure it globally in app component
You have to use ReactiveFormConfig
class set method and pass the validation message object.
ReactiveFormConfig.set({
"validationMessage": {
"required": "This field is required.",
"minLenght":"Enter minimum length of {{0}} characters.",
"compare":"The value should be matched with {{0}}.",
"alpha":"you can only enter alphabets."
}
});
Please refer the working example code
Other benefits to use this approach:
Conditional validation :
In some of the cases you may require your validation to be fired based upon some condition. To implement it using decorator based approach you must pass parameter conditionalExpression
in the decorator above the property.
import {required} from "@rxweb/reactive-form-validators"
export class User{
@required()
firstName:string;
@required({conditionalExpressions:(x=>x.firstName == "John")})
lastName:string;
}
Please refer the working example
Show Custom Message :
If you want to show a custom validation message on a particular field, You must pass it in message
parameter in the decorator above the property.
import {required} from "@rxweb/reactive-form-validators"
export class User{
@required()
firstName:string;
@required({message:"Last Name is required"})
lastName:string;
}
Please refer the working example
This validation framework has several other validators which can be used directly in component without creating custom validation functions
If you have any question/suggestion, Please share your comments below.
Top comments (0)