Skip to content

Instantly share code, notes, and snippets.

@dougal83
Created November 24, 2016 19:05
Show Gist options
  • Save dougal83/27bbeffd6129d9cb620d0e996fd8156b to your computer and use it in GitHub Desktop.
Save dougal83/27bbeffd6129d9cb620d0e996fd8156b to your computer and use it in GitHub Desktop.
Angular 2 validator to compare two controls in a form (e.g. passwords on signup forms) v0.1
/** '/src/app/shared/equal-value-validator.ts' */
/** Just a demo/draft, please ensure your implementation is sound before going live */
import { FormGroup, ValidatorFn } from '@angular/forms';
/** this control value must be equal to given control's value */
export function equalValueValidator(targetKey: string, toMatchKey: string): ValidatorFn {
return (group: FormGroup): {[key: string]: any} => {
const target = group.controls[targetKey];
const toMatch = group.controls[toMatchKey];
if (target.touched && toMatch.touched) {
const isMatch = target.value === toMatch.value;
// set equal value error on dirty controls
if (!isMatch && target.valid && toMatch.valid) {
toMatch.setErrors({equalValue: targetKey});
const message = targetKey + ' != ' + toMatchKey;
return {'equalValue': message};
}
if (isMatch && toMatch.hasError('equalValue')) {
toMatch.setErrors(null);
}
}
return null;
};
}
/** /src/app/auth/register/register.component.ts */
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { FormGroup, Validators, FormBuilder } from '@angular/forms';
import { equalValueValidator } from '../../shared/equal-value-validator';
@Component({
selector: 'app-register',
templateUrl: './register.component.html',
styleUrls: ['./register.component.css']
})
export class RegisterComponent implements OnInit {
private registrationForm: FormGroup;
private submitError = false;
private formErrors = {
'username': '',
'password': '',
'confirmPassword': ''
};
constructor(private router: Router,
private fb: FormBuilder) { }
ngOnInit() {
this.buildForm();
}
buildForm() {
this.registrationForm = this.fb.group({
'username': ['', [
Validators.required
]
],
'password': ['', [
Validators.required,
Validators.minLength(8)
]
],
'confirmPassword': ['', [
Validators.required,
Validators.minLength(8)
]
]
},
{validator: equalValueValidator('password', 'confirmPassword')} // key is to validate on the form group
);
}
register() {
// do somthing
}
}
@dougal83
Copy link
Author

Some unnecessary bits left in like submitError and submitError that can be ignored depending on your implementation.

@PTC-JoshuaMatthews
Copy link

@dougal83

Thanks for the validator! One issue I am having is that if the equalValue form control is the last item in the form, then the touched property isn't set on it until blur, but the validator doesn't fire again after that point so the fields never get compared. Do you have any ideas for getting around this? Currently having to comment out the check for touched, any better idea?

@dougal83
Copy link
Author

@PTC-JoshuaMatthews

Apologies for late reply. I've adopted a simpler method following some angular documentation, whereby we just rely on the form group level validation. See new equal value example here.. Hope this helps others down the line.

@HernanNET
Copy link

Thanks dougal for share
Hernan

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment