contraseña y confirmar validación de campo de contraseña angular2 formas reactivas
angular2-forms (6)
Necesito verificar si la contraseña y confirmar los campos de contraseña tienen el mismo valor usando la forma reactiva angular2. Vi muchas respuestas sobre lo mismo aquí, el formulario Angular 2 validando para repetir la contraseña , comparando campos en el validador con angular2 , pero ninguno parecía funcionar para mí. ¿Puede alguien ayudarme? "Esto" no está definido en mi función de validación: (. Compartiendo mi código,
this.addEditUserForm = this.builder.group({
firstName: ['''', Validators.required],
lastName: ['''', Validators.required],
title: ['''', Validators.required],
email: ['''', Validators.required],
password: ['''', Validators.required],
confirmPass: ['''', [Validators.required, this.validatePasswordConfirmation]]
});
validatePasswordConfirmation(group: FormGroup): any{
let valid = true;
// if (this.addEditUserForm.controls.password != this.addEditUserForm.controls.confirmPass) {
// valid = false;
// this.addEditUserForm.controls.confirmPass.setErrors({validatePasswordConfirmation: true});
// }
return valid;
}
Esto es lo que finalmente funcionó para mí:
this.addEditUserForm = this.builder.group({
firstName: ['''', Validators.required],
lastName: ['''', Validators.required],
title: ['''', Validators.required],
email: ['''', Validators.required],
password: ['''', Validators.required],
confirmPass: ['''', 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);
}
}
}
Hice un enfoque diferente que funcionará para cualquier control. Primero defino los controles básicos del formulario:
this.myForm = this.formBuilder.group({
name: ['''', Validators.required],
password: ['''', Validators.required],
});
Luego creo un nuevo control para confirmar el valor con mi validador personalizado:
const confirmPasswordControl = new FormControl('''', {
validator: sameValueAs(this.myForm, ''password'')
});
this.myForm.addControl(''confirmPassword'', confirmPasswordControl);
El código del validador
sameValueAs
es el siguiente, puede definirlo en un archivo separado para usarlo en cualquier lugar
export function sameValueAs(group: FormGroup, controlName: string): ValidatorFn {
return (control: FormControl) => {
const myValue = control.value;
const compareValue = group.controls[controlName].value;
return (myValue === compareValue) ? null : {valueDifferentFrom:controlName};
};
}
Lo mejor sería tener un grupo anidado dentro del grupo de formularios, donde tenemos un validador personalizado que verifica el grupo de formularios con
password
y
confirmPass
, por lo que cuando se cambia cualquiera de los campos, se
confirmPass
el validador, ya que solo se
confirmPass
cuando
confirmPass
campo modificado
Entonces, haga algo como esto dentro del grupo de forma externo:
// ...
passwords: this.fb.group({
password: ['''', [...]],
confirmPass: ['''', [...]]
}, {validator: this.checkPasswords}) // add a validator for the whole group
// ...
y luego el validador podría verse así:
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 }
}
Mostrar el error de validación podría hacerse así:
*ngIf="addEditUserForm.hasError(''notSame'', ''passwords'')"
Por supuesto, no necesita tener un grupo anidado, pero es mejor no activar el validador personalizado cada vez que se producen cambios en el formulario. De esta forma, solo se activa cuando se producen cambios en este grupo de formas internas.
Para aquellos que desean agregar un validador personalizado sin verse obligados a pasar de la validación del grupo de formularios, es posible agregar el validador después de definir el formulario.
Una ventaja de este enfoque es que el error se agrega al control de formulario y no al grupo de formulario. De esta manera, es más fácil mostrar el error asociado al campo, ya que podemos verificar el error directamente en el control de campo / formulario.
Así es como lo implementé:
Validador personalizado
import { AbstractControl, ValidatorFn } from ''@angular/forms'';
export class MismatchValidator {
static mismatch(otherInputControl: AbstractControl): ValidatorFn {
return (inputControl: AbstractControl): { [key: string]: boolean } | null => {
if (inputControl.value !== undefined
&& inputControl.value.trim() != ""
&& inputControl.value !== otherInputControl.value) {
return { ''mismatch'': true };
}
return null;
};
}
}
Aplicar el validador personalizado al control de formulario
ngOnInit() {
this.initForm();
// The validators are set after defining the form in order to be able to access the password control and pass it to the custom validator as a parameter
this.setValidators();
}
private initForm() {
this.myForm = this.formBuilder.group({
password: new FormControl(''''),
passwordConfirmation: new FormControl('''')
});
}
private setValidators() {
const formValidators = {
"password": Validators.compose([
Validators.required,
//....
]),
"passwordConfirmation": Validators.compose([
Validators.required,
MismatchValidator.mismatch(this.myForm.get("password"))
])
}
this.passwordRecoveryForm.get("password").setValidators(
formValidators["password"]
);
this.passwordRecoveryForm.get("passwordConfirmation").setValidators(
formValidators["passwordConfirmation"]
);
}
Los validadores se configuran después de definir el formulario para poder acceder al control de contraseña y pasarlo al validador personalizado como parámetro.
Si desea hacerlo de esa manera, debe vincular la función al contexto actual "este".
Pase
this.validatePasswordConfirmation.bind(this)
pero tenga en cuenta que a esta función se le pasará el FormControl para la confirmación, y no el FormGroup como usted indicó en la firma de la función.
Si no desea pasar por un validador personalizado, puede crear un campo de entrada que sea independiente y, por lo tanto, no se computará en su formGroup sino a través de ngModel
<input type="password" matInput [(ngModel)]="passwordConfirm" [ngModelOptions]="{standalone: true}">
Luego, en su ts, puede validar y arrojar un error o invalidar el formulario si lo desea. Lo encontré un poco más rápido y práctico:
// Comprobar coincidencia de contraseñas
if (this.staffAccountForm.value.password !== this.passwordConfirm) {
this.snackbar.snackBarSimple(''Passwords do not match.'');
return false;
}