page - Validación de forma angular 2 para repetir contraseña
router events subscribe angular 4 (19)
Consulte esta question respecto a los campos de comparación en el validador con angular2 . Desafortunadamente, Angular 2 cambió un poco, por lo que la solución ya no funciona. Aquí está mi código:
import {IonicApp,Page,NavController,NavParams} from ''ionic/ionic''
import {Component} from ''angular2/core''
import {FORM_PROVIDERS, FormBuilder, Validators} from ''angular2/common''
import {ControlMessages} from ''../../components/control-messages''
import {ValidationService} from ''../../services/validation-service''
@Page({
templateUrl: ''build/pages/account/register.html'',
directives: [ControlMessages]
})
export class RegisterPage {
constructor(nav:NavController,private builder: FormBuilder) {
this.nav = nav
this.registerForm = this.builder.group({
''name'' : ['''', Validators.required],
''email'' : ['''',Validators.compose([Validators.required, ValidationService.emailValidator])],
''password'' : ['''',Validators.required],
''repeat'' : ['''',this.customValidator]
}
)
}
register() {
alert(this.registerForm.value.password)
}
private customValidator(control) {
//console.log(this.registerForm.value.password)
//return {isEqual: control.value === this.registerForm.value.password}
return true
}
}
Mi html:
<ion-content class="account">
<ion-list padding>
<form [ngFormModel]=''registerForm'' (submit)=''register()''>
<div class="centered">
<img class="logo" src="img/logo.png" alt="">
</div>
<div class="spacer" style="height: 20px;"></div>
<ion-input>
<ion-label floating>Name</ion-label>
<input type="text" ngControl=''name'' id=''name''>
<control-messages control="name"></control-messages>
</ion-input>
<ion-input>
<ion-label floating>Email</ion-label>
<input type="email" ngControl=''email'' id=''email''>
<control-messages control="email"></control-messages>
</ion-input>
<ion-input>
<ion-label floating>Password</ion-label>
<input type="password" ngControl=''password'' id=''password'' value="">
<control-messages control="password"></control-messages>
</ion-input>
<ion-input>
<ion-label floating>Confirm Password</ion-label>
<input type="password" ngControl=''repeat'' id=''repeat''>
<control-messages control="repeat"></control-messages>
</ion-input>
<button class="calm" full type=''submit'' [disabled]=''!registerForm.valid''>Register</button>
<ion-item style="background-color:transparent;border:none;">
<button class="text-button" clear item-right (click)="gotoLogin()">Have an account already, Login</button>
</ion-item>
</form>
</ion-list>
</ion-content>
Pero desafortunadamente, no puedo acceder al valor de ''contraseña'' en mi función de validación. Si descomento console.log (this.registerForm.value.password) , aparece el siguiente mensaje de error:
EXCEPCIÓN: TypeError: no se puede leer la propiedad ''valor'' de undefined
¿Alguna idea? Gracias.
Además, a partir de angular 2 rc4 con formas 0.2.0, el marcado y el atributo que llama el nombre del grupo utilizado para abarcar las entradas agrupadas es necesario para evitar errores
<div formGroupName="passwords">group input fields here... </div>
Al usar esta biblioteca ng2-validation-manager puedes hacer esto fácilmente:
this.form = new ValidationManager({
''password'' : ''required|rangeLength:8,50'',
''repassword'' : ''required|equalTo:password''
});
Aquí está mi manera de usar validadores angulares
COMPONENTE:
import { UserModel } from ''../../settings/users/user.model'';
import { AbstractControl, FormBuilder, FormGroup, Validators } from ''@angular/forms'';
import { FormRequestModel } from ''../Shared/form.model'';
import { Component, OnInit } from ''@angular/core'';
@Component({
selector: ''app-add-user'',
templateUrl: ''./add-user.component.html'',
styleUrls: [''./add-user.component.scss'']
})
export class AddUserComponent implements OnInit {
passwordsForm: FormGroup;
user: UserModel;
constructor(private fb: FormBuilder) { }
ngOnInit() {
this.passwordsForm = this.fb.group({
inputPassword: ['''', Validators.compose([Validators.required, Validators.minLength(6), Validators.maxLength(50)])],
inputPasswordAgain: ['''']
});
}
}
HTML:
<form class="form-horizontal" [formGroup]="passwordsForm" novalidate>
<div class="form-group">
<br/>
<label for="inputPassword" class="col-sm-2 control-label">Password</label>
<div class="col-sm-10">
<input type="password" formControlName="inputPassword" class="form-control" id="inputPassword" placeholder="Password">
</div>
</div>
<div class="alert alert-danger" *ngIf="!passwordsForm.controls[''inputPassword''].valid && passwordsForm.controls[''inputPassword''].touched">Password must contain at least 6 characters!!</div>
<div class="form-group">
<br/>
<label for="inputPasswordAgain" class="col-sm-2 control-label">Password again</label>
<div class="col-sm-10">
<input type="password" formControlName="inputPasswordAgain" class="form-control" id="inputPasswordAgain" placeholder="Password again">
</div>
</div>
<!-- Show div warning element if both inputs does not match the validation rules below -->
<div class="alert alert-danger" *ngIf="passwordsForm.controls[''inputPasswordAgain''].touched
&& passwordsForm.controls[''inputPasswordAgain''].value !== passwordsForm.controls[''inputPassword''].value">
Both passwords must be equal!</div>
Bueno, busqué una respuesta sobre este tema y todos eran demasiado grandes para mi pereza, así que lo hice así. Creo que hace bien el trabajo.
Utilicé el ngModel para enlazar la contraseña y repetir la entrada de contraseña y luego he mostrado u ocultado el div con el mensaje de comparación de contraseña con el atributo [oculto] en angular 2.
<label for="usr">Password</label>
<input placeholder="12345" id="password" type="text" class="form-control"
[(ngModel)]="password">
<label for="usr">Repeat pasword</label>
<input placeholder="12345" type="text" class="form-control"
[(ngModel)]="repeatPassword">
<div [hidden]="password == repeatPassword">Passwords do not match!</div>
Encontré una solución mucho más simple. No estoy seguro si esta es la forma correcta de hacerlo, pero funciona para mí
<!-- PASSWORD -->
<ion-item [ngClass]="{''has-error'': !signupForm.controls.password.valid && signupForm.controls.password.dirty}">
<ion-input formControlName="password" type="password" placeholder="{{ ''SIGNUP.PASSWORD'' | translate }}" [(ngModel)]="registerCredentials.password"></ion-input>
</ion-item>
<!-- VERIFY PASSWORD -->
<ion-item [ngClass]="{''has-error'': !signupForm.controls.verify.valid && signupForm.controls.verify.dirty}">
<ion-input formControlName="verify" [(ngModel)]="registerCredentials.verify" type="password" pattern="{{registerCredentials.password}}" placeholder="{{ ''SIGNUP.VERIFY'' | translate }}"> </ion-input>
</ion-item>
Ver
pattern="{{registerCredentials.password}}"
Encontré una solución que me hizo más feliz en cuanto a la consistencia del código y el manejo de errores:
Primero: crear una clase de validación personalizada con un método estático que realice la validación
Este método debe tener un parámetro AbstractControl que inyecte angularmente
Tenga en cuenta que pasará esto en el control ConfirmPassword, por lo que debe llamar a los padres para acceder al FormGroup. Desde allí, llama a formGroup.get (''myControl'') y obtiene los controles para la contraseña y confirma como los nombró cuando creó el grupo de formularios.
import {AbstractControl} from ''@angular/forms'';
export class PasswordValidation {
static MatchPassword(AC: AbstractControl) {
const formGroup = AC.parent;
if (formGroup) {
const passwordControl = formGroup.get(''Password''); // to get value in input tag
const confirmPasswordControl = formGroup.get(''Confirm''); // to get value in input tag
if (passwordControl && confirmPasswordControl) {
const password = passwordControl.value;
const confirmPassword = confirmPasswordControl.value;
if (password !== confirmPassword) {
return { matchPassword: true };
} else {
return null;
}
}
}
return null;
}
}
2do: Use su Validador de clientes al igual que usa angulares
this.registerForm = this.fb.group({ // <-- the parent FormGroup
Email: ['''', Validators.required ],
Username: ['''', Validators.required ],
FirstName: ['''', Validators.required ],
Password: ['''',
[
Validators.required,
Validators.minLength(6)
]
],
Confirm: ['''',
[
Validators.required,
PasswordValidation.MatchPassword
]
]
});
Angular luego agregará ''matchPassword'': verdadero a su Confirmar controla los errores exactamente como agregaría ''requerido'' verdadero cuando falta un valor
Esta es la forma más fácil que sigo. He eliminado el código que no es relevante.
Creo que esto te ayudará.
auth.component.ts, auth.component.html, auth.component.css
import { Component, OnInit, EventEmitter, Input, Output ,Directive, forwardRef, Attribute,OnChanges, SimpleChanges} from ''@angular/core'';
import { NG_VALIDATORS,Validator,Validators,AbstractControl,ValidatorFn } from ''@angular/forms'';
import { ActivatedRoute, Router } from ''@angular/router'';
import { RegisterUser } from ''../shared/models'';
@Component({
moduleId: module.id,
selector: ''auth-page'',
styleUrls: [''./auth.component.css''],
templateUrl: ''./auth.component.html''
})
export class AuthComponent implements OnInit {
userRegisterModel: RegisterUser = new RegisterUser();
constructor(private route: ActivatedRoute, private router: Router) { }
ngOnInit() {
this.userRegisterModel.LoginSource = ''M'';//Manual,Facebook,Google
}
userRegister() {
console.log(this.userRegisterModel);
}
}
.validation
{
margin:0;
padding-top: 1px;
padding-bottom: 0px;
}
.validation .message
{
font-size: 10px;
color: #de1a16;
}
<form (ngSubmit)="userRegister()" #authRegisterForm="ngForm" novalidate>
<div class="col-md-6 form-group" style="padding-right: 5px;padding-left: 0px;margin-bottom: 0;">
<label>First Name:</label>
<input type="text" class="form-control" required pattern="[a-zA-Z][a-zA-Z ]+" [(ngModel)]="userRegisterModel.firstName" name="firstName"
#firstName="ngModel" placeholder="Your first name">
<div style="display: flex;">
<div [hidden]="firstName.valid || firstName.pristine" class="validation">
<div [hidden]="!firstName.hasError(''required'')" class="message">Name is required</div>
<div [hidden]="!firstName.hasError(''pattern'')" class="message">Only alphabets allowed</div>
</div>
</div>
</div>
<div class="col-md-6 form-group" style="padding-right: 5px;padding-left: 0px;margin-bottom: 0;">
<label>Last Name:</label>
<input type="text" class="form-control" required pattern="[a-zA-Z][a-zA-Z ]+" [(ngModel)]="userRegisterModel.lastName" name="lastName"
#lastName="ngModel" placeholder="Your last name">
<div style="display: flex;">
<div [hidden]="lastName.valid || lastName.pristine" class="validation">
<div [hidden]="!lastName.hasError(''required'')" class="message">Name is required</div>
<div [hidden]="!lastName.hasError(''pattern'')" class="message">Only alphabets allowed</div>
</div>
</div>
</div>
<div class="col-md-12 form-group" style="padding-right: 5px;padding-left: 0px;margin-bottom: 0;">
<label>Email:</label>
<input type="text" class="form-control" required [(ngModel)]="userRegisterModel.email" name="email" pattern="^/w+([/.-]?/w+)*@/w+([/.-]?/w+)*(/./w{2,3})+$"
#email="ngModel" placeholder="Your email">
<div style="display: flex;">
<div [hidden]="email.valid || email.pristine" class="validation">
<div [hidden]="!email.hasError(''required'')" class="message">Email is required</div>
<div [hidden]="!email.hasError(''pattern'')" class="message">Email format should be
<small>
<b>[email protected]</b>
</small>
</div>
</div>
</div>
</div>
<div class="col-md-12 form-group" style="padding-right: 5px;padding-left: 0px;margin-bottom: 0;">
<label>Password:</label>
<input type="password" class="form-control" required [(ngModel)]="userRegisterModel.password" name="password" #password="ngModel"
minlength="6" placeholder="Your strong password" >
<div style="display: flex;">
<div [hidden]="password.valid || password.pristine" class="validation">
<div [hidden]="!password.hasError(''minlength'')" class="message">Password should be 6digit</div>
<div [hidden]="!password.hasError(''required'')" class="message">Password is required</div>
</div>
</div>
</div>
<div class="col-md-12 form-group" style="padding-right: 5px;padding-left: 0px;margin-bottom: 0;">
<label>Confirm Password:</label>
<input type="password" class="form-control" required validateEqual="password" [(ngModel)]="userRegisterModel.confirmPassword"
name="confirmPassword" #confirmPassword="ngModel" placeholder="Confirm your password">
<div style="display: flex;">
<div [hidden]="confirmPassword.valid || confirmPassword.pristine" class="validation">
<div class="message">Passwords did not match</div>
</div>
</div>
</div>
<div class="col-md-12 form-group text-right" style="padding-right: 5px;padding-left: 0px;margin-bottom: 0;">
<button type="submit" class="btn btn-primary" [disabled]="!authRegisterForm.form.valid">
Submit form
<i class="icon-arrow-right14 position-right"></i>
</button>
</div>
</form>
registerUser.mocel.ts
export class RegisterUser {
FirstName : number;
LastName : string;
Email: string;
Password : string;
}
password.match.directive.ts
import { Directive, forwardRef, Attribute } from ''@angular/core'';
import { NG_VALIDATORS,Validator,Validators,AbstractControl,ValidatorFn } from ''@angular/forms'';
@Directive({
selector: ''[validateEqual][formControlName],[validateEqual][formControl],[validateEqual][ngModel]'',
providers: [
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => EqualValidator), multi: true }
]
})
export class EqualValidator implements Validator {
constructor( @Attribute(''validateEqual'') public validateEqual: string) {}
validate(c: AbstractControl): { [key: string]: any } {
// self value (e.g. retype password)
let v = c.value;
// control value (e.g. password)
let e = c.root.get(this.validateEqual);
// value not equal
if (e && v !== e.value) return {
validateEqual: false
}
return null;
}
}
app.module.ts
import { ModuleWithProviders, NgModule } from ''@angular/core'';
import { BrowserModule } from ''@angular/platform-browser'';
import { RouterModule } from ''@angular/router'';
//import { AppRoutingModule } from ''./app-routing.module'';
//import { AppComponent } from ''./app.component'';
//shared components
import { EqualValidator} from ''./shared/password.match.directive'';
@NgModule({
declarations: [
// AppComponent,
//FooterComponent,
// HeaderComponent,
// LoginComponent,
// LayoutComponent,
// AuthComponent,
// UserExistComponent,
// HomeComponent,
EqualValidator
],
imports: [
// BrowserModule,
// AppRoutingModule,
// SharedModule
],
providers: [
// ApiService,
// AuthGuard,
//JwtService,
// UserService,
// HomeAuthResolver,
// NoAuthGuard,
// SharedService
],
bootstrap: [AppComponent]
})
export class AppModule { }
Guarde la contraseña en la variable de instancia.
password = new FormControl('''', [Validators.required]);
Luego úselo en su grupo de formularios.
this.registrationForm = this.fb.group({
''email'': ['''', [
Validators.required,
NGValidators.isEmail,
]
],
''password'': this.password,
''password2'': ['''', [Validators.required, this.passwordMatch]]
});
Entonces la función se ve así.
private passwordMatch() {
let that = this;
return (c: FormControl) =>
{
return (c.value == that.password.value) ? null : {''passwordMatch'': {valid: false}};
}
}
Sé que no es la mejor solución, ¡pero está funcionando!
He implementado un validador de coincidencia de contraseñas personalizadas para Angular 4.
Además de verificar si dos valores coinciden, también se suscribe a los cambios de otro control y vuelve a validar cuando se actualiza cualquiera de los dos controles. Siéntase libre de usarlo como referencia para su propia implementación o simplemente copiarlo directamente.
Aquí está el enlace a la solución: https://gist.github.com/slavafomin/17ded0e723a7d3216fb3d8bf845c2f30 .
Y aquí estoy proporcionando una copia del código:
match-other-validator.ts
import {FormControl} from ''@angular/forms'';
export function matchOtherValidator (otherControlName: string) {
let thisControl: FormControl;
let otherControl: FormControl;
return function matchOtherValidate (control: FormControl) {
if (!control.parent) {
return null;
}
// Initializing the validator.
if (!thisControl) {
thisControl = control;
otherControl = control.parent.get(otherControlName) as FormControl;
if (!otherControl) {
throw new Error(''matchOtherValidator(): other control is not found in parent group'');
}
otherControl.valueChanges.subscribe(() => {
thisControl.updateValueAndValidity();
});
}
if (!otherControl) {
return null;
}
if (otherControl.value !== thisControl.value) {
return {
matchOther: true
};
}
return null;
}
}
Uso
Así es como puede usarlo con formas reactivas:
private constructForm () {
this.form = this.formBuilder.group({
email: ['''', [
Validators.required,
Validators.email
]],
password: ['''', Validators.required],
repeatPassword: ['''', [
Validators.required,
matchOtherValidator(''password'')
]]
});
}
Más validadores actualizados se pueden encontrar aquí: moebius-mlm/ng-validators .
Mi solución para Angular 4.3.4, que no requiere
FormGroup
adicional:
-
registre un validador personalizado para la verificación
repeatedPassword
contraseñas si las contraseñas son las mismas -
suscriba el controlador en
password.valueChanges
durante la creación del formulario y llame.updateValueAndValidity() method
enrepeatedPassword
Aquí hay un código:
form: FormGroup
passwordFieldName = ''password''
repeatedPasswordFieldName = ''repeatedPassword''
createForm() {
this.form = this.formBuilder.group({
login: ['''', [Validators.required, Validators.minLength(3), Validators.maxLength(255), Validators.email]],
[passwordFieldName]: ['''', [Validators.required, Validators.minLength(6), Validators.maxLength(255)]],
[repeatedPasswordFieldName]: ['''', [Validators.required, this.samePassword]]
});
this.form
.get(passwordFieldName)
.valueChanges.subscribe(() => {
this.form
.get(repeatedPasswordFieldName).updateValueAndValidity();
})
}
samePassword(control: FormControl) {
if (!control || !control.parent) {
return null;
}
if (control.value !== control.parent.get(passwordFieldName).value) {
return {''passwordMismatch'': true}
}
return null;
}
No creo que necesitemos un validador personalizado para contraseñas coincidentes, esto se puede lograr fácilmente usando
formname.controls[''controlName''].value
.
<input type="password" class="form-control" formControlName="password">
<div class="alert alert-danger" *ngIf="!userForm.controls[''password''].valid && userForm.controls[''password''].touched">
Enter valid password between 7 and 14 characters.
</div>
<input type="password" class="form-control" formControlName="confPassword">
<div *ngIf="userForm.controls[''confPassword''].touched">
<div class="alert alert-danger" *ngIf="userForm.controls[''confPassword''].value != userForm.controls[''password''].value">
Password do not match
</div>
</div>
En
fileName.component.ts
el control de formulario declarado como:
''password'':[null, Validators.compose([Validators.required, Validators.minLength(7), Validators.maxLength(14))],
''confPassword'':[null, Validators.required]
Recién comenzando con Angular y encontré esta solución, no sé si es una buena práctica:
// Custom password confirmation validation
static matchFieldValidator(fieldToMatch:string) : ValidatorFn {
return (control : AbstractControl) : { [key: string]: any;} => {
let confirmField = control.root.get(fieldToMatch);
return (confirmField && control.value !== confirmField.value) ? {match:false} : null;
}
}
De esta manera, puede hacer algo como esto al configurar las reglas de validación
this.registrationForm = fb.group({
...
password1 : ['''', [Validators.minLength(3)]],
// remember to replace RegisterComponent with YOUR class name
password2 : ['''', [RegisterComponent.matchFieldValidator(''password1'')]],
});
Respondiendo a la persona de Zhou Hao que planteó la cuestión del debate, creo que esto es lo que estaba buscando porque me sucedió lo mismo que a usted, dijo que la variable no estaba definida y la resolvió así:
static comparePassword(control) {
try {
control.parent.value.password;
if (control.parent.value.password == control.value) {
return null;
} else {
return { ''invalidValue'': true };
}
} catch (e) {
e.message;
}
}
Si desea crear una directiva y usarla, vea esto
Aquí está el código completo de la directiva
import { Directive, Attribute } from ''@angular/core'';
import { Validator, NG_VALIDATORS } from ''@angular/forms'';
@Directive({
selector: ''[advs-compare]'',
providers: [{provide: NG_VALIDATORS, useExisting: CompareDirective, multi: true}]
})
export class CompareDirective implements Validator {
constructor(@Attribute(''advs-compare'') public comparer: string){}
validate(c: Control): {[key: string]: any} {
let e = c.root.get(this.comparer);
if(e && c.value !== e.value){
return {"compare": true};
}
return null;
}
}
Para obtener más información sobre cómo usarlo, consulte http://www.advancesharp.com/blog/1226/angular-5-email-compare-password-validation-different-ways
Si está utilizando RC.5 y no puede encontrar ControlGroup, puede intentar usar FormGroup. Puede encontrar más de mi respuesta:
Angular 2 RC.5 validación de formulario para repetir contraseña
Solo quiero publicar mi solución:
this.authorizationSettings = formBuilder.group({
currentPassword: [null, Validators.compose([Validators.required, Validators.minLength(8)])],
newPassword: [null, Validators.compose([Validators.required, Validators.minLength(8)])],
repeatNewPassword: [null]
});
this.authorizationSettings.controls.newPassword.valueChanges.subscribe(data => {
if (data) {
data = data.replace(/[|//{}()[/]^$+*?.]/g, ''//$&'');
}
this.authorizationSettings.controls.repeatNewPassword
.clearValidators();
this.authorizationSettings.controls.repeatNewPassword
.setValidators(Validators.compose([Validators.required, Validators.pattern(data)]));
});
Primero debemos crear un grupo de formularios, luego suscribirnos al primer campo de contraseña nuevo y luego agregar validación para repetir el campo.
Veo varios problemas en tu código.
Intenta utilizar
this
palabra clave en la función de validación y esto no corresponde a la instancia del componente.
Es porque hace referencia a la función cuando la configura como una función de validación.
Además, el valor asociado con un control se puede alcanzar en la propiedad de
value
.
Dicho esto, creo que la forma correcta de validar sus dos campos juntos es crear un grupo y asociar un validador en él:
import { FormBuilder, Validators } from ''@angular/forms'';
...
constructor(private fb: FormBuilder) { // <--- inject FormBuilder
this.createForm();
}
createForm() {
this.registerForm = this.fb.group({
''name'' : ['''', Validators.required],
''email'': ['''', [Validators.required, Validators.email] ],
''passwords'': this.fb.group({
password: ['''', Validators.required],
repeat: ['''', Validators.required]
}, {validator: this.matchValidator})
});
}
De esta manera, tendrá acceso a todos los controles del grupo y no solo a uno, y ya no necesitará usar
this
palabra clave ... Se puede acceder a los
controls
de formulario del grupo utilizando la propiedad de
controls
de FormGroup.
FormGroup se proporciona cuando se activa la validación.
Por ejemplo:
matchValidator(group: FormGroup) {
var valid = false;
for (name in group.controls) {
var val = group.controls[name].value
(...)
}
if (valid) {
return null;
}
return {
mismatch: true
};
}
Vea esta respuesta para más detalles:
Editar
Para mostrar el error, simplemente puede usar lo siguiente:
<span *ngIf="!registerForm.passwords.valid" class="help-block text-danger">
<div *ngIf="registerForm.passwords?.errors?.mismatch">
The two passwords aren''t the same
</div>
</span>
¡Solución angular 4.3.3!
Puede hacerlo usando:
[formGroup]
,
formGroupName
,
formControlName
en html y
new FormGroup
,
new FormControl
y el método
areEqual
personalizado en TS
reg.component.html
<div [formGroup]="userFormPassword">
<div>
<input formControlName="current_password" type="password" placeholder="Current Password">
</div>
<div formGroupName="passwords">
<input formControlName="new_password" type="password" placeholder="New Password">
</div>
<div formGroupName="passwords">
<input formControlName="repeat_new_password" type="password" class="form-control" placeholder="Repeat New Password">
<div class="input-error" *ngIf="
userFormPassword.controls[''passwords''].errors &&
userFormPassword.controls[''passwords''].errors.areEqual &&
userFormPassword.controls[''passwords''].controls.repeat_new_password.touched &&
userFormPassword.controls[''passwords''].controls.new_password.touched
">PASSWORDS do not match
</div>
</div>
</div>
reg.component.ts
export class HomeHeaderSettingsModalComponent implements OnInit {
userFormPassword: FormGroup;
// ...
static areEqual(c: AbstractControl): ValidationErrors | null {
const keys: string[] = Object.keys(c.value);
for (const i in keys) {
if (i !== ''0'' && c.value[ keys[ +i - 1 ] ] !== c.value[ keys[ i ] ]) {
return { areEqual: true };
}
}
}
ngOnInit() {
this.userFormPassword = new FormGroup({
''current_password'': new FormControl(this.user.current_password, [
Validators.required,
]),
''passwords'': new FormGroup({
''new_password'': new FormControl(this.user.new_password, [
Validators.required
]),
''repeat_new_password'': new FormControl(this.user.repeat_new_password, [
Validators.required
])
}, HomeHeaderSettingsModalComponent.areEqual)
});
}
}
Resumen
- Activa la validación cada vez que cambia el valor del otro control.
- Darse de baja para evitar pérdidas de memoria
-
devolver
{match: true}
nos permitirá verificar si un control dado tiene el error usandomyControl.hasError(''match'')
Implementación
import { AbstractControl, ValidatorFn } from ''@angular/forms'';
import { Subscription } from ''rxjs/Subscription'';
export function matchOtherValidator(otherControlName: string): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } => {
const otherControl: AbstractControl = control.root.get(otherControlName);
if (otherControl) {
const subscription: Subscription = otherControl
.valueChanges
.subscribe(() => {
control.updateValueAndValidity();
subscription.unsubscribe();
});
}
return (otherControl && control.value !== otherControl.value) ? {match: true} : null;
};
}
Ejemplo
this.registerForm = formBuilder.group({
email: ['''', [
Validators.required, Validators.email
]],
password: ['''', [
Validators.required, Validators.minLength(8)
]],
confirmPassword: ['''', [
Validators.required, matchOtherValidator(''password'')
]]
});