Confirm password validation in Angular 6

2020-01-24 20:10发布

I want to perform password and confirm password validations using material components only,and an error message below the confirm password field if confirm password field doesn't match And if it is empty.Tried many resources unable to achieve.

Tried this video too.

This is the material component i am looking for

enter image description here

HTML

     <mat-form-field >
        <input matInput  placeholder="New password" [type]="hide ? 'password' 
          : 'text'" [formControl]="passFormControl" required>
        <mat-icon matSuffix (click)="hide = !hide">{{hide ? 'visibility' : 
          'visibility_off'}}</mat-icon>
        <mat-error *ngIf="passFormControl.hasError('required')">
            Please enter your newpassword
         </mat-error>
      </mat-form-field>

      <mat-form-field >
         <input matInput  placeholder="Confirm password" [type]="hide ? 
              'password' : 'text'" [formControl]="confirmFormControl" 
                    required>
         <mat-icon matSuffix (click)="hide = !hide">{{hide ? 'visibility' : 
                'visibility_off'}}</mat-icon>
         <mat-error *ngIf="confirmFormControl.hasError('required')">
          Confirm your password
          </mat-error>
      </mat-form-field>

TS

     import {Component, OnInit } from '@angular/core';
     import {FormControl, FormGroupDirective, NgForm, Validators} from 
             '@angular/forms';
     import {ErrorStateMatcher} from '@angular/material/core';

     @Component({
            selector: 'asd-set-pass',
            templateUrl: './set-pass.component.html',
             styleUrls: ['./set-pass.component.css']
         })

       passFormControl = new FormControl('', [
            Validators.required,
        ]);
        confirmFormControl = new FormControl('', [
            Validators.required,
            ]);

             hide =true;

       }

It's validating the following conditions fine 1)If password and confirm password fields are empty its showing error text.

I want to compare to fields in (.ts) file like how its validating for empty field, and an error to come if confirm password field is empty.

13条回答
聊天终结者
2楼-- · 2020-01-24 20:49

In case you have more than just Password and Verify Password fields. Like this the Confirm password field will only highlights error when user write something on this field:

validators.ts

import { FormGroup, FormControl, Validators, FormBuilder, FormGroupDirective, NgForm } from '@angular/forms';
import { ErrorStateMatcher } from '@angular/material/core';

export const EmailValidation = [Validators.required, Validators.email];
export const PasswordValidation = [
  Validators.required,
  Validators.minLength(6),
  Validators.maxLength(24),
];

export class RepeatPasswordEStateMatcher implements ErrorStateMatcher {
  isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
    return (control && control.parent.get('password').value !== control.parent.get('passwordAgain').value && control.dirty)
  }
}
export function RepeatPasswordValidator(group: FormGroup) {
  const password = group.controls.password.value;
  const passwordConfirmation = group.controls.passwordAgain.value;

  return password === passwordConfirmation ? null : { passwordsNotEqual: true }     
}

register.component.ts

import { FormGroup, FormControl, Validators, FormBuilder} from '@angular/forms';
import { EmailValidation, PasswordValidation, RepeatPasswordEStateMatcher, RepeatPasswordValidator } from 'validators';

...

form: any;
passwordsMatcher = new RepeatPasswordEStateMatcher;


constructor(private formBuilder: FormBuilder) {
    this.form = this.formBuilder.group ( {
      email: new FormControl('', EmailValidation),
      password: new FormControl('', PasswordValidation),
      passwordAgain: new FormControl(''),
      acceptTerms: new FormControl('', [Validators.requiredTrue])
    }, { validator: RepeatPasswordValidator });
  }

...

register.component.html

<form [formGroup]="form" (ngSubmit)="submitAccount(form)">
    <div class="form-content">
        <div class="form-field">
            <mat-form-field>
            <input matInput formControlName="email" placeholder="Email">
            <mat-error *ngIf="form.get('email').hasError('required')">
                E-mail is mandatory.
            </mat-error>
            <mat-error *ngIf="form.get('email').hasError('email')">
                Incorrect E-mail.
            </mat-error>
            </mat-form-field>
        </div>
        <div class="form-field">
            <mat-form-field>
            <input matInput formControlName="password" placeholder="Password" type="password">
            <mat-hint class="ac-form-field-description">Between 6 and 24 characters.</mat-hint>
            <mat-error *ngIf="form.get('password').hasError('required')">
                Password is mandatory.
            </mat-error>
            <mat-error *ngIf="form.get('password').hasError('minlength')">
                Password with less than 6 characters.
            </mat-error>
            <mat-error *ngIf="form.get('password').hasError('maxlength')">
                Password with more than 24 characters.
            </mat-error>
            </mat-form-field>
        </div>
        <div class="form-field">
            <mat-form-field>
            <input matInput formControlName="passwordAgain" placeholder="Confirm the password" type="password" [errorStateMatcher]="passwordsMatcher">
            <mat-error *ngIf="form.hasError('passwordsNotEqual')" >Passwords are different. They should be equal!</mat-error>
            </mat-form-field>
        </div>
        <div class="form-field">
            <mat-checkbox name="acceptTerms" formControlName="acceptTerms">I accept terms and conditions</mat-checkbox>
        </div>
    </div>
    <div class="form-bottom">
        <button mat-raised-button [disabled]="!form.valid">Create Account</button>
    </div>
</form>

i hope it helps!

查看更多
做个烂人
3楼-- · 2020-01-24 20:53

I am using angular 6 and I have been searching on best way to match password and confirm password. This can also be used to match any two inputs in a form. I used Angular Directives. I have been wanting to use them

ng g d compare-validators --spec false and i will be added in your module. Below is the directive

import { Directive, Input } from '@angular/core';
import { Validator, NG_VALIDATORS, AbstractControl, ValidationErrors } from '@angular/forms';
import { Subscription } from 'rxjs';

@Directive({
  // tslint:disable-next-line:directive-selector
  selector: '[compare]',
  providers: [{ provide: NG_VALIDATORS, useExisting: CompareValidatorDirective, multi: true}]
})
export class CompareValidatorDirective implements Validator {
  // tslint:disable-next-line:no-input-rename
  @Input('compare') controlNameToCompare;

  validate(c: AbstractControl): ValidationErrors | null {
    if (c.value.length < 6 || c.value === null) {
      return null;
    }
    const controlToCompare = c.root.get(this.controlNameToCompare);

    if (controlToCompare) {
      const subscription: Subscription = controlToCompare.valueChanges.subscribe(() => {
        c.updateValueAndValidity();
        subscription.unsubscribe();
      });
    }

    return controlToCompare && controlToCompare.value !== c.value ? {'compare': true } : null;
  }

}

Now in your component

<div class="col-md-6">
              <div class="form-group">
                <label class="bmd-label-floating">Password</label>
                <input type="password" class="form-control" formControlName="usrpass" [ngClass]="{ 'is-invalid': submitAttempt && f.usrpass.errors }">
                <div *ngIf="submitAttempt && signupForm.controls['usrpass'].errors" class="invalid-feedback">
                  <div *ngIf="signupForm.controls['usrpass'].errors.required">Your password is required</div>
                  <div *ngIf="signupForm.controls['usrpass'].errors.minlength">Password must be at least 6 characters</div>
                </div>
              </div>
            </div>
            <div class="col-md-6">
              <div class="form-group">
                <label class="bmd-label-floating">Confirm Password</label>
                <input type="password" class="form-control" formControlName="confirmpass" compare = "usrpass"
                [ngClass]="{ 'is-invalid': submitAttempt && f.confirmpass.errors }">
                <div *ngIf="submitAttempt && signupForm.controls['confirmpass'].errors" class="invalid-feedback">
                  <div *ngIf="signupForm.controls['confirmpass'].errors.required">Your confirm password is required</div>
                  <div *ngIf="signupForm.controls['confirmpass'].errors.minlength">Password must be at least 6 characters</div>
                  <div *ngIf="signupForm.controls['confirmpass'].errors['compare']">Confirm password and Password dont match</div>
                </div>
              </div>
            </div>

I hope this one helps

查看更多
一夜七次
4楼-- · 2020-01-24 20:57

My answer is very simple>i have created password and confirm password validation using template driiven in angular 6

My html file

<div class="form-group">
  <label class="label-sm">Confirm Password</label>
  <input class="form-control" placeholder="Enter Password" type="password" #confirm_password="ngModel" [(ngModel)]="userModel.confirm_password" name="confirm_password" required (keyup)="checkPassword($event)" />
  <div *ngIf="confirm_password.errors && (confirm_password.dirty||confirm_password.touched||signup.submitted)">
  <div class="error" *ngIf="confirm_password.errors.required">Please confirm your password</div>
  </div>
  <div *ngIf="i" class='error'>Password does not match</div>
</div>

My typescript file

      public i: boolean;

      checkPassword(event) {
        const password = this.userModel.password;
        const confirm_new_password = event.target.value;

        if (password !== undefined) {
          if (confirm_new_password !== password) {
            this.i = true;
          } else {
            this.i = false;
          }
        }
      }

when clicking on submit button i check whether value of i is true or false

if true

if (this.i) {
      return false;
    }

else{
**form submitted code comes here**
}
查看更多
兄弟一词,经得起流年.
5楼-- · 2020-01-24 20:59

I found a bug in AJT_82's answer. Since I do not have enough reputation to comment under AJT_82's answer, I have to post the bug and solution in this answer.

Here is the bug:

enter image description here

Solution: In the following code:

export class MyErrorStateMatcher implements ErrorStateMatcher {
  isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
    const invalidCtrl = !!(control && control.invalid && control.parent.dirty);
    const invalidParent = !!(control && control.parent && control.parent.invalid && control.parent.dirty);

    return (invalidCtrl || invalidParent);
  }
}

Change control.parent.invalid to control.parent.hasError('notSame') will solve this problem.

After the small changes, the problem solved.

enter image description here

查看更多
够拽才男人
6楼-- · 2020-01-24 21:02

The simplest way imo:

(It can also be used with emails for example)

public static matchValues(
    matchTo: string // name of the control to match to
  ): (AbstractControl) => ValidationErrors | null {
    return (control: AbstractControl): ValidationErrors | null => {
      return !!control.parent &&
        !!control.parent.value &&
        control.value === control.parent.controls[matchTo].value
        ? null
        : { isMatching: false };
    };
}

In your Component:

this.SignUpForm = this.formBuilder.group({

password: [undefined, [Validators.required]],
passwordConfirm: [undefined, 
        [
          Validators.required,
          matchValues('password'),
        ],
      ],
});
查看更多
SAY GOODBYE
7楼-- · 2020-01-24 21:03

I did it like this. hope this will help you.

HTML :

<form [formGroup]='addAdminForm'>   
          <div class="form-group row">
            <label class="col-sm-3 col-form-label">Password</label>
            <div class="col-sm-7">
              <input type="password" class="form-control" formControlName='password' (keyup)="checkPassSame()">

              <div *ngIf="addAdminForm.controls?.password?.invalid && addAdminForm.controls?.password.touched">
                <p *ngIf="addAdminForm.controls?.password?.errors.required" class="errorMsg">*This field is required.</p>
              </div>
            </div>
          </div>

          <div class="form-group row">
            <label class="col-sm-3 col-form-label">Confirm Password</label>
            <div class="col-sm-7">
              <input type="password" class="form-control" formControlName='confPass' (keyup)="checkPassSame()">

              <div *ngIf="addAdminForm.controls?.confPass?.invalid && addAdminForm.controls?.confPass.touched">
                <p *ngIf="addAdminForm.controls?.confPass?.errors.required" class="errorMsg">*This field is required.</p>
              </div>
              <div *ngIf="passmsg != '' && !addAdminForm.controls?.confPass?.errors?.required">
                <p class="errorMsg">*{{passmsg}}</p>
              </div>  
            </div>
          </div>
      </form>

TS File :

export class AddAdminAccountsComponent implements OnInit {

  addAdminForm: FormGroup;
  password: FormControl;
  confPass: FormControl;
  passmsg: string;


  constructor(
    private http: HttpClient,
    private router: Router,
  ) { 
  }

  ngOnInit() {    
    this.createFormGroup();
  }



    // |---------------------------------------------------------------------------------------
    // |------------------------ form initialization -------------------------
    // |---------------------------------------------------------------------------------------
    createFormGroup() {    
      this.addAdminForm = new FormGroup({
        password: new FormControl('', [Validators.required]),
        confPass: new FormControl('', [Validators.required]),
      })
    }



    // |---------------------------------------------------------------------------------------
    // |------------------------ Check method for password and conf password same or not -------------------------
    // |---------------------------------------------------------------------------------------

    checkPassSame() {
      let pass = this.addAdminForm.value.password;
      let passConf = this.addAdminForm.value.confPass;
      if(pass == passConf && this.addAdminForm.valid === true) {
        this.passmsg = "";
        return false;
      }else {
        this.passmsg = "Password did not match.";
        return true;
      }
    }



}
查看更多
登录 后发表回答