J'ai un formulaire de confirmation de mot de passe que je souhaite valider.
Je veux afficher mon élément mat-error lorsque le mot de passe n'est pas le même que la valeur dans la confirmation du mot de passe. Pour cela, j'ai une fonction appelée equalPasswords()
. Si les fonctions sont les mêmes, nous recevons vrai, sinon, nous recevons faux.
<mat-form-field>
<input matInput placeholder="Repeat password" [formControl]="password2" type="password">
<mat-error *ngIf="password2.invalid && password2.hasError('required')">Password is required</mat-error>
<mat-error *ngIf="!equalPasswords() && !password2.hasError('required')">Passwords need to match</mat-error>
</mat-form-field>
J'ai vérifié la console et lorsque j'entre deux entrées différentes dans les zones de mot de passe, equalPasswords () renvoie false. Cependant, il ne montre toujours pas l'erreur dans le DOM.
Est-ce que quelqu'un sait comment résoudre ce problème?
Signup.component.ts
@Component({
selector: 'app-sign-up',
templateUrl: 'sign-up.component.html',
styleUrls: ['sign-up.component.css']
})
export class SignUpComponent implements OnInit {
mySignupForm: FormGroup;
countries = countries;
uniqueUsernameMessage;
uniqueEmailMessage;
formSubmitted = false;
@Output() closeSubmenu = new EventEmitter();
@ViewChild('select') select;
constructor(
private authService: AuthenticationService,
private route: Router,
private navigationService: NavigationService){}
get firstName() { return this.mySignupForm.get('firstName'); }
get lastName() { return this.mySignupForm.get('lastName'); }
get username() { return this.mySignupForm.get('username'); }
get email() { return this.mySignupForm.get('email'); }
get password1() { return this.mySignupForm.get('password1'); }
get password2() { return this.mySignupForm.get('password2'); }
get birthDate() { return this.mySignupForm.get('birthDate'); }
get country() { return this.mySignupForm.get('country'); }
get house() { return this.mySignupForm.get('house'); }
ngOnInit() {
this.mySignupForm = new FormGroup({
firstName: new FormControl(null, Validators.required),
lastName: new FormControl(null, Validators.required),
username: new FormControl(null, [Validators.required, Validators.minLength(5), Validators.maxLength(15)]),
birthDate: new FormControl(null, Validators.required),
password1: new FormControl(null, [Validators.required, Validators.minLength(6), Validators.maxLength(15), Validators.pattern('^.*(?=.{4,10})(?=.*\\d)(?=.*[a-zA-Z]).*$')]),
password2: new FormControl(null, Validators.required),
email: new FormControl(null, [Validators.required, Validators.email]),
country: new FormControl(null, Validators.required),
house: new FormControl(null, Validators.required)
})
}
equalPasswords() {
console.log('equaltest', this.password1.value === this.password2.value);
return this.password1.value === this.password2.value;
}
}
MatFormField
affiche uniquement les éléments mat-error
lorsque FormControl
contient une erreur. Il ne s'affiche pas simplement parce que vous le lui dites via ngIfElse
- cela ne fonctionnerait que sous réserve de l'état de contrôle du formulaire. Une façon de résoudre ce problème consiste à créer un validateur personnalisé et à l'utiliser pour vérifier que les mots de passe correspondent. Vous pouvez également définir une erreur sur le champ à partir de votre fonction equalPasswords()
. Cela devrait être quelque chose comme:
equalPasswords(): boolean {
const matched: boolean = this.password1.value === this.password2.value;
console.log('equaltest', matched);
if (matched) {
this.signupForm.controls.password2.setErrors(null);
} else {
this.signupForm.controls.password2.setErrors({
notMatched: true
});
}
return matched;
}
J'ai découvert une situation très subtile où cela peut se produire.
Si vous mettez [formGroup]
directive sur quelque chose comme un <div>
alors il n'obtiendra pas submitted == true
lorsque le formulaire est soumis (il doit être sur un <form>
pour que cela se produise).
Le formulaire soumis est l'un des deux déclencheurs d'affichage de l'erreur - l'autre est que le champ a été touché. Et toucher signifie onBlur
ce qui signifie que le focus doit avoir été perdu .
Vous pouvez donc obtenir cette situation:
[formGroup]
sur un divblur
- édité le champ du mot de passe (par exemple, votre curseur est toujours dans cette case)[formGroup]
sur un <form>
tagErrorStateMatcher
Si vous passez un formGroup
à un composant enfant 'dumb' (qui n'a pas sa propre forme), vous devez utiliser l'injection de dépendances et passer le FormGroupDirective
à la place dans le constructeur.