I’m having a tough time comparing e-mail fields as part of my form validation with formBuilder. I’ve read the following forum posts but I still can’t get it to work the way I want it to, so I’m hoping someone can shed some light on things:
I have the validation being performed correctly, however I can’t work out how to assign the error value to the re_password field. Basically I want the error text to be displayed under the “re_password” ion-input, much like it does for the “email” and “password” ion-inputs.
Here is my setup:
home.html
<p *ngIf="submitAttempt" style="color: #ea6153;">There are errors with your submission!</p>
<form [formGroup]="registerForm">
<ion-item [class.invalid]="!email.valid && email.touched">
<ion-label floating>Email</ion-label>
<ion-input type="text" value="" [formControl]="email" autocapitalize="off"></ion-input>
</ion-item>
<ion-item *ngIf="email.hasError('required') && email.touched" class="invalid">
<p>* Email is required!</p>
</ion-item>
<ion-item *ngIf="email.hasError('minlength') && email.touched" class="invalid">
<p>* Minimum username length is 3!</p>
</ion-item>
<ion-item *ngIf="email.hasError('maxlength') && email.touched" class="invalid">
<p>* Maximum username length is 25!</p>
</ion-item>
<ion-item *ngIf="email.hasError('invalid_domain') && email.touched" class="invalid">
<p>* Invalid e-mail domain!</p>
</ion-item>
<ion-item [class.invalid]="!password.valid && password.touched">
<ion-label floating>Password</ion-label>
<ion-input type="password" value="" [formControl]="password"></ion-input>
</ion-item>
<ion-item *ngIf="password.hasError('required') && password.touched" class="invalid">
<p>* Password is required!</p>
</ion-item>
<ion-item *ngIf="password.hasError('minlength') && password.touched" class="invalid">
<p>* Minimum password length is 3!</p>
</ion-item>
<ion-item *ngIf="password.hasError('maxlength') && password.touched" class="invalid">
<p>* Maximum password length is 25!</p>
</ion-item>
<ion-item [class.invalid]="!re_password.valid && re_password.touched">
<ion-label floating>Re-enter Password</ion-label>
<ion-input type="password" value="" [formControl]="re_password"></ion-input>
</ion-item>
<ion-item *ngIf="re_password.hasError('pw_mismatch') && re_password.touched" class="invalid">
<p>* Passwords do not match!</p>
</ion-item>
</form>
<button primary (click)="save()" [disabled]="(!registerForm.valid)">Submit Form</button>
<br />
<br />
<button primary (click)="logControlErrors()">Log Control Errors</button>
home.ts
import {Component} from '@angular/core';
import {FormBuilder, FormGroup, Validators, AbstractControl} from '@angular/forms';
import {EmailValidator} from '../../validators/email';
import {PasswordValidator} from '../../validators/password';
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
registerForm: FormGroup;
email: AbstractControl;
password: AbstractControl;
re_password: AbstractControl;
constructor(private formBuilder: FormBuilder) {
this.registerForm = formBuilder.group({
'email': ['', Validators.compose([Validators.required, Validators.minLength(3), Validators.required, Validators.maxLength(25), EmailValidator.checkEmail])],
'password': ['', [Validators.required, Validators.minLength(5), Validators.maxLength(45)]],
're_password': ['', [Validators.required]]
}, { 'validator': PasswordValidator.isMatching }
);
this.email = this.registerForm.controls['email'];
this.password = this.registerForm.controls['password'];
this.re_password = this.registerForm.controls['re_password'];
}
ionViewDidLoad() {
}
save(){
this.submitAttempt = true;
if(!this.registerForm.valid){
console.log("Invalid Submission!")
}
else {
console.log("Success!")
console.log(this.registerForm.value);
}
}
elementChanged(input){
let field = input.inputControl.name;
this[field + "Changed"] = true;
}
logControlErrors(){
console.log(this.email.errors);
console.log(this.password.errors);
console.log(this.re_password.errors);
}
}
email.ts (Custom Validator)
import {FormControl} from '@angular/forms';
export class EmailValidator {
static checkEmail(control: FormControl){
console.log("e-mail check");
var requiredDomains = ["gmail.com","yahoo.com"];
var lowercaseValue = control.value.toLowerCase();
var providedDomain = lowercaseValue.substr(lowercaseValue.indexOf('@')+1);
var returnVal: any;
for (var i = 0; i < requiredDomains.length; i++) {
if(requiredDomains[i] != providedDomain) {
returnVal = {"invalid_domain": true};
i = requiredDomains.length;
}
}
return returnVal;
}
}
password.ts (Custom Validator)
import {FormGroup} from '@angular/forms';
export class PasswordValidator {
static isMatching(group: FormGroup){
console.log("password check");
var firstPassword = group.controls['password'].value;
var secondPassword = group.controls['re_password'].value;
if((firstPassword && secondPassword) && (firstPassword != secondPassword)){
console.log("mismatch");
return { "pw_mismatch": true };
} else{
return null;
}
}
}
I’m guessing the solution relates to how I am calling the e-mail custom validator. The problem I am facing is that if I call it inside the “re_password” validator then I don’t know how to get the value of the “password” form control (in order to perform the comparison). If I call it outside of the “re_password” validator then I can get both the “password” and “re_password” form control values using FormGroup, however I don’t know how to assign the error to the “re_password” form control.
@richardmarais - the most recent posts I’ve read on the subject have been started by you. Did you ever get this validation working with the latest release of Ionic 2? Do you know what I need to do to fix my code?
Thanks in advance for any help.