在Angular 6中确认密码验证

Sha*_*kar 47 angular-material angular angular-forms

我想只使用材料组件执行密码确认密码验证 ,如果和.确认许多资源无法实现,则在确认密码字段下面显示错误消息.confirm password field doesn't matchif it is empty

也试过这个视频.

这是我正在寻找的材料成分

在此输入图像描述

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>
Run Code Online (Sandbox Code Playgroud)

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;

       }
Run Code Online (Sandbox Code Playgroud)

它正在验证以下条件:1)如果密码和确认密码字段为空,则显示错误文本.

我想比较(.ts)文件中的字段,比如它如何验证空字段,以及如果确认密码字段为空则会出现错误.

AJT*_*T82 82

这两个答案的结合可以解决这个问题:https://stackoverflow.com/a/43493648/6294072/sf/answers/3336962471/

首先,您需要一个自定义验证器来检查密码,它们可能如下所示:

checkPasswords(group: FormGroup) { // here we have the 'passwords' group
  let pass = group.get('password').value;
  let confirmPass = group.get('confirmPass').value;

  return pass === confirmPass ? null : { notSame: true }     
}
Run Code Online (Sandbox Code Playgroud)

并且您将为您的字段创建一个表单组,而不只是两个表单控件,然后为您的表单组标记该自定义验证器:

this.myForm = this.fb.group({
  password: ['', [Validators.required]],
  confirmPassword: ['']
}, {validator: this.checkPasswords })
Run Code Online (Sandbox Code Playgroud)

然后如其他答案中所述,mat-error仅显示FormControl是否无效,因此您需要一个错误状态匹配器:

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);
  }
}
Run Code Online (Sandbox Code Playgroud)

在上面你可以调整何时显示错误信息.我只会在password触摸该字段时显示消息.另外我想在上面,requiredconfirmPassword字段中删除验证器,因为如果密码不匹配,表单无论如何都无效.

然后在组件中创建一个新的ErrorStateMatcher:

matcher = new MyErrorStateMatcher();
Run Code Online (Sandbox Code Playgroud)

最后,模板看起来像这样:

<form [formGroup]="myForm">
  <mat-form-field>
    <input matInput placeholder="New password" formControlName="password" required>
    <mat-error *ngIf="myForm.hasError('required', 'password')">
        Please enter your new password
    </mat-error>
  </mat-form-field>

  <mat-form-field>
    <input matInput placeholder="Confirm password" formControlName="confirmPassword" [errorStateMatcher]="matcher">
    <mat-error *ngIf="myForm.hasError('notSame')">
        Passwords do not match
    </mat-error>  
  </mat-form-field>
</form>
Run Code Online (Sandbox Code Playgroud)

以下是使用上述代码的演示:StackBlitz

  • 您可能希望在 `MyErrorStateMatcher ` 类中添加 `control.touched`,以便即使在用户尝试重新输入密码之前也不会弹出错误。 (4认同)
  • 我遇到的一个问题是,密码匹配时控件仍然是无效事件。更改MyErrorStateMatcher的最后一行即可解决:`return control.parent.errors &amp;&amp; control.parent.errors ['notSame']` (3认同)
  • 组验证器应该是{validator:this.checkPasswords},没有s :) (2认同)

Alo*_*ali 37

您可以简单地使用密码字段值作为确认密码字段的模式。例如 :

<div class="form-group">
 <input type="password" [(ngModel)]="userdata.password" name="password" placeholder="Password" class="form-control" required #password="ngModel" pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}" />
 <div *ngIf="password.invalid && (myform.submitted || password.touched)" class="alert alert-danger">
   <div *ngIf="password.errors.required"> Password is required. </div>
   <div *ngIf="password.errors.pattern"> Must contain at least one number and one uppercase and lowercase letter, and at least 8 or more characters.</div>
 </div>
</div>

<div class="form-group">
 <input type="password" [(ngModel)]="userdata.confirmpassword" name="confirmpassword" placeholder="Confirm Password" class="form-control" required #confirmpassword="ngModel" pattern="{{ password.value }}" />
 <div *ngIf=" confirmpassword.invalid && (myform.submitted || confirmpassword.touched)" class="alert alert-danger">
   <div *ngIf="confirmpassword.errors.required"> Confirm password is required. </div>
   <div *ngIf="confirmpassword.errors.pattern"> Password & Confirm Password does not match.</div>
 </div>
</div>
Run Code Online (Sandbox Code Playgroud)

  • 这不会允许“ha..o”与“haxxo”重复吗? (4认同)
  • 这适用于特殊字符: &lt;div *ngIf="password.value!=confirmpassword.value"&gt; 密码与确认密码不匹配。&lt;/div&gt; (4认同)
  • 特别是在密码字段上,像“$”或“!”这样的控制字符如果不进行转义就不起作用。 (2认同)

Zah*_*ema 33

最简单的方式imo:

(它也可以用于例如电子邮件)

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 };
    };
}
Run Code Online (Sandbox Code Playgroud)

在您的组件中:

this.SignUpForm = this.formBuilder.group({

password: [undefined, [Validators.required]],
passwordConfirm: [undefined, 
        [
          Validators.required,
          matchValues('password'),
        ],
      ],
});
Run Code Online (Sandbox Code Playgroud)

跟进:

正如其他人在评论中指出的那样,如果您通过修复password字段来修复错误,则错误不会消失,因为验证会在passwordConfirm输入时触发。这可以通过多种方式解决。我认为最好的是:

this.SignUpForm .controls.password.valueChanges.subscribe(() => {
  this.SignUpForm .controls.confirmPassword.updateValueAndValidity();
});
Run Code Online (Sandbox Code Playgroud)

关于password变化,revliadte confirmPassword

  • 这是一个很好的解决方案,但如果您返回密码字段并更改密码,它并不完整,confirmPassword 字段不会抛出相应的错误。 (3认同)

Was*_*siF 9

响应式表单的单一方法

打字稿

// All is this method
onPasswordChange() {
  if (this.confirm_password.value == this.password.value) {
    this.confirm_password.setErrors(null);
  } else {
    this.confirm_password.setErrors({ mismatch: true });
  }
}

// getting the form control elements
get password(): AbstractControl {
  return this.form.controls['password'];
}

get confirm_password(): AbstractControl {
  return this.form.controls['confirm_password'];
}
Run Code Online (Sandbox Code Playgroud)

HTML

// PASSWORD FIELD
<input type="password" formControlName="password" (change)="onPasswordChange()"/>

// CONFIRM PASSWORD FIELD
<input type="password" formControlName="confirm_password" (change)="onPasswordChange()" />

// SHOW ERROR IF MISMATCH
<span *ngIf="confirm_password.hasError('mismatch')">Password do not match.</span>
Run Code Online (Sandbox Code Playgroud)


Hen*_*nry 7

我在 AJT_82 的答案中发现了一个错误。由于我没有足够的声誉来在 AJT_82 的答案下发表评论,因此我必须在此答案中发布错误和解决方案。

这是错误:

在此输入图像描述

解决方案:在下面的代码中:

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);
  }
}
Run Code Online (Sandbox Code Playgroud)

更改control.parent.invalidcontrol.parent.hasError('notSame')将解决此问题。

经过一些小的修改,问题就解决了。

在此输入图像描述

编辑:要仅在用户开始输入后验证确认密码字段,您可以返回此字段

return ((invalidCtrl || invalidParent) && control.valid);
Run Code Online (Sandbox Code Playgroud)


小智 6

我正在使用 angular 6,我一直在寻找匹配密码和确认密码的最佳方式。这也可用于匹配表单中的任意两个输入。我使用了角度指令。我一直想使用它们

ng gd compare-validators --spec false 并且 i 将被添加到您的模块中。下面是指令

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;
  }

}
Run Code Online (Sandbox Code Playgroud)

现在在您的组件中

<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>
Run Code Online (Sandbox Code Playgroud)

我希望这个有帮助


Cel*_*res 5

如果您不仅有密码和验证密码字段,这样,“确认密码”字段仅在用户在此字段上写一些内容时才会突出显示错误:

验证者

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 }     
}
Run Code Online (Sandbox Code Playgroud)

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 });
  }

...
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

希望对您有所帮助!


gol*_*kin 5

*此解决方案适用于反应形式

您可能听说过确认密码被称为跨域验证。而我们通常编写的字段级验证器只能应用于单个字段。对于跨文件验证,您可能必须编写一些父级验证器。对于确认密码的具体情况,我宁愿这样做:

this.form.valueChanges.subscribe(field => {
  if (field.password !== field.confirm) {
    this.confirm.setErrors({ mismatch: true });
  } else {
    this.confirm.setErrors(null);
  }
});
Run Code Online (Sandbox Code Playgroud)

这是模板:

<mat-form-field>
      <input matInput type="password" placeholder="Password" formControlName="password">
      <mat-error *ngIf="password.hasError('required')">Required</mat-error>
</mat-form-field>
<mat-form-field>
    <input matInput type="password" placeholder="Confirm New Password" formControlName="confirm">`enter code here`
    <mat-error *ngIf="confirm.hasError('mismatch')">Password does not match the confirm password</mat-error>
</mat-form-field>
Run Code Online (Sandbox Code Playgroud)


The*_*ger 5

无需使用嵌套表单组和自定义 ErrorStateMatcher 来确认密码验证。添加这些步骤是为了促进密码字段之间的协调,但您可以在没有所有开销的情况下完成此操作。

这是一个例子:

this.registrationForm = this.fb.group({
  username: ['', Validators.required],
  email: ['', [Validators.required, Validators.email]],
  password1: ['', [Validators.required, (control) => this.validatePasswords(control, 'password1') ] ],
  password2: ['', [Validators.required, (control) => this.validatePasswords(control, 'password2') ] ]
});
Run Code Online (Sandbox Code Playgroud)

请注意,我们将附加上下文传递给 validatePasswords 方法(无论源是password1 还是password2)。

  validatePasswords(control: AbstractControl, name: string) {
    if (this.registrationForm === undefined || this.password1.value === '' || this.password2.value === '') {
      return null;
    } else if (this.password1.value === this.password2.value) {
      if (name === 'password1' && this.password2.hasError('passwordMismatch')) {
        this.password1.setErrors(null);
        this.password2.updateValueAndValidity();
      } else if (name === 'password2' && this.password1.hasError('passwordMismatch')) {
        this.password2.setErrors(null);
        this.password1.updateValueAndValidity();
      }
      return null;
    } else {
      return {'passwordMismatch': { value: 'The provided passwords do not match'}};
    }  
Run Code Online (Sandbox Code Playgroud)

请注意,当密码匹配时,我们会与其他密码字段协调以更新其验证。这将清除任何过时的密码不匹配错误。

为了完整起见,这里是定义this.password1和的吸气剂this.password2

  get password1(): AbstractControl {
    return this.registrationForm.get('password1');
  }

  get password2(): AbstractControl {
    return this.registrationForm.get('password2');
  }
Run Code Online (Sandbox Code Playgroud)