Sometimes, we need to add, remove or modify controls in a form in run time. For example, when user click on a check box control then an input apprear
In the class code we just add 3 form controls as normal.
form: FormGroup;
ngOnInit() {
this.form = new FormGroup({
optionA: new FormControl(false),
optionB: new FormControl(false),
optionBExtra: new FormControl('', [ Validators.required ])
});
}
Then in template code, the input form control we add directive *ngIf with condition is check box B value
<form [formGroup]="form">
<input type="checkbox" formControlName="optionA"> Option A
<input type="checkbox" formControlName="optionB"> Option B
<input formControlName="optionBExtra" placeholder="Reason" *ngIf="optionB.value">
</form>
The problem is the form still invalid even if the input is disappear, because of the following reasons:
- The
optionBExtra
control still be a part of this form even if it not appears - The
optionBExtra
control still haveValidators.required
even if it not appears - The
optionBExtra
control still enable even if it not appears
You can see the Live demo
We can add a listener for check box B and handle whenever it checked add a control named optionBExtra
and remove when it unchecked
this.optionB.valueChanges.subscribe(checked => {
if (checked) {
const validators = [ Validators.required, Validators.minLength(5) ];
this.form.addControl('optionBExtra', new FormControl('', validators));
} else {
this.form.removeControl('optionBExtra');
}
this.form.updateValueAndValidity();
});
You can see the Live demo
We can add or remove the validators of a control in runtime base on user interact with the UI, in this case user check the check box B
this.optionB.valueChanges.subscribe(checked => {
if (checked) {
this.optionBExtra.setValidators([Validators.required, Validators.minLength(5)]);
} else {
this.optionBExtra.setValidators(null);
}
this.optionBExtra.updateValueAndValidity();
});
We can just simply disable or enable a control
this.optionB.valueChanges.subscribe(checked => {
checked ? this.optionBExtra.enable() : this.optionBExtra.disable()
});