Created
November 24, 2016 19:05
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** '/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; | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** /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 | |
} | |
} |
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?
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.
Thanks dougal for share
Hernan
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Some unnecessary bits left in like submitError and submitError that can be ignored depending on your implementation.