I have problems with reactive forms and an array of radio buttons. My problem is I only can select single package not multiple package.How should I do so that I can select multiple package. This is my Stackblitz demo. My Form looks like this:

And This my example code
HTML
<div class="card col-8 shadow-sm">
<div class="list-group">
<form name="form" [formGroup]="form" (ngSubmit)="form.valid && onSubmit()">
<div class="list-group-item flex-column align-items-start" *ngFor="let list of packages ; list as index; let i of index">
<div class="card-body">
<div class="d-flex justify-content-between mb-3">
<span class="d-flex align-items-center">
<h5 class="card-title pr-3 d-inline-block font-weight-bold">{{list.eventName}}</h5>
</span>
</div>
<p class="card-text">
{{list.eventNote}}
</p>
<div>
<span class="font-weight-bold pr-2">Attendings :</span>
<span class="ml-5">
<mat-radio-group formControlName="attendings" aria-label="Select an option">
<mat-radio-button value="y">Yes</mat-radio-button>
<mat-radio-button value="n">No</mat-radio-button>
</mat-radio-group>
</span>
</div>
<div class="w-60 mt-4">
<div class="card card-line col-md-12 mb-3" *ngFor="let fee of list.feeList">
<div class="card-body ctrl-height">
<input type="radio" formControlName="fee" id="{{fee.feeId}}" [value]="fee">
<label for="{{fee.feeId}}">
<span class="id-conf">{{fee.category}}</span>
<span class="price">{{fee.price}}</span>
</label>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
<div class="card-footer no-gutters ctrl-lr">
<div class="card-body float-right">
{{form.value | json}}
<a (click)="submit()" class="btn btn-primary card-link d-inline pl-4 pr-4">Next </a>
</div>
</div>
</div>
Component
packages = packages;
form = new FormGroup({
attendings: new FormControl,
fee: new FormControl
});
submit() {
console.log(this.form.value)
}
You have arrays of packages in your package-list component, but you have only one FormGroup with attendings and fee FormControls for all of these packages. That's why whatever you select, it overwrites only available FormGroup.
You should use FormArray
In your package-list.component.ts
import { FormArray, FormControl, FormGroup } from '@angular/forms';
...
export class PackagesListComponent implements OnInit {
packages = packages;
// generate array of FormGroup
controls = packages.map(pack => {
return new FormGroup({
attendings: new FormControl(),
fee: new FormControl()
});
});
// gengerate main FormGroup containing our FormArray
// FormArray will contain our generated FormGroups with necessary FormControls
form = new FormGroup({
formArray: new FormArray(this.controls)
});
// this getter will be used in the template to get the formArray
get myFormArray() {
return this.form.get('formArray') as FormArray;
}
...
}
In your package-list.component.html
<div class="card col-8 shadow-sm">
<div class="list-group">
<form name="form" [formGroup]="form" (ngSubmit)="form.valid && submit()">
<div class="list-group-item flex-column align-items-start" *ngFor="let list of packages; let i = index">
<div class="card-body">
<div class="d-flex justify-content-between mb-3">
<span class="d-flex align-items-center">
<h5 class="card-title pr-3 d-inline-block font-weight-bold">{{list.eventName}}</h5>
</span>
</div>
<p class="card-text">
{{list.eventNote}}
</p>
<div>
<span class="font-weight-bold pr-2">Attendings :</span>
<span class="ml-5">
<mat-radio-group [formControl]="myFormArray.at(i).get('attendings')" aria-label="Select an option">
<mat-radio-button value="y">Yes</mat-radio-button>
<mat-radio-button value="n">No</mat-radio-button>
</mat-radio-group>
</span>
</div>
<div class="w-60 mt-4">
<div class="card card-line col-md-12 mb-3" *ngFor="let fee of list.feeList">
<div class="card-body ctrl-height">
<input type="radio" [formControl]="myFormArray.at(i).get('fee')" id="{{fee.feeId}}" [value]="fee">
<label for="{{fee.feeId}}">
<span class="id-conf">{{fee.category}}</span>
<span class="price">{{fee.price}}</span>
</label>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
<div class="card-footer no-gutters ctrl-lr">
<div class="card-body float-right">
{{form.value | json}}
<a (click)="submit()" class="btn btn-primary card-link d-inline pl-4 pr-4">Next </a>
</div>
</div>
</div>
I have done several things here:
*ngFor in line number 4:<div class="list-group-item flex-column align-items-start" *ngFor="let list of packages; let i = index"><mat-radio-group [formControl]="myFormArray.at(i).get('attendings')" aria-label="Select an option"><input type="radio" [formControl]="myFormArray.at(i).get('fee')" id="{{fee.feeId}}" [value]="fee">If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With