Open In App

Angular - Confirm Password Validation Using Custom Validators

Last Updated : 08 Jan, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

To confirm password validation in Angular forms, you can use a custom validator to ensure two password fields (like password and confirmPassword) match. This is especially useful in sign-up or password reset forms where password confirmation is necessary.

Prerequisite

Steps To Implement CustomConfirm Password Validation

Step 1: Install Angular CLI if you haven't installed it already.

npm install -g @angular/cli

Step 2: Create a new Angular application using the following command.

ng new password-validator-app

Folder Structure

angular-folder-structure
Folder Structure

Dependencies

"dependencies": {
"@angular/animations": "^18.2.0",
"@angular/common": "^18.2.0",
"@angular/compiler": "^18.2.0",
"@angular/core": "^18.2.0",
"@angular/forms": "^18.2.0",
"@angular/platform-browser": "^18.2.0",
"@angular/platform-browser-dynamic": "^18.2.0",
"@angular/router": "^18.2.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.10"
}

Step 3: Create the Component Logic

In app.component.ts, create the form using the FormBuilder service, adding custom validators for password complexity requirements and a validator to confirm that the password and confirm password fields match.

JavaScript
//app.component.ts

import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import {
    FormBuilder,
    FormGroup,
    ReactiveFormsModule,
    Validators,
    AbstractControl,
} from '@angular/forms';
import { RouterOutlet } from '@angular/router';

@Component({
    selector: 'app-root',
    standalone: true,
    imports: [RouterOutlet, CommonModule, ReactiveFormsModule],
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
})
export class AppComponent {
    title = 'password-validator-app';
    passwordForm: FormGroup;

    constructor(private fb: FormBuilder) {
        this.passwordForm = this.fb.group(
            {
                password: [
                    '',
                    [
                        Validators.required,
                        Validators.minLength(6),
                        this.hasUppercase,
                        this.hasNumber,
                        this.hasSpecialCharacter,
                    ],
                ],
                confirmPassword: ['', Validators.required],
            },
            { validator: this.passwordMatchValidator }
        );
    }

    // Custom validator to check if passwords match
    passwordMatchValidator(form: FormGroup) {
        const password = form.get('password')?.value;
        const confirmPassword = form.get('confirmPassword')?.value;
        if (password !== confirmPassword) {
            return { passwordMismatch: true };
        }
        return null;
    }

    // Custom validator to check if the password contains at least one uppercase letter
    hasUppercase(control: AbstractControl) {
        const value = control.value;
        if (value && !/[A-Z]/.test(value)) {
            return { uppercase: true };
        }
        return null;
    }

    // Custom validator to check if the password contains at least one number
    hasNumber(control: AbstractControl) {
        const value = control.value;
        if (value && !/\d/.test(value)) {
            return { number: true };
        }
        return null;
    }

    // Custom validator to check if the password contains at least one special character
    hasSpecialCharacter(control: AbstractControl) {
        const value = control.value;
        if (value && !/[!@#$%^&*(),.?":{}|<>]/.test(value)) {
            return { specialCharacter: true };
        }
        return null;
    }

    // Form Submit
    onSubmit() {
        if (this.passwordForm.valid) {
            alert(`Form Submitted Successfully`);
        } else {
            alert('Please check the form for errors');
        }
    }

    // check if a specific control has a specific error and if it was touched
    hasError(controlName: string, errorName: string) {
        return (
            this.passwordForm.get(controlName)?.hasError(errorName) &&
            this.passwordForm.get(controlName)?.touched
        );
    }
}

In this code

  • Password Match Validator (passwordMatchValidator): Verifies that password and confirmPassword fields match.
  • Uppercase Validator (hasUppercase): Ensures that the password has at least one uppercase letter.
  • Number Validator (hasNumber): Ensures that the password contains at least one number.
  • Special Character Validator (hasSpecialCharacter): Ensures that the password includes at least one special character.

Step 4: Create the HTMl template.

In app.component.html, set up the form with the appropriate form controls and error messages

HTML
<!-- app.component.html -->

<h1>Password Confirmation Form</h1>
<form [formGroup]="passwordForm" (ngSubmit)="onSubmit()">
    <div>
        <label for="password">Password:</label>
        <input type="password" id="password" formControlName="password" />
    </div>

    <!-- Error messages for password field -->
    <div *ngIf="hasError('password', 'required')">
        <p style="color: red">Password is required</p>
    </div>
    <div *ngIf="hasError('password', 'minlength')">
        <p style="color: red">Password must be at least 6 characters long</p>
    </div>
    <div *ngIf="hasError('password', 'uppercase')">
        <p style="color: red">
            Password must contain at least one uppercase letter
        </p>
    </div>
    <div *ngIf="hasError('password', 'number')">
        <p style="color: red">Password must contain at least one number</p>
    </div>
    <div *ngIf="hasError('password', 'specialCharacter')">
        <p style="color: red">
            Password must contain at least one special character
        </p>
    </div>

    <div>
        <label for="confirmPassword">Confirm Password:</label>
        <input type="password" id="confirmPassword" formControlName="confirmPassword" />
    </div>

    <!-- Error messages for confirm password field -->
    <div *ngIf="passwordForm.errors?.['passwordMismatch'] && passwordForm.get('confirmPassword')?.touched">
        <p style="color: red">Passwords do not match!</p>
    </div>

    <button type="submit" [disabled]="passwordForm.invalid">Submit</button>
</form>

Step 5: Style the Form.

In app.component.css, apply basic styling to improve the form's appearance.

CSS
/* app.component.css */

h1 {
    text-align: center;
}
form {
    max-width: 400px;
    margin: 0 auto;
  }
div {
    margin-bottom: 10px;
  }
input {
    padding: 5px;
    width: 100%;
    box-sizing: border-box;
  }
button {
    padding: 5px 10px;
  }
p {
    color: red;
    font-size: 12px;
  }  

To run the application, use the below command

ng serve

Output


Next Article
Article Tags :

Similar Reads