Margerine
Margerine

Reputation: 183

How to get the value of my dropdown for each check box selected in Angular8

I am dynamically creating checkboxes and associated dropdowns from the data i get from api ....

my html code below::

<label [for]="i" class="form-check-label fw7 h5 mb0" formArrayName="planDivList" *ngFor="let plan of planForm.controls.planDivList.controls; let i = index">
    <br>
    <input [name]="i" [id]="i" class="form-check-input" type="checkbox" [formControlName]="i">
    {{planDivList[i].planCode}}
    <label *ngIf="planDivList[i].divisions.length > 0" for="inputDiv">
        Divisions
        <select id="inputDiv" formcontrolName='divCtrl'>
            <option *ngFor="let division of planDivList[i].divisions" Value="division.divisionCode">
                {{division.divisionName}}
            </option>
        </select>
    </label>
</label>

my dataset is

planDivList = [
    { planCode: "B3692", divisions: [] },
    { planCode: "B3693", divisions: [] },
    { planCode: "B67", divisions: [{ divisionCode: "2", divisionName: "Assisted Living " }, { divisionCode: "1", divisionName: "LILC" }] },
    { planCode: "B69", divisions: [{ divisionCode: "3", divisionName: "Four Seasons" }, { divisionCode: "2", divisionName: "Lakeside" }, { divisionCode: "1", divisionName: "Sunrise" }] }
];

ts file:

const selectedPlans = this.planForm.value.planDivList
          .map((checked, index) => (checked ? this.planDivList[index].planCode : null))
          .filter(value => value !== null);

console.log(selectedPlans);

Here is my stackblitz

https://stackblitz.com/edit/angular-fsgswa?file=src%2Fapp%2Fapp.component.ts

i am able to get the selected checkbox value.But How do i get the value of the respective division that is selected for that checkbox in submit button? Any help is appreciated

Upvotes: 1

Views: 2728

Answers (1)

Kurt Hamilton
Kurt Hamilton

Reputation: 13515

To solve your problem, I have take several steps, which I will break down below.

1. Build your form array

You have an array of data for which each item should have multiple controls (checkbox and select). This requires a form array of form groups.

Your form is an array and nothing more, so we can simply bind the form to an array.

We will need to refer to the nested form control values later, so store them in a property for easy reference.

form: FormArray;
private formControls: {
  checkbox: FormControl;
  division: FormControl;
}[];

// initialise component in ngOnInit instead of constructor
ngOnInit() {    
  this.formControls = this.plans.map((plan, i) => {
    const divisionCode = plan.divisions.length > 0 
      ? plan.divisions[0].divisionCode 
      : '';
    return { 
      checkbox: this.fb.control(i === 0),
      division: this.fb.control(divisionCode)
    };
  });

  const formGroups = this.formControls.map(x => this.fb.group(x));
  this.form = this.fb.array(formGroups, this.minSelectedCheckboxes(1));
}

2. Bind the HTML to the form

You should prefer handling form submit by using (submit) to a button (click). (submit) will handle all of the ways in which a form can be submitted.

The HTML bindings match the structure of the form we built. Notice how the checkbox and division controls are binding to the ith form group in the array.

I would also recommend using your model as much as possible to generate loops, and restrict form binding to the form control directives.

<form [formGroup]="form" (submit)="onSubmit()">    
  <div *ngFor="let plan of plans; index as i" [formGroupName]="i">
    <label>
      <input type="checkbox" formControlName="checkbox">
      {{plan.planCode}}
    </label>

    <label *ngIf="plan.divisions.length > 0" >
      Divisions
      <select formControlName="division">
        <option *ngFor="let division of plan.divisions"   
          [value]="division.divisionCode">
          {{division.divisionName}}
        </option>
      </select>
    </label>
  </div>  
  <div *ngIf="formInvalid && form.hasError('required')">
    At least one plan must be selected
  </div>
  <button>Enroll</button>
</form>

3. Handle the submit

It is now simply a case of querying the form control array to find out which ones are checked, and what the selected division code is where relevant.

onSubmit(){
  this.formInvalid = this.form.invalid;    
  if (this.formInvalid) {
    return;
  }

  this.selectedPlans = this.plans
    .map((plan, i) => ({
      planCode: plan.planCode,
      selected: this.formControls[i].checkbox.value,
      divisionCode: this.formControls[i].division.value
    }))
    .filter(x => x.selected);
}

The actual output that you need will probably differ slightly from my example, and I renamed a few of your properties for the purposes of a simpler demo. Hopefully I have demonstrated the techniques that you can apply to your own form.

DEMO: https://stackblitz.com/edit/angular-qxm8wk

Upvotes: 1

Related Questions