wake-up-neo.com

Bestätigen Sie die Passwortüberprüfung in Angular 6

Ich möchte nur password und confirm validieren, indem nur material -Komponenten verwendet werden, und eine Fehlermeldung unter dem confirm password -Feld, wenn confirm password field doesn't match und if it is empty. Versucht viele Ressourcen, die nicht erreichbar sind .

Versuchte dieses Video auch.

Dies ist die Materialkomponente, nach der ich suche

 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;

       }

Es werden die folgenden Bedingungen in Frage gestellt: 1. Wenn die Felder für Kennwort und Kennwort bestätigen leer sind, wird der Fehlertext angezeigt.

Ich möchte mit Feldern in (.ts) -Dateien vergleichen, beispielsweise wie es für leeres Feld validiert wird, und ein Fehler wird angezeigt, wenn das Kennwort bestätigen-Feld leer ist.

17
Shankar

Diese Frage könnte mit einer Kombination dieser beiden Antworten gelöst werden: https://stackoverflow.com/a/43493648/6294072 und https://stackoverflow.com/a/47670892/6294072

Zunächst benötigen Sie einen benutzerdefinierten Prüfer, um die Kennwörter zu überprüfen. Dies könnte folgendermaßen aussehen:

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

  return pass === confirmPass ? null : { notSame: true }     
}

sie erstellen eine Formulargruppe für Ihre Felder und nicht nur zwei Formularsteuerelemente. Markieren Sie dann diesen benutzerdefinierten Prüfer für Ihre Formulargruppe:

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

und wie in einer anderen Antwort erwähnt, zeigt der mat-error nur, ob ein FormControl ungültig ist, daher benötigen Sie einen Fehlerstatusabgleicher:

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

in den obigen Abschnitten können Sie die Anzeige der Fehlermeldung ändern. Ich würde die Nachricht nur anzeigen, wenn das Feld password berührt wird. Außerdem möchte ich oben den Validator required aus dem Feld confirmPassword entfernen, da das Formular sowieso nicht gültig ist, wenn die Passwörter nicht übereinstimmen.

Dann erstellen Sie in der Komponente eine neue ErrorStateMatcher:

matcher = new MyErrorStateMatcher();

Schließlich würde die Vorlage folgendermaßen aussehen:

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

Hier ist eine Demo mit dem obigen Code für Sie: StackBlitz

44
AJT_82

Sie können den Wert des Kennwortfelds einfach als Muster für die Bestätigung des Kennwortfelds verwenden. Beispielsweise :

<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>
31
Alok Mali

Falls Sie mehr als nur Felder für Kennwort und Kennwortbestätigung haben ... So wird im Feld Kennwort bestätigen nur ein Fehler angezeigt, wenn der Benutzer etwas in dieses Feld schreibt:

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) {
  let password = group.controls.password.value;
  let passwordConfirmation = group.controls.passwordAgain.value;

  return password === passConfirmation ? 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>

ich hoffe, es hilft!

3
Celso Soares

Der einfachste Weg imo:

(Kann auch für E-Mails verwendet werden)

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 Ihrer Komponente:

this.SignUpForm = this.formBuilder.group({

password: [undefined, [Validators.required]],
passwordConfirm: [undefined, 
        [
          Validators.required,
          matchValues('password'),
        ],
      ],
});
2
Zahema

Führen Sie einfach einen benutzerdefinierten Standardvalidator aus und überprüfen Sie zuerst, ob das Formular selbst definiert ist. Andernfalls wird ein Fehler ausgegeben, der besagt, dass das Formular nicht definiert ist, da zunächst versucht wird, den Validator auszuführen, bevor das Formular erstellt wird.

// form builder
private buildForm(): void {
    this.changePasswordForm = this.fb.group({
        currentPass: ['', Validators.required],
        newPass: ['', Validators.required],
        confirmPass: ['', [Validators.required, this.passwordMatcher.bind(this)]],
    });
}

// confirm new password validator
private passwordMatcher(control: FormControl): { [s: string]: boolean } {
    if (
        this.changePasswordForm &&
        (control.value !== this.changePasswordForm.controls.newPass.value)
    ) {
        return { passwordNotMatch: true };
    }
    return null;
}

Es wird nur überprüft, ob das neues Passwort Feld den gleichen Wert hat wie das Passwort bestätigen Feld. Ist ein Validator spezifisch für das Passwort bestätigen Feld anstelle des gesamten Formulars.

Sie müssen nur bestätigen, dass this.changePasswordForm ist definiert, da es sonst beim Erstellen des Formulars einen undefinierten Fehler auslöst.

Es funktioniert einwandfrei, ohne Anweisungen oder Fehlerzustandsvergleiche zu erstellen.

1
David Prieto

* Diese Lösung ist für reaktive Form

Möglicherweise haben Sie gehört, dass das Bestätigungspasswort als Cross-Field-Validierung bezeichnet wird. Während der Feldebenenprüfer, den wir normalerweise schreiben, nur auf ein einzelnes Feld angewendet werden kann. Für die feldübergreifende Validierung müssen Sie wahrscheinlich einen Validierer auf Elternebene schreiben. Für den Fall der Passwortbestätigung möchte ich lieber Folgendes tun:

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

Und hier ist die Vorlage:

<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>
1
goldenbearkin

Ich verwende eckig 6 und habe am besten nach passendem Passwort gesucht und das Passwort bestätigt. Dies kann auch verwendet werden, um zwei beliebige Eingaben in einem Formular abzugleichen. Ich habe Angular-Direktiven verwendet. Ich wollte sie benutzen 

vergleiche-Validatoren --spec false und ich werde in Ihrem Modul hinzugefügt. Unten ist die Direktive

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

}

Jetzt in deiner Komponente

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

Ich hoffe das hilft

1
Niclausel

Einzelmethode für reaktive Formen

TypeScript

// 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'];
}

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>
0
WasiF

Ich würde vorschlagen, die Bibliothek ng-form-rules zu verwenden. Es ist eine großartige Bibliothek zum Erstellen aller Arten von Formularen mit Validierungslogik, die von der Komponente entkoppelt ist (und wieder verwendbar ist). Sie haben großartige Dokumentationen , Beispiele und ein Video, das eine Reihe von Funktionen zeigt . Eine solche Validierung (Überprüfung der Gleichheit zweier Formularsteuerelemente) ist trivial.

Sie können ihre README auf einige Informationen und ein einfaches Beispiel überprüfen.

0
Chris Knight

Meine Antwort ist sehr einfach> Ich habe ein Kennwort erstellt und die Kennwortüberprüfung mit einer in Winkel 6 geleiteten Vorlage bestätigt

Meine HTML-Datei

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

Meine TypeScript-Datei

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

wenn Sie auf die Schaltfläche zum Senden klicken, prüfe ich, ob der Wert von i wahr oder falsch ist

wenn wahr 

if (this.i) {
      return false;
    }

else{
**form submitted code comes here**
}
0
Mukul Kashyap

Es ist nicht erforderlich, verschachtelte Formulargruppen und einen benutzerdefinierten ErrorStateMatcher zur Bestätigung der Kennwortüberprüfung zu verwenden. Diese Schritte wurden hinzugefügt, um die Koordination zwischen den Kennwortfeldern zu erleichtern. Sie können dies jedoch ohne den gesamten Aufwand tun.

Hier ist ein Beispiel:

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

Beachten Sie, dass wir der validatePasswords-Methode zusätzlichen Kontext übergeben (unabhängig davon, ob die Quelle password1 oder password2 ist).

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

Beachten Sie hier, dass wir bei Übereinstimmung der Passwörter mit dem anderen Passwortfeld koordinieren, damit dessen Validierung aktualisiert wird. Dies löscht alle veralteten Fehler aufgrund von Fehlanpassungen von Passwörtern.

Und der Vollständigkeit halber hier die Getter, die this.password1 Und this.password2 Definieren.

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

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

Ich habe einen Fehler in der Antwort von AJT_82 gefunden. Da ich nicht genug Ruf habe, um unter der Antwort von AJT_82 zu kommentieren, muss ich den Fehler und die Lösung in dieser Antwort posten.

Hier ist der Fehler: 

 enter image description here

Lösung: Im folgenden 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);
  }
}

Ändern Sie control.parent.invalid in control.parent.hasError('notSame'), um dieses Problem zu lösen.

Nach den kleinen Änderungen wurde das Problem gelöst.

 enter image description here

0
Henry