2

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?

7
  • 1
    Try instead hasError('validemail') this: hasError('validateEmail') - this is the property of error object that you return from validator Commented Dec 13, 2016 at 8:54
  • I wish I could hide... like forever ! :P Thanks! it works like this. And I noticed that my password regexp is wrong... Commented Dec 13, 2016 at 8:59
  • @ZasypinN.V. Updated question with related issue... :) Commented Dec 13, 2016 at 9:11
  • I'm not sure if I've undestood question correctly. As I understand FormGroup only defines object of your form, and it's not responsible for showing/hiding elements of it. Commented Dec 13, 2016 at 9:51
  • Well, I'm quite confused with it... In my template, I declare that the button has to enable on condition "loginForm.valid" OR "registerForm.valid". When "registerForm" is valid, then button is clickable. If not, it's disabled. But, it only works when both 3 fields are valid. "button in login form" should be clickable when login and password are valid, email is there not required... (only required in registerform formgroup) @ZasypinN.V. Commented Dec 13, 2016 at 9:56

1 Answer 1

1

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
});
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.