javascript - Lösenord Bekräfta Angular Material
Jag arbetar med att autentisera en användare med Angular Material. Jag försöker för närvarande få rätt mat-error att visas när bekräftelselösenordet inte matchar det först inmatade lösenordet.
Här är min html:
<mat-form-field hintLabel="Minimum 8 Characters" class="">
<mat-label>Password</mat-label>
<input
matInput
#input
type="password"
formControlName="password">
<mat-hint align="end">{{input.value?.length || 0}}/8</mat-hint>
</mat-form-field>
<mat-form-field>
<mat-label>Confirm</mat-label>
<input
matInput
required
type="password"
#confirm
formControlName="confirmPassword">
<mat-error *ngIf="form.get('confirmPassword').invalid || confirmPasswordMismatch">Password does not match</mat-error>
</mat-form-field>
Felet visas när användaren har fokuserat på lösenordsbekräftelsen och sedan tappar fokus utan att skriva något. När användaren skriver något försvinner felet även om bekräftelsen inte matchar lösenordet.
Här är min TS-fil:
public get confirmPasswordMismatch() {
return (this.form.get('password').dirty || this.form.get('confirmPassword').dirty) && this.form.hasError('confirmedDoesNotMatch');
}
this.form = new FormGroup({
userName: new FormControl(null, [Validators.required]),
fullName: new FormControl(null, [Validators.required]),
email: new FormControl(null, [Validators.required, Validators.pattern(this.EMAIL_REGEX)]),
password: new FormControl(null),
confirmPassword: new FormControl(null, ),
}, (form: FormGroup) => passwordValidator.validate(form));
Den önskade effekten är att felet visas när användaren har skrivit text i lösenordsfältet när bekräfta lösenord är tomt och att visa ett fel när båda har text men bekräfta inte matchar lösenordet.
Svar #1
Jag löste det så här:
Mall:
<mat-form-field>
<input matInput type="password" placeholder="Password" formControlName="password" (input)="onPasswordInput()">
<mat-error *ngIf="password.hasError('required')">Password is required</mat-error>
<mat-error *ngIf="password.hasError('minlength')">Password must have at least {{minPw}} characters</mat-error>
</mat-form-field>
<mat-form-field>
<input matInput type="password" placeholder="Confirm password" formControlName="password2" (input)="onPasswordInput()">
<mat-error *ngIf="password2.hasError('required')">Please confirm your password</mat-error>
<mat-error *ngIf="password2.invalid && !password2.hasError('required')">Passwords don't match</mat-error>
</mat-form-field>
Komponent:
export class SignUpFormComponent implements OnInit {
minPw = 8;
formGroup: FormGroup;
constructor(private formBuilder: FormBuilder) { }
ngOnInit() {
this.formGroup = this.formBuilder.group({
password: ['', [Validators.required, Validators.minLength(this.minPw)]],
password2: ['', [Validators.required]]
}, {validator: passwordMatchValidator});
}
/* Shorthands for form controls (used from within template) */
get password() { return this.formGroup.get('password'); }
get password2() { return this.formGroup.get('password2'); }
/* Called on each input in either password field */
onPasswordInput() {
if (this.formGroup.hasError('passwordMismatch'))
this.password2.setErrors([{'passwordMismatch': true}]);
else
this.password2.setErrors(null);
}
}
Validator:
export const passwordMatchValidator: ValidatorFn = (formGroup: FormGroup): ValidationErrors | null => {
if (formGroup.get('password').value === formGroup.get('password2').value)
return null;
else
return {passwordMismatch: true};
};
Anteckningar:
- Tack vare att
onPasswordInput()kallas från antingen lösenordsfältet, orsakar redigering av det första lösenordsfältet (och därmed ogiltigförklaring av lösenordsbekräftelsen) också att felmeddelandet om mismatch visas i fältet för lösenordsbekräftelse. - Testet
*ngIf="password2.invalid && !password2.hasError('required')"för fältet för lösenordsbekräftelse säkerställer att aldrig båda felmeddelandena ("mismatch" och "required") visas samtidigt.
Svar #2
Baserat på din kod ser det inte ut som att du har lagt till någon validering för fältet confirmPassword: confirmPassword: new FormControl(null, ) så den enda validering som sker är via required-attributet. Dessutom kommer mat-error bara att visas av formulärfältet om formkontrollen är ogiltig. Det betyder att du inte kan tvinga fram ett felmeddelande enbart genom att använda ngIf. Eftersom du endast har required-validering för det fältet är det logiskt att du bara får ett fel när fältet är tomt. För att lösa detta problem behöver du skapa en validator för mismatch-kontroll och lägga till den på confirmPassword-formkontrollen. Som alternativ kan du manuellt lägga till fel på formkontrollen med setErrors() när fältet ändras genom att lägga till en input-lyssnare - till exempel (detta är bara från minnet - kan behöva justeras):
<mat-form-field>
<mat-label>Confirm</mat-label>
<input matInput required type="password" #confirm formControlName="confirmPassword"
(input)="onInput($event.target.value)">
<mat-error *ngIf="form.get('confirmPassword').invalid>
Password does not match
</mat-error>
</mat-form-field>
onInput(value) {
if (this.form.hasError('confirmedDoesNotMatch')) { // or some other test of the value
this.form.get('confirmPassword').setErrors([{'confirmedDoesNotMatch': true}]);
} else {
this.form.get('confirmPassword').setErrors(null);
}
}
