Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reactive Form Array with Radio Buttons

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:

enter image description here

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)
  }
like image 317
Pravu Avatar asked Jan 31 '26 22:01

Pravu


1 Answers

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:

  1. updated your *ngFor in line number 4:
    <div class="list-group-item flex-column align-items-start" *ngFor="let list of packages; let i = index">
  2. change the line number 18:
    <mat-radio-group [formControl]="myFormArray.at(i).get('attendings')" aria-label="Select an option">
  3. change the line number 27:
    <input type="radio" [formControl]="myFormArray.at(i).get('fee')" id="{{fee.feeId}}" [value]="fee">
like image 117
Mazedul Islam Avatar answered Feb 02 '26 14:02

Mazedul Islam



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!