Necesito verificar si los campos de contraseña y confirmación de contraseña tienen el mismo valor usando el formulario reactivo angular2. Vi muchas respuestas sobre lo mismo aquí, la validación del formulario Angular 2 para repetir la contraseña , la comparación de campos en el validador con angular2 , pero ninguna pareció 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); } } }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, el validador se activa, como anteriormente solo se activa cuando confirmPass se modifica el campo.
Entonces, en su lugar, haga algo como esto dentro del grupo de formulario externo:
// ... passwords: this.fb.group({ password: ['', [...]], confirmPass: ['', [...]] }, {validators: this.checkPasswords}) // add a validator for the whole group // ...y luego el validador podría verse así:
checkPasswords: ValidatorFn = (group: AbstractControl): ValidationErrors | null => { let pass = group.get('password').value; let confirmPass = group.get('confirmPassword').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 que el validador personalizado no se active cada vez que se produzca algún cambio en el formulario. De esta forma, solo se activa cuando se producen cambios en este grupo de formulario interno.
Para aquellos que quieran 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 formularios. De esta forma es más fácil mostrar el error asociado al campo ya que podemos comprobar el error directamente en el propio 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ñas y pasarlo al validador personalizado como parámetro.