Form validation in Angular mat form

585 views Asked by At

I am building login form using angular mat form.

Login form is following.

login-form.component.html

<form [formGroup]="registerForm" (ngSubmit)="onSubmit()">
  <div fxLayout="column" fxLayoutAlign="center center">
    <div fxFlex="100%">
      <mat-form-field appearance="outline" class="form-field">
        <mat-label>Full Name</mat-label>
        <input matInput formControlName="name" name="name">
        <mat-error *ngIf="registerForm.get('name').hasError('required')">This field is required</mat-error>
        <mat-error *ngIf="registerForm.get('name').hasError('pattern')">Must be your full name</mat-error>
      </mat-form-field>
    </div>
    <div fxFlex="100%">
      <mat-form-field appearance="outline" class="form-field">
        <mat-label>Email</mat-label>
        <input matInput formControlName="email" name="email">
      </mat-form-field>
    </div>
    <div fxFlex="100%">
      <mat-form-field appearance="outline" class="form-field">
        <mat-label>Password</mat-label>
        <input matInput formControlName="password" name="password" type="password">
        <mat-error *ngIf="registerForm.value.password">Password must be a combination of lower-case, upper-case, numbers
          and at least 9 characters long</mat-error>
      </mat-form-field>
    </div>
    <div fxFlex="100%">
      <mat-form-field appearance="outline" class="form-field">
        <mat-label>Confirm Password</mat-label>
        <input matInput formControlName="confirmPassword" name="confirmPassword" type="password">
        <mat-error *ngIf="registerForm.value.confirmPassword">Passwords do not match.</mat-error>
      </mat-form-field>
    </div>
    <div fxFlex="100%">
      <button mat-stroked-button color="primary" type="submit"
        [disabled]="!registerForm.valid">Register<mat-icon>chevron_right</mat-icon></button>
    </div>
  </div>
</form>

login-form.component.ts

import { Component, OnInit } from '@angular/core';
import { AbstractControl, FormControl, FormGroup, ValidationErrors, ValidatorFn, Validators } from '@angular/forms';

@Component({
  selector: 'app-login-form',
  templateUrl: './login-form.component.html',
  styleUrls: ['./login-form.component.css']
})
export class LoginFormComponent {
  registerForm = new FormGroup({
    name: new FormControl('', [Validators.pattern(/\s/), Validators.required]),
    email: new FormControl('', [Validators.required, Validators.email]),
    password: new FormControl('', [Validators.required, Validators.pattern('^(?=.*[A-Z])(?=.*[0-9])(?=.*[a-z]).{8,}$')]),
    confirmPassword: new FormControl('', Validators.required)
  }, { validators: confirmPasswordValidator})

  onSubmit(): void {
    // display some fireworks
  }
}

export const confirmPasswordValidator: ValidatorFn = (control: AbstractControl): ValidationErrors | null => {
  const password = control.get('password');
  const confirmPassword = control.get('confirmPassword');

  return password && confirmPassword && password.value === confirmPassword.value ? { confirmPassword: true } : null;
};

For individual form controls, the validation is working well. But When the password and confirmPassword is different, the invalid message is not displayed. It looks like a valid form.
I think custom validator confirmPasswordValidator is not working.

1

There are 1 answers

3
Aman Gojariya On

Please create custom validator like below

Here is form,

ngOnInit() {
    this.registerForm = this.fb.group({
          password: ['', [Validators.required]],
          confirmPassword: ['', [Validators.required]]
      }, { validator: this.checkPassword('password', 'confirmPassword') 
    });
}

Here is my checkPassword function,

checkPassword(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 another validator has already found an error on the matchingControl
        return;
      }
      // set error on matchingControl if validation fails
      if (control.value !== matchingControl.value) {
        matchingControl.setErrors({ mustMatch: true });
        this.isPasswordSame = (matchingControl.status == 'VALID') ? true : false;
      } else {
        matchingControl.setErrors(null);
        this.isPasswordSame = (matchingControl.status == 'VALID') ? true : false;
      }
    }
}

Here I am showing errors in HTML,

<mat-form-field>
     <mat-label>Confirm Password</mat-label>
     <input [type]="inputType" formControlName="confirmPassword" matInput required>
     <mat-error *ngIf="registerForm.get('confirmPassword').hasError('required')">Please Enter Confirm Password.</mat-error>
     <mat-error *ngIf="registerForm.get('confirmPassword').hasError('mustMatch')">Confirm Password does not match with Password.</mat-error>
</mat-form-field>