I'm trying to create a very generic\dynamic reactive form which can use a custom Validation Function for a formgroup (to compare 2 dates). The function can actually be any validation function which is of type ValidatorFn:
export interface ValidatorFn {
(control: AbstractControl): ValidationErrors | null;
}
Here is the root problem:
I'm defining the function in a kind of configuration file and I init the reactive form with it (receiving the function as a parameter) and set the formGroup with the validationFn.
Here is the function:
customValidationFunction : ValidatorFn = (group : FormGroup) : ValidationErrors | null =>
{
return (/*control : AbstractControl*/)/*:{[key: string] : any} | null*/ =>
{
if (group.controls["CreatedDateFormatFrom"] && group.controls["CreatedDateFormatTo"])
{
let from : AbstractControl = group.get("CreatedDateFormatFrom");
let to : AbstractControl = group.get("CreatedDateFormatTo");
const inValid = from && to && to.value < from.value;
return inValid ? {'invalidDates' : true } : null;
}
return null;
}
}
Now, in the "customize\generic\dynamically created" reactive form initiation, I set the function (or some functions):
initForm(formGroupCustomValidation? : ValidatorFn[] )
{
let group: any = {};
//Here I initiate the group with FormControls, for example:
group[<fieldName>] = new FormControl(<some value> || '');
//This is where the custom validation function comes:
if (formGroupCustomValidation)
{
this.form = new FormGroup(group, {validators:
formGroupCustomValidation });
}
this.form.valueChanges.subscribe(values => {
console.log(values);
this.formValid();
})
}
I'm sorry for the "blurry" code, but this is due to the dynamically created form. The problem is how to pass and execute the function with the group : FormGroup parameter ? I tend to believe that I have some problem with the function definition\scope, etc. I can't see the function body triggered, when trying to debug the function. Please support.
You don't have to return another function since you are not passing extra arguments, that would be enough:
customValidationFunction: ValidatorFn = (group: FormGroup) => {
const from: AbstractControl = group.get('CreatedDateFormatFrom');
const to: AbstractControl = group.get('CreatedDateFormatTo');
if (from && to) {
const inValid = from && to && to.value < from.value;
return inValid ? {'invalidDates': true} : null;
}
return null;
}
Edit 1:
Ok I missed a point a bit since you want to pass this first group to second one and perform validation on controls from first one.
That should work:
const group = new FormGroup({
CreatedDateFormatFrom: new FormControl(),
CreatedDateFormatTo: new FormControl()
});
const group2 = new FormGroup({anotherGroup: group}, this.customValidationFunction(group));
group.controls.CreatedDateFormatFrom.setValue('11-12-2018');
group.controls.CreatedDateFormatTo.setValue('11-11-2018');
customValidationFunction: ValidatorFn = (group: FormGroup) => {
return () => {
const from: AbstractControl = group.get('CreatedDateFormatFrom');
const to: AbstractControl = group.get('CreatedDateFormatTo');
if (from && to) {
const inValid = from && to && to.value < from.value;
return inValid ? {'invalidDates': true} : null;
}
return null;
};
}