I have a reactive form with 2 controls (port_start and port_end) that have the following requirements:
This is what I tried so far:
[...]
this.formModel.addControl('port_start',
new FormControl(object.port_start ? object.port_start : 0,
[Validators.required, Validators.min(0), Validators.max(65535), this.minMaxValidator('port_start', 'port_end').bind(this)]));
this.formModel.addControl('port_end',
new FormControl(object.ort_end ? object.port_end : 0,
[Validators.required, Validators.min(0), Validators.max(65535), this.minMaxValidator('port_start', 'port_end').bind(this)]));
[...]
This is the custom validator function:
minMaxValidator = function(startControl : string, endControl : string): ValidatorFn {
return (control: FormControl): {[key: string]: any} => {
let valid = true;
let valStart = 0;
let valEnd = 0;
if(this.formModel.controls[startControl] && this.formModel.controls[endControl]) {
valStart = <number>this.formModel.controls[startControl].value;
valEnd = <number>this.formModel.controls[endControl].value;
}
valid = valEnd >= valStart;
return valid ? null : { minmax : true };
};
}
This works fine except for this problem:
I understand that the problem is that I need to re-check the associated field each time I change the other one's value, but I don't know how to do it.
Any ideas? Thanks,
The min
, max
and required
validators can be kept as is. If you want to validate one control based on the value of another, you need to lift the validation to the parent control.
import { Component } from '@angular/core';
import { ValidatorFn, FormBuilder, FormGroup, Validators } from '@angular/forms';
const portStartEnd: ValidatorFn = (fg: FormGroup) => {
const start = fg.get('portStart').value;
const end = fg.get('portEnd').value;
return start && end && start < end ? null : { startEnd: true };
}
@Component({
selector: 'my-app',
template: `
<input [formControl]="form.get('portStart')" type="number" >
<input [formControl]="form.get('portEnd')" type="number" >
{{ form.valid }}
`,
styleUrls: ['./app.component.css']
})
export class AppComponent {
form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
portStart: [null, [Validators.required, Validators.min(0), Validators.max(65535)]],
portEnd: [null, [Validators.required, Validators.min(0), Validators.max(65535)]]
}, { validator: portStartEnd } );
}
}