Je construis un formulaire d’inscription dans Ionic 3, j’ai deux champs mot de passe1 et motdepasse2 et l’exigence est mot de passe2 doit être identique à motdepasse1.
Mon composant:
public registration : FormGroup;
constructor(private formBuilder: FormBuilder) {
this.registration = this.formBuilder.group({
username: ['', Validators.compose([Validators.pattern('^(?=.*[a-zA-Z])(?=.*[0-9])[a-zA-Z0-9]+$'), Validators.required])],
email: ['', Validators.compose([Validators.email, Validators.required])],
password1: ['', Validators.compose([Validators.minLength(5), Validators.pattern('^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])[a-zA-Z0-9]+$'), Validators.required])],
password2: ['', Validators.required],
}, (registration: FormGroup) => {
return PasswordValidator.areEqual(registration);
});
}
validation_messages = {
'username': [
{ type: 'pattern', message: 'Username must contain only combination of letterns and numbers.' },
{ type: 'required', message: 'Username is required.' }
],
'email': [
{ type: 'required', message: 'Email is required.' },
{ type: 'email', message: 'Not a valid email!' }
],
'password1': [
{ type: 'minlength', message: 'Password must be minimum 5 characters.' },
{ type: 'required', message: 'Password is required.' },
{ type: 'pattern', message: 'Password must contain combination of upper and lower case letterns and numbers.' }
],
'password2': [
{ type: 'required', message: 'Password is required.' },
{ type: 'areEqual', message: 'Confirm password is not same.' },
],
}
J'ai créé un validateur de mot de passe dans un fichier séparé (je ne sais pas si c'est le bon chemin):
import { FormControl, FormGroup } from '@angular/forms';
export class PasswordValidator {
static areEqual(formGroup: FormGroup) {
let val;
let valid = true;
for (let key in formGroup.controls) {
if (formGroup.controls.hasOwnProperty(key)) {
let control: FormControl = <FormControl>formGroup.controls[key];
if (val === undefined) {
val = control.value
} else {
if (val !== control.value) {
valid = false;
break;
}
}
}
}
if (valid) {
return null;
}
return {
areEqual: true
}
}
}
Et mon template:
<!-- Registration Form -->
<form *ngSwitchCase="'registrationForm'" [formGroup]="registration" (ngSubmit)="register()" autocomplete="off">
<ion-item>
<ion-label>Username</ion-label>
<ion-input type="text" formControlName="username"></ion-input>
</ion-item>
<!-- Username validation errors -->
<div class="validation-errors">
<ng-container *ngFor="let validation of validation_messages.username" >
<div class="error-message" *ngIf=" registration.get('username').hasError(validation.type)
&& ( registration.get('username').dirty || registration.get('username').touched)">
{{ validation.message }}
</div>
</ng-container>
</div>
<ion-item>
<ion-label>Email</ion-label>
<ion-input type="email" formControlName="email"></ion-input>
</ion-item>
<!-- Email validation errors -->
<div class="validation-errors">
<ng-container *ngFor="let validation of validation_messages.email" >
<div class="error-message" *ngIf=" registration.get('email').hasError(validation.type)
&& ( registration.get('email').dirty || registration.get('email').touched)">
{{ validation.message }}
</div>
</ng-container>
</div>
<ion-item>
<ion-label>Password1</ion-label>
<ion-input type="password" formControlName="password1"></ion-input>
</ion-item>
<!-- Password1 validation errors -->
<div class="validation-errors">
<ng-container *ngFor="let validation of validation_messages.password1" >
<div class="error-message" *ngIf=" registration.get('password1').hasError(validation.type)
&& ( registration.get('password1').dirty || registration.get('password1').touched)">
{{ validation.message }}
</div>
</ng-container>
</div>
<ion-item>
<ion-label>Password2</ion-label>
<ion-input type="password" formControlName="password2"></ion-input>
</ion-item>
<!-- Password2 validation errors -->
<div class="validation-errors">
<ng-container *ngFor="let validation of validation_messages.password2" >
<div class="error-message" *ngIf=" registration.get('password2').hasError(validation.type)
&& ( registration.get('password2').dirty || registration.get('password2').touched)">
{{ validation.message }}
</div>
</ng-container>
</div>
<button ion-button full type="submit" [disabled]="!registration.valid">Submit</button>
</form>
Toutes les autres validations fonctionnent correctement, c'est-à-dire que les messages corrects sont imprimés. La validation de Password2 ne fonctionne que pour un mot de passe vide et ne permet pas de vérifier s'il est identique à password1.
Qu'est-ce que je fais mal?
Je vérifie le mot de passe et confirme le mot de passe de cette façon.
Fichier html
<ion-item>
<ion-label floating>Password</ion-label>
<ion-input type="password" clearinput [(ngModel)]="user.password" required formControlName="password">
</ion-input>
</ion-item>
<ion-item no-lines
*ngIf="ChangePassword.get('password').hasError('minlength') && ChangePassword.get('password').touched"
class="invalid">
<p class="error_message">* Minimum password length is 6!</p>
</ion-item>
<ion-item no-lines
*ngIf="(ChangePassword.get('password').hasError('required') ) && ChangePassword.get('password').touched">
<div class="error"
*ngIf="ChangePassword.get('password').hasError('required') && ChangePassword.get('password').touched">
<p class="error_message">* Password is required</p>
</div>
</ion-item>
<ion-item>
<ion-label floating>Conform Password</ion-label>
<ion-input type="password" clearinput [(ngModel)]="user.password_confirmation" required
formControlName="password_confirmation">
</ion-input>
</ion-item>
<ion-item no-lines
*ngIf="ChangePassword.get('password_confirmation').hasError('minlength') && ChangePassword.get('password_confirmation').touched"
class="invalid">
<p class="error_message">* Minimum password length is 6!</p>
</ion-item>
<ion-item no-lines
*ngIf="(ChangePassword.get('password_confirmation').hasError('equalTo') || ChangePassword.get('password_confirmation').hasError('required') ) && ChangePassword.get('password_confirmation').touched">
<div class="error"
*ngIf="ChangePassword.get('password_confirmation').hasError('required') && ChangePassword.get('password_confirmation').touched">
<p class="error_message">* Confirm password is required</p>
</div>
<div class="error"
*ngIf="ChangePassword.get('password_confirmation').hasError('equalTo') && ChangePassword.get('password_confirmation').touched">
<p class="error_message">* Password Mismatch</p>
</div>
</ion-item>
<button ion-button block class="auth-action-button login-button" type="submit"
[disabled]="!ChangePassword.valid">
Submit
</button>
Fichier ts
this.ChangePassword = new FormGroup({
// token: new FormControl('', [Validators.required]),
email: new FormControl('', [Validators.required]),
password: new FormControl('', [Validators.required, Validators.minLength(6), Validators.maxLength(15)]),
password_confirmation: new FormControl('', [Validators.required, Validators.minLength(6), Validators.maxLength(15), this.equalto('password')])
});
equalto(field_name): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } => {
let input = control.value;
let isValid = control.root.value[field_name] == input;
if (!isValid)
return {'equalTo': {isValid}};
else
return null;
};
}
ça marche bien pour moi
this.profileForm = this.fb.group({
name: ['',[Validators.required,Validators.minLength(3),Validators.maxLength(25)]],
password: ['',Validators.compose([Validators.minLength(5),Validators.required,Validators.pattern('^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])[a-zA-Z0-9]+$')])],
confirmPass: ['',Validators.required],
/*title_ar: ['',[Validators.required,Validators.minLength(3),Validators.maxLength(30)]],
desc_en: ['',[Validators.required]],*/
},{validator: this.checkIfMatchingPasswords('password', 'confirmPass')})
checkIfMatchingPasswords(passwordKey: string, passwordConfirmationKey: string) {
return (group: FormGroup) => {
let passwordInput = group.controls[passwordKey],
passwordConfirmationInput = group.controls[passwordConfirmationKey];
if (passwordInput.value !== passwordConfirmationInput.value) {
return passwordConfirmationInput.setErrors({notEquivalent: true})
}
else {
return passwordConfirmationInput.setErrors(null);
}
}