Reactive forms provide a model-driven approach to handling form inputs whose values change over the time. It is more flexible but more complex scenario, easier to perform an action on value change.
In this article, We will learn ‘Reactive forms validation’. I explain simply step by step forms validation. Follow below steps.
You can create an app by the below command.
npm install -g @angular/cli
ng new reactive-form
cd reactive-form
npm start
Now, open your app.module.ts file and add the below imports there.
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { ReactiveFormsModule } from '@angular/forms'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule,ReactiveFormsModule, AppRoutingModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Open your app.component.html file and add the below form there.
<div class="register-form"> <h3>Register form</h3> <form [formGroup]="registerForm" (ngSubmit)="onSubmit()"> <div class="form-group"> <label>Full Name</label> <input type="text" formControlName="fullname" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.fullname.errors }" /> <div *ngIf="submitted && f.fullname.errors" class="invalid-feedback"> <div *ngIf="f.fullname.errors.required">Fullname is required</div> </div> </div> <div class="form-group"> <label>Username</label> <input type="text" formControlName="username" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.username.errors }" /> <div *ngIf="submitted && f.username.errors" class="invalid-feedback"> <div *ngIf="f.username.errors.required">Username is required</div> <div *ngIf="f.username.errors.minlength"> Username must be at least 6 characters </div> <div *ngIf="f.username.errors.maxlength"> Username must not exceed 20 characters </div> </div> </div> <div class="form-group"> <label>Email</label> <input type="text" formControlName="email" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.email.errors }" /> <div *ngIf="submitted && f.email.errors" class="invalid-feedback"> <div *ngIf="f.email.errors.required">Email is required</div> <div *ngIf="f.email.errors.email">Email is invalid</div> </div> </div> <div class="form-group"> <label>Password</label> <input type="password" formControlName="password" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.password.errors }" /> <div *ngIf="submitted && f.password.errors" class="invalid-feedback"> <div *ngIf="f.password.errors.required">Password is required</div> <div *ngIf="f.password.errors.minlength"> Password must be at least 6 characters </div> <div *ngIf="f.password.errors.maxlength"> Username must not exceed 40 characters </div> </div> </div> <div class="form-group"> <label>Confirm Password</label> <input type="password" formControlName="confirmPassword" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.confirmPassword.errors }" /> <div *ngIf="submitted && f.confirmPassword.errors" class="invalid-feedback"> <div *ngIf="f.confirmPassword.errors.required"> Confirm Password is required </div> <div *ngIf="f.confirmPassword.errors.mustMatch"> Confirm Password does not match </div> </div> </div> <div class="form-group form-check"> <input type="checkbox" formControlName="acceptTerms" class="form-check-input" [ngClass]="{ 'is-invalid': submitted && f.acceptTerms.errors }" /> <label for="acceptTerms" class="form-check-label" >I have read and agree to the Terms</label> <div *ngIf="submitted && f.acceptTerms.errors" class="invalid-feedback"> Accept Terms is required </div> </div> <div class="form-button"> <button type="submit" class="btn-primary">Register</button> <button type="button" (click)="onReset()" class="btn-warning">Reset</button> </div> </form> </div>
Open your app.component.ts file and add the below code there.
import { Component, OnInit } from '@angular/core'; import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms'; import { MustMatch } from './confirmed.validator'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'reactive-form'; registerForm: FormGroup; submitted = false; constructor(private formBuilder: FormBuilder) { this.registerForm = this.formBuilder.group( { fullname: ['', Validators.required], username: [ '', [ Validators.required, Validators.minLength(6), Validators.maxLength(20) ] ], email: ['', [Validators.required, Validators.email]], password: [ '', [ Validators.required, Validators.minLength(6), Validators.maxLength(40) ] ], confirmPassword: ['', Validators.required], acceptTerms: [false, Validators.requiredTrue] }, { validator: MustMatch('password', 'confirmPassword') } ); } ngOnInit(): void { } get f(): { [key: string]: AbstractControl } { return this.registerForm.controls; } onSubmit(): void { this.submitted = true; if (this.registerForm.invalid) { return; } console.log(JSON.stringify(this.registerForm.value, null, 2)); } onReset(): void { this.submitted = false; this.registerForm.reset(); } }
Create confirmed.validator.ts file in app folder for password validation and add the below code there
import { FormGroup } from '@angular/forms'; export function MustMatch(controlName: string, matchingControlName: string) { return (formGroup: FormGroup) => { const control = formGroup.controls[controlName]; const matchingControl = formGroup.controls[matchingControlName]; if (matchingControl.errors && !matchingControl.errors.mustMatch) { return; } if (control.value !== matchingControl.value) { matchingControl.setErrors({ mustMatch: true }); } else { matchingControl.setErrors(null); } } }
Now, add some basic css in app.component.css file
body{ margin: 0; font-size: 14px; font-family: monospace; } .register-form { max-width: 450px; margin: 0 auto; font-family: Arial, Helvetica, sans-serif; font-size: 14px; } h3{ text-align: center; font-size: 22px; } label{ font-weight: 600; opacity: .7; margin-bottom: 5px; display: inline-block; } .form-group{ margin-bottom: 15px; } .form-control{ width: 427px; display: block; border: 1px solid #ddd; border-radius: 5px; padding: 10px; } .form-button{ display: flex; justify-content: space-between; } .form-button button{ width: 100px; height: 40px; border: 1px solid #ddd; background-color: #fff; color: #000; transition: all .3s; } .form-button button.btn-primary{background-color: #5151fd;color: #fff;} .form-button button.btn-warning{background-color: #ef551a;color: #000;} .form-button button:hover{ cursor: pointer; background-color: #000; color: #fff; border-color: #000; } .invalid-feedback{font-size: 12px;color: #ff0000;}
That’s it! now check your output