I am working on a form with radio button inputs (using PrimeNg ui but this shouldn't matter to the question at hand), where each radio button group is being populated by an API into a form group. In my AppComponent
I am populating the data, and is how this comes in from the API (static data for sample):
ngOnInit() {
this.settingsByCategory = [
{
categoryName: 'None',
permissions: [
{
id: 1,
name: 'Test Category 1'
},
{
id: 2,
name: 'Test Category 2'
},
{
id: 9,
name: 'Test Category 3'
}
]
}
];
this.settingForm = this.fb.group({
settings: this.fb.array([])
});
this.setForm();
}
setForm() {
this.settingsByCategory.forEach(i => {
i.permissions.forEach(p => {
(this.settingForm.get('settings') as FormArray).push(
this.fb.group({
settingId: p.id,
settingName: p.name,
permission1: null,
permission2: null,
permission3: null
})
);
});
});
}
The problem is that when I select a radio button, all groups are selected instead of just one single group.
In my HTML I am using a nested grouping of FormGroup, FormArrayName, and FormControls to populate with the appropriate data. It is a little messy, but I am first trying to work through this issue:
<ng-container>
<div>
<form [formGroup]="settingForm">
<div formArrayName="settings" class="perm-grid">
<div *ngFor="let setting of settings.controls; index as i">
<div [formGroupName]="i">
<h2 style="border-bottom: 1px solid #495057; padding-left: 5px">{{ setting.value.settingName }}</h2>
<ul class="perm-list">
<li class="radio-grid">
<div class="radio-grid-row">
<div style="margin-left: 5px"></div>
<div>Company</div>
<div>Area</div>
<div>Location</div>
</div>
<div class="radio-grid-row">
<div style="margin-left: 5px">None</div>
<div>
<p-radioButton (onClick)="logRadio($event, setting)" name="permission1"
formControlName="permission1" [value]=0>
</p-radioButton>
</div>
<div>
<p-radioButton (onClick)="logRadio($event, setting)" name="permission2"
formControlName="permission2" [value]=0>
</p-radioButton>
</div>
<div>
<p-radioButton (onClick)="logRadio($event, setting)" name="permission3"
formControlName="permission3" [value]=0>
</p-radioButton>
</div>
</div>
<div class="radio-grid-row">
<div style="margin-left: 5px">View</div>
<div>
<p-radioButton (onClick)="logRadio($event, setting)" name="permission1"
formControlName="permission1" [value]=1>
</p-radioButton>
</div>
<div>
<p-radioButton (onClick)="logRadio($event, setting)" name="permission2"
formControlName="permission2" [value]=1>
</p-radioButton>
</div>
<div>
<p-radioButton (onClick)="logRadio($event, setting)" name="permission3"
formControlName="permission3" [value]=1>
</p-radioButton>
</div>
</div>
<div class="radio-grid-row">
<div style="margin-left: 5px">Edit</div>
<div>
<p-radioButton (onClick)="logRadio($event, setting)" name="permission1"
formControlName="permission1" [value]=2>
</p-radioButton>
</div>
<div>
<p-radioButton (onClick)="logRadio($event, setting)" name="permission2"
formControlName="permission2" [value]=2>
</p-radioButton>
</div>
<div>
<p-radioButton (onClick)="logRadio($event, setting)" name="permission3"
formControlName="permission3" [value]=2>
</p-radioButton>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
</form>
</div>
</ng-container>
With standard inputs, I have used this method and it has worked just fine. Why are all the radiobutton form controls being repeated across groups?
That happens because the name
of the radio-button group is the same for all categories, so all of them are connected to each other.
You can resolve this issue like the following:
i
such as name="permission1-{{i}}"
, so this will be resolved later to name="permission1-0"
for category 1 & name="permission1-1"
for category 2...etc.primeNG
version, which is: If you define both a name and a formControlName attribute on your radio button, their values must match
, and to resolve it you can use formControl
instead of formControlName
such as: [formControl]="settingForm?.get('settings').controls[i].get('permission1')"
So the radio-botton part of your component template will look like the following:
<div class="radio-grid-row">
<div style="margin-left: 5px">None</div>
<div>
<p-radioButton (onClick)="logRadio($event, setting)" name="permission1-{{i}}"
[formControl]="settingForm?.get('settings').controls[i].get('permission1')" [value]="0">
</p-radioButton>
</div>
<div>
<p-radioButton (onClick)="logRadio($event, setting)" name="permission2-{{i}}"
[formControl]="settingForm?.get('settings').controls[i].get('permission2')" [value]="0">
</p-radioButton>
</div>
<div>
<p-radioButton (onClick)="logRadio($event, setting)" name="permission3-{{i}}"
[formControl]="settingForm?.get('settings').controls[i].get('permission3')" [value]="0">
</p-radioButton>
</div>
</div>
<div class="radio-grid-row">
<div style="margin-left: 5px">View</div>
<div>
<p-radioButton (onClick)="logRadio($event, setting)" name="permission1-{{i}}"
[formControl]="settingForm?.get('settings').controls[i].get('permission1')" [value]="1">
</p-radioButton>
</div>
<div>
<p-radioButton (onClick)="logRadio($event, setting)" name="permission2-{{i}}"
[formControl]="settingForm?.get('settings').controls[i].get('permission2')" [value]="1">
</p-radioButton>
</div>
<div>
<p-radioButton (onClick)="logRadio($event, setting)" name="permission3-{{i}}"
[formControl]="settingForm?.get('settings').controls[i].get('permission3')" [value]="1">
</p-radioButton>
</div>
</div>
<div class="radio-grid-row">
<div style="margin-left: 5px">Edit</div>
<div>
<p-radioButton (onClick)="logRadio($event, setting)" name="permission1-{{i}}"
[formControl]="settingForm?.get('settings').controls[i].get('permission1')" [value]="2">
</p-radioButton>
</div>
<div>
<p-radioButton (onClick)="logRadio($event, setting)" name="permission2-{{i}}"
[formControl]="settingForm?.get('settings').controls[i].get('permission2')" [value]="2">
</p-radioButton>
</div>
<div>
<p-radioButton (onClick)="logRadio($event, setting)" name="permission3-{{i}}"
[formControl]="settingForm?.get('settings').controls[i].get('permission3')" [value]="2">
</p-radioButton>
</div>
</div>
And here is the edited version of your stackbiltz: https://stackblitz.com/edit/primeng-dynamicdialog-demo-25iydv