Reputation: 2102
Here is the problem,
I try to build a "custom validator" for a password and an email field with angularJS v2. Following the "standard structure", I do have these files interacting together :
/forms/form.component.ts
/validators/password.validator.ts
/validators/email.validator.ts
In my form component template, I come to this for the two concerned fields :
//...
<input type="password" class="form-control" placeholder="password" [(ngModel)]="user.password" [formControl]="passwordCtrl" required />
<div *ngIf="passwordCtrl.dirty && passwordCtrl.hasError('validPassword')">PASSWORD NOT VALID</div>
//...
<input type="text" class="form-control" placeholder="email" [(ngModel)]="user.email" [formControl]="emailCtrl" required />
<div *ngIf="emailCtrl.dirty && emailCtrl.hasError('validemail')">EMAIL NOT VALID</div>
//...
And, in the component (.ts) I have this :
//...
import { validateEmail } from '../validators/email.validator';
import { validatePassword } from '../validators/password.validator';
//...in constructor(fb: FormBuilder) :
this.passwordCtrl = fb.control(this.user.password, Validators.compose([validatePassword])),
this.emailCtrl = fb.control(this.user.email, Validators.compose([validateEmail])),
//...
Declarations and instanciations are right in my component.ts since when I do add a "required" validator in the "compose." part, this works fine. Problem seems to come from the validator itself... Here are them :
//email.validator.ts
import { FormControl } from '@angular/forms';
export function validateEmail(c: FormControl){
let EMAIL_REGEXP = new RegExp(`([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)+`);
return EMAIL_REGEXP.test(c.value) ? null : {
validateEmail: {
validemail: false
}
};
}
//password.validator.ts
import { FormControl } from '@angular/forms';
export function validatePassword(c: FormControl) {
let PASSWORD_REGEXP = new RegExp(`^.*(?=.{6,20})(?=.*\d)(?=.*[a-zA-Z]).*$`);
return PASSWORD_REGEXP.test(c.value) ? null : {
validatePassword: {
validpassword: false
}
};
}
The validator "example" comes from there : http://blog.thoughtram.io/angular/2016/03/14/custom-validators-in-angular-2.html
This changes nothing when I change "validpassword" or "validemail" return value (true, false, whatever). The div depending on validateemail, validatepassword validators, NEVER appears...
Thanks for reading/help
Update 1 :
My form is there to handle LOGIN and REGISTER possibilities. So, there are 2 forms, one shows by default, another one shows when clicking on "register" link. BUT they are located on same page.
In my form.component.ts, I do create 2 formGroups :
//...
this.loginForm = fb.group({
login: this.loginCtrl,
password: this.passwordCtrl
}),
this.registerForm = fb.group({
login: this.loginCtrl,
password: this.passwordCtrl,
email: this.emailCtrl
});
So, the two different forms, are related to specific formGroups. I bind them in the template like this (and add buttons to submit) :
//...
<form (ngSubmit)="register()" [formGroup]="registerForm">
//...
<button class="btn btn-default submit" [disabled]="!registerForm.valid">Submit</button>
//...
//...
<form (ngSubmit)="login()" [formGroup]="loginForm">
//...
<button class="btn btn-default submit" [disabled]="!loginForm.valid">Login</button>
Both buttons keep disabled EXCEPT when ALL fields are completed. Meaning that : if the email field is empty in the "registerForm" group, then the "login button" in the "loginForm" group keeps disabled!
FormGroup"ing" isn't supposed to handle these cases?
Upvotes: 2
Views: 139
Reputation: 234
Main question - instead hasError('validemail')
use this: hasError('validateEmail')
- this is the property of error object that you return from validator.
Update 1: use for your form components new instances of FormControl.
this.loginFormLoginCtrl = new FormControl('', Validators.required);
this.loginFormPasswordCtrl = new FormControl('', Validators.required);
this.registerFormLoginCtrl = new FormControl('', Validators.required);
this.registerFormPasswordCtrl = new FormControl('', Validators.required);
this.registerFormLoginCtrl = new FormControl('', Validators.required);
....
this.loginForm = fb.group({
login: this.loginFormLoginCtrl,
password: this.loginFormPasswordCtrl
});
this.registerForm = fb.group({
login: this.registerFormLoginCtrl,
password: this.registerFormPasswordCtrl,
email: this.registerFormEmailCtrl
});
Upvotes: 1