FormGroup containing Radio Buttons with an Angular FormArray
What you need to consider when looping through an array group is the id
and name
you assign to each one. You currently have your input id
and name
getting set to the same value in each loop.
You would need to use the i
variable you have available to make the id
and name
for each input a dynamic value, like below:
<div [formGroup]="form">
<div *ngIf="conditions" formArrayName="conditions">
<div *ngFor="let condition of conditions.controls; let i=index" [formGroupName]="i">
<input class="form-control" formControlName="title" type="text" placeholder="title">
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" id="{{ 'acceptable' + i}}" formControlName="acceptability"
class="custom-control-input" [value]="ACCEPTABILITY.ACCEPTABLE">
<label class="custom-control-label" for="{{ 'acceptable' + i}}">Acceptable</label>
</div>
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" id="{{ 'unacceptable' + i}}" formControlName="acceptability"
class="custom-control-input" [value]="ACCEPTABILITY.INACCEPTABLE">
<label class="custom-control-label" for="{{ 'unacceptable' + i}}">Unacceptable</label>
</div>
</div>
<button type="button" class="btn btn-outline-dark btn-block" (click)="addCondition()">
<i class="fa fa-plus fa-lg mr-3"></i>ADD A NEW CONDITION</button>
</div>
</div>
<div>
<pre>{{ form.value | json }}</pre>
</div>
Notice the string interpolation for the name
and id
attributes. Same goes for
the for attribute in the labels.
You may have to play around with this to get is exactly where it needs to be. (I didn't test it thoroughly)
Hope this helps.
Sammy
Updated on June 11, 2022Comments
-
Sammy almost 2 years
I have the following code that dynamically adds a form group containing a title and two radio buttons to create a condition, effectively providing its title and whether or not it's an acceptable condition:
export enum Acceptability { ACCEPTABLE, INACCEPTABLE } export interface Condition { title: string; acceptability: Acceptability; } export class AddCondition implements OnInit { form: FormGroup; ACCEPTABILITY = Acceptability; constructor(private fb: FormBuilder) {} ngOnInit() { // build the form this.form = this.fb.group({ conditions: this.fb.array([]) }); } get conditions(): FormArray { return this.form.get('conditions') as FormArray; } addCondition() { this.conditions.push(this.fb.group({ title: ['', Validators.required], acceptability: ['', Validators.required] })); } }
<div formArrayName="conditions"> <div *ngFor="let condition of conditions.controls; let i=index" [formGroupName]="i"> <input class="form-control" formControlName="title" type="text" placeholder="title"> <div class="custom-control custom-radio custom-control-inline"> <input type="radio" id="acceptable" formControlName="acceptability" name="acceptability" class="custom-control-input" [value]="ACCEPTABILITY.ACCEPTABLE"> <label class="custom-control-label" for="acceptable">Acceptable</label> </div> <div class="custom-control custom-radio custom-control-inline"> <input type="radio" id="inacceptable" formControlName="acceptability" name="acceptability" class="custom-control-input" [value]="ACCEPTABILITY.INACCEPTABLE"> <label class="custom-control-label" for="inacceptable">Inacceptable</label> </div> </div> <button type="button" class="btn btn-outline-dark btn-block" (click)="addCondition()"> <i class="fa fa-plus fa-lg mr-3"></i>ADD A NEW CONDITION</button> </div>
The problem is that when clicking the ADD A NEW CONDITION button, and the new form group appears, every time I select any radio button in the group array, the corresponding radio button of the first array item in the group is the one that gets selected.
-
Sammy over 6 yearsThank you, but this then produces the following error:
If you define both a name and a formControlName attribute on your radio button, their values must match. Ex: <input type="radio" formControlName="food" name="food">
-
Sammy over 6 yearsBut then of course, if I go ahead and change
formControlName
to match it, then I get the error that the control does not exist; which is normal since when I push the new group, I push it with the nameacceptability
only. -
R. Richards over 6 yearsHave you tried it without setting the
name
attribute at all by removing it? -
Sammy over 6 yearsYes, that's where I get
Error: Cannot find control with path: 'conditions -> 0 -> acceptability0'
which is, I believe, logical, since what I'mpush
ing up there isacceptability
only. -
R. Richards over 6 yearsOkay, let me try a few things. I will update the answer when I have something. Sorry about the back and forth!
-
R. Richards over 6 yearsI have updated the answer. This is working for me. No errors at all. I am able to add to the form array and the radio buttons work as expected. I added a div tag to output the form value, which looks accurate to me, and update when the form values change. Have a look and give this a try.
-
Sammy over 6 yearsThank you; besides removing
name
, did you do anything else that I'm not seeing? When you click the "add" button, you do not get theCannot find control with path...
error? -
R. Richards over 6 yearsNo errors whatsoever. Removing the name was all I really did from the code I originally posted. I pulled your component code into a project I have been playing around with to test this. Works.
-
Sammy over 6 yearsIndeed; I guess removing name and not having
formControlName
dynamic was the one permutation I did not try. Thank you :) -
IronWorkshop over 4 yearsThis helped alot thank you, I was stuck on it for a while and couldn't work out why. I did have to remove the '[]' expression syntax from my 'value' attribute however. But everything else worked great. Thanks!