Angular 2: Get Values of Multiple Checked Checkboxes

JsonFormsCheckboxAngularAngular2 Forms

Json Problem Overview


My problem is really simple: I have a list of checkboxes like this:

<div class="form-group">
    <label for="options">Options :</label>
    <label *ngFor="#option of options" class="form-control">
        <input type="checkbox" name="options" value="option" /> {{option}}
    </label>
</div>

And I would like to send an array of the selected options, something like: [option1, option5, option8] if options 1, 5 and 8 are selected. This array is part of a JSON that I would like to send via an HTTP PUT request.

Thanks for your help!

Json Solutions


Solution 1 - Json

Here's a simple way using ngModel (final Angular 2)

<!-- my.component.html -->

<div class="form-group">
    <label for="options">Options:</label>
    <div *ngFor="let option of options">
        <label>
            <input type="checkbox"
                   name="options"
                   value="{{option.value}}"
                   [(ngModel)]="option.checked"/>
            {{option.name}}
        </label>
    </div>
</div>

// my.component.ts

@Component({ moduleId:module.id, templateUrl:'my.component.html'})

export class MyComponent {
  options = [
    {name:'OptionA', value:'1', checked:true},
    {name:'OptionB', value:'2', checked:false},
    {name:'OptionC', value:'3', checked:true}
  ]

  get selectedOptions() { // right now: ['1','3']
    return this.options
              .filter(opt => opt.checked)
              .map(opt => opt.value)
  }
}

Solution 2 - Json

I have find a solution thanks to Gunter! Here is my whole code if it could help anyone:

<div class="form-group">
            <label for="options">Options :</label>
            <div *ngFor="#option of options; #i = index">
                <label>
                    <input type="checkbox"
                           name="options"
                           value="{{option}}"
                           [checked]="options.indexOf(option) >= 0"
                           (change)="updateCheckedOptions(option, $event)"/>
                    {{option}}
                </label>
            </div>
        </div>

Here are the 3 objects I'm using:

options = ['OptionA', 'OptionB', 'OptionC'];
optionsMap = {
        OptionA: false,
        OptionB: false,
        OptionC: false,
};
optionsChecked = [];

And there are 3 useful methods:

1. To initiate optionsMap:

initOptionsMap() {
    for (var x = 0; x<this.order.options.length; x++) {
        this.optionsMap[this.options[x]] = true;
    }
}

2. to update the optionsMap:

updateCheckedOptions(option, event) {
   this.optionsMap[option] = event.target.checked;
}

3. to convert optionsMap into optionsChecked and store it in options before sending the POST request:

updateOptions() {
    for(var x in this.optionsMap) {
        if(this.optionsMap[x]) {
            this.optionsChecked.push(x);
        }
    }
    this.options = this.optionsChecked;
    this.optionsChecked = [];
}

Solution 3 - Json

create a list like :-

this.xyzlist = [
  {
    id: 1,
    value: 'option1'
  },
  {
    id: 2,
    value: 'option2'
  }
];

Html :-

<div class="checkbox" *ngFor="let list of xyzlist">
            <label>
              <input formControlName="interestSectors" type="checkbox" value="{{list.id}}" (change)="onCheckboxChange(list,$event)">{{list.value}}</label>
          </div>

then in it's component ts :-

onCheckboxChange(option, event) {
     if(event.target.checked) {
       this.checkedList.push(option.id);
     } else {
     for(var i=0 ; i < this.xyzlist.length; i++) {
       if(this.checkedList[i] == option.id) {
         this.checkedList.splice(i,1);
      }
    }
  }
  console.log(this.checkedList);
}

Solution 4 - Json

<input type="checkbox" name="options" value="option" (change)="updateChecked(option, $event)" /> 

export class MyComponent {
  checked: boolean[] = [];
  updateChecked(option, event) {
    this.checked[option]=event; // or `event.target.value` not sure what this event looks like
  }
}

Solution 5 - Json

I have encountered the same problem and now I have an answer I like more (may be you too). I have bounded each checkbox to an array index.

First I defined an Object like this:

SelectionStatusOfMutants: any = {};

Then the checkboxes are like this:

<input *ngFor="let Mutant of Mutants" type="checkbox"
[(ngModel)]="SelectionStatusOfMutants[Mutant.Id]" [value]="Mutant.Id" />

As you know objects in JS are arrays with arbitrary indices. So the result are being fetched so simple:

Count selected ones like this:

let count = 0;
    Object.keys(SelectionStatusOfMutants).forEach((item, index) => {
        if (SelectionStatusOfMutants[item])
            count++;
    });

And similar to that fetch selected ones like this:

let selecteds = Object.keys(SelectionStatusOfMutants).filter((item, index) => {
        return SelectionStatusOfMutants[item];
    });

You see?! Very simple very beautiful. TG.

Solution 6 - Json

Here's a solution without map, 'checked' properties and FormControl.

app.component.html:

<div *ngFor="let item of options">
  <input type="checkbox" 
  (change)="onChange($event.target.checked, item)"
  [checked]="checked(item)"
>
  {{item}}
</div>

app.component.ts:

  options = ["1", "2", "3", "4", "5"]
  selected = ["1", "2", "5"]

  // check if the item are selected
  checked(item){
    if(this.selected.indexOf(item) != -1){
      return true;
    }
  }
  
  // when checkbox change, add/remove the item from the array
  onChange(checked, item){
    if(checked){
    this.selected.push(item);
    } else {
      this.selected.splice(this.selected.indexOf(item), 1)
    }
  }

DEMO

Solution 7 - Json

I hope this would help someone who has the same problem.

templet.html

<form [formGroup] = "myForm" (ngSubmit) = "confirmFlights(myForm.value)">
  <ng-template ngFor [ngForOf]="flightList" let-flight let-i="index" >
     <input type="checkbox" [value]="flight.id" formControlName="flightid"
         (change)="flightids[i]=[$event.target.checked,$event.target.getAttribute('value')]" >
  </ng-template>
</form>

component.ts

flightids array will have another arrays like this [ [ true, 'id_1'], [ false, 'id_2'], [ true, 'id_3']...] here true means user checked it, false means user checked then unchecked it. The items that user have never checked will not be inserted to the array.

flightids = []; 
confirmFlights(value){  
    //console.log(this.flightids);

    let confirmList = [];
    this.flightids.forEach(id => {
      if(id[0]) // here, true means that user checked the item 
        confirmList.push(this.flightList.find(x => x.id === id[1]));
    });
    //console.log(confirmList);

}

Solution 8 - Json

In Angular 2+ to 9 using Typescript

Source Link

enter image description here

we can use an object to bind multiple Checkbox

  checkboxesDataList = [
	{
	  id: 'C001',
	  label: 'Photography',
	  isChecked: true
	},
	{
	  id: 'C002',
	  label: 'Writing',
	  isChecked: true
	},
	{
	  id: 'C003',
	  label: 'Painting',
	  isChecked: true
	},
	{
	  id: 'C004',
	  label: 'Knitting',
	  isChecked: false
	},
	{
	  id: 'C004',
	  label: 'Dancing',
	  isChecked: false
	},
	{
	  id: 'C005',
	  label: 'Gardening',
	  isChecked: true
	},
	{
	  id: 'C006',
	  label: 'Drawing',
	  isChecked: true
	},
	{
	  id: 'C007',
	  label: 'Gyming',
	  isChecked: false
	},
	{
	  id: 'C008',
	  label: 'Cooking',
	  isChecked: true
	},
	{
	  id: 'C009',
	  label: 'Scrapbooking',
	  isChecked: false
	},
	{
	  id: 'C010',
	  label: 'Origami',
	  isChecked: false
	}
  ]

In HTML Template use

  <ul class="checkbox-items">
    <li *ngFor="let item of checkboxesDataList">
      <input type="checkbox" [(ngModel)]="item.isChecked" (change)="changeSelection()">{{item.label}}
    </li>
  </ul>

To get selected checkboxes, add the following method in class

  // Selected item
  fetchSelectedItems() {
	this.selectedItemsList = this.checkboxesDataList.filter((value, index) => {
	  return value.isChecked
	});
  }
  
  // IDs of selected item
  fetchCheckedIDs() {
	this.checkedIDs = []
	this.checkboxesDataList.forEach((value, index) => {
	  if (value.isChecked) {
		this.checkedIDs.push(value.id);
	  }
	});
  }

Solution 9 - Json

  1. I have just simplified little bit for those whose are using list of value Object. XYZ.Comonent.html

    <div class="form-group">
            <label for="options">Options :</label>
            <div *ngFor="let option of xyzlist">
                <label>
                    <input type="checkbox"
                           name="options"
                           value="{{option.Id}}"
                           
                           (change)="onClicked(option, $event)"/>
                    {{option.Id}}-- {{option.checked}}
                </label>
            </div>
            <button type="submit">Submit</button>
        </div> 
    

** XYZ.Component.ts**.

  1. create a list -- xyzlist.

  2. assign values, I am passing values from Java in this list.

  3. Values are Int-Id, boolean -checked (Can Pass in Component.ts).

  4. Now to get value in Componenet.ts.

    xyzlist;//Just created a list
    onClicked(option, event) {
        console.log("event  " + this.xyzlist.length);
        console.log("event  checked" + event.target.checked);
        console.log("event  checked" + event.target.value);
        for (var i = 0; i < this.xyzlist.length; i++) {
            console.log("test --- " + this.xyzlist[i].Id;
            if (this.xyzlist[i].Id == event.target.value) {
                this.xyzlist[i].checked = event.target.checked;
            }
            console.log("after update of checkbox" + this.xyzlist[i].checked);
    
        }
    

Solution 10 - Json

I just faced this issue, and decided to make everything work with as less variables as i can, to keep workspace clean. Here is example of my code

<input type="checkbox" (change)="changeModel($event, modelArr, option.value)" [checked]="modelArr.includes(option.value)" />

Method, which called on change is pushing value in model, or removing it.

public changeModel(ev, list, val) {
  if (ev.target.checked) {
    list.push(val);
  } else {
    let i = list.indexOf(val);
    list.splice(i, 1);
  }
}

Solution 11 - Json

@ccwasden solution above works for me with a small change, each checkbox must have a unique name otherwise binding wont works

<div class="form-group">
    <label for="options">Options:</label>
    <div *ngFor="let option of options; let i = index">
        <label>
            <input type="checkbox"
                   name="options_{{i}}"
                   value="{{option.value}}"
                   [(ngModel)]="option.checked"/>
            {{option.name}}
        </label>
    </div>
</div>

// my.component.ts

@Component({ moduleId:module.id, templateUrl:'my.component.html'})

export class MyComponent {
  options = [
    {name:'OptionA', value:'1', checked:true},
    {name:'OptionB', value:'2', checked:false},
    {name:'OptionC', value:'3', checked:true}
  ]

  get selectedOptions() { // right now: ['1','3']
    return this.options
              .filter(opt => opt.checked)
              .map(opt => opt.value)
  }
}

and also make sur to import FormsModule in your main module

import { FormsModule } from '@angular/forms';


imports: [
    FormsModule
  ],

Solution 12 - Json

Since I spent a long time solving a similar problem, I'm answering to share my experience. My problem was the same, to know, getting many checkboxes value after a specified event has been triggered. I tried a lot of solutions but for me the sexiest is using ViewChildren.

import { ViewChildren, QueryList } from '@angular/core';

/** Get handle on cmp tags in the template */
@ViewChildren('cmp') components: QueryList<any>;

ngAfterViewInit(){
    // print array of CustomComponent objects
    console.log(this.components.toArray());
}

Found here: https://stackoverflow.com/a/40165639/4775727

Potential other solutions for ref, there are a lot of similar topic, none of them purpose this solution...:

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionYannick MorelView Question on Stackoverflow
Solution 1 - JsonccwasdenView Answer on Stackoverflow
Solution 2 - JsonYannick MorelView Answer on Stackoverflow
Solution 3 - JsonAlok KambojView Answer on Stackoverflow
Solution 4 - JsonGünter ZöchbauerView Answer on Stackoverflow
Solution 5 - JsonConductedCleverView Answer on Stackoverflow
Solution 6 - JsonDawnbView Answer on Stackoverflow
Solution 7 - JsonJames SungView Answer on Stackoverflow
Solution 8 - JsonCode SpyView Answer on Stackoverflow
Solution 9 - JsonGourav BhatiaView Answer on Stackoverflow
Solution 10 - Jsontv1stView Answer on Stackoverflow
Solution 11 - JsonSyed WaqasView Answer on Stackoverflow
Solution 12 - Json4x10mView Answer on Stackoverflow