I have a formgroup containing several fields. I also have a check box. When the check-box is checked, I'd like one of the input fields to take values from another input field. If the check-box is not checked I'd like to make the field independent.
I tried using the boolean value of the check-box form-control to assign values of one of the input fields to another (side of a sqaure = sides of a rectangle, if the rectangle is a square) but Angular threw an error message saying "too much recursion".
in component.ts
ngOnInit() {
this.formMain = this.fb.group({
sideSquare: this.addSq.side,
lenRect: this.addRect.len,
widRect: this.addRect.wid,
isSquare: true,
});
this.onChanges();
}
onChanges(): void {
this.formMain.valueChanges.subscribe(val => this.updateValues());
}
updateValues(): void {
this.formMain.get('lenRect').setvalue(
this.formMain.get('isSquare').value ?
this.formMain.get('sideSquare').value : 0 );
this.formMain.get('widRect').setvalue(
this.formMain.get('isSquare').value ?
this.formMain.get('sideSquare').value : 0 );
}
in component.html
<form [formGroup]="formMain">
<mat-card>
<mat-card-header>
<mat-card-title>Square vs Rectangle</mat-card-title>
</mat-card-header>
<mat-card-content>
<mat-form-field>
<input matInput placeholder="Square side" type="number" formControlName="sideSquare">
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Rectangle length" type="number" formControlName="lenRect">
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Rectangle length" type="number" formControlName="widRect">
</mat-form-field>
<mat-checkbox formControlName="isSquare">Rectangle is a square</mat-checkbox>
</mat-card-content>
</mat-card>
</form>
This problem is similar to forms where shipping address is the same as billing address (but simpler). I found another question on the address problem but the suggested answer didn't work for me.
Is there a way of doing this well? Thanks for your help!
Keep it simple :
form = new FormGroup({
'f1': new FormControl(''),
'f2': new FormControl(''),
'propagate': new FormControl(false),
});
ngOnInit() {
this.form.valueChanges.pipe(
filter(formValue => formValue.propagate),
map(formValue => formValue.f1),
).subscribe(f1 => this.form.get('f2').setValue(f1, { emitEvent: false }));
}
In this example, F1 is the master control and F2 the slave control.
You listen to form value changes : if the checkbox is checked, then you do something, otherwise you do not.
You then map the value of the form to only the value of F1.
Finally, you set the value of F2 according to F1, without emitting an event (to prevent an infinite loop)