In an Angular 4 application, how can I validate two fields of a form doing a comparison?
For example, let's suppose that my form has a startDate
and an endDate
date fields and I want to make sure that the endDate
must be bigger than the startDate
.
CompareValidator also can be used to check whether a form field contains a particular data type. For example, you can use the control to check whether a user entered a valid date, number, or currency value.
Prerequisites: Basic knowledge in Angular Reactive Forms. Angular provides FormControl validation in order to determine whether a form field is valid or not. These form control validation helps to determine the validity of a form field with some predetermined rules.
In simple words, making sure our data is correct by using multiple fields to check the validity of another. In fancier terms, this process is called Cross Field Validation. Sanity checking your dataset for data integrity is essential to have accurate analysis and running machine learning models.
ValidatorFnlinkA function that receives a control and synchronously returns a map of validation errors if present, otherwise null. interface ValidatorFn { (control: AbstractControl<any, any>): ValidationErrors | null }
When you want to implement validations containing one or more sibling (form)controls, you have to define the validator function on a level up/above that of the sibling controls. For ex:
ngOnInit() {
this.form = this.formbuilder.group({
'startDate': ['', [<control-specific - validations >]],
'endDate': ['', [<control-specific - validations >]]
}, { validator: checkIfEndDateAfterStartDate });
}
Then outside the component class's definition (in the same file), define the function checkIfEndDateAfterStartDate
as well.
export function checkIfEndDateAfterStartDate (c: AbstractControl) {
//safety check
if (!c.get('startDate').value || !c.get('endDate').value) { return null }
// carry out the actual date checks here for is-endDate-after-startDate
// if valid, return null,
// if invalid, return an error object (any arbitrary name), like, return { invalidEndDate: true }
// make sure it always returns a 'null' for valid or non-relevant cases, and a 'non-null' object for when an error should be raised on the formGroup
}
This validation will make the FormGroup
invalid by adding the error-flag (here invalidEndDate
) to true
to the errors object for that FormGroup
. If you want to have specific errors to be set on any of the sibling controls instead, then you can manually set the error flags on that formControl
by using something like, c.get('endDate').setErrors({ invalidEndDate: true })
. If you do this, then make sure you clear them for a valid case by setting the errors to null
like this, c.get('endDate').setErrors(null)
.
A live demo of a similar validation can be seen here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With