Angular Multi-Checkbox Array in ng-repeat


I'm trying to build part of a simple form with Angular yet struggling with a small part of it.

Part of the form has a 'Divisions' section with a list of checkboxes that are dynamically populated from an API call. The user then can select anywhere from 1 to 7 different checkboxes to select which 'Division' the form belongs to.

Then when the user submits the form it should post JSON looking like Divisions: 'div1 div2 div3 div4'

The issue I'm having is for some reason I can't select more than one checkbox at a time. If I try and select another one, it unchecks the first one I selected.

This is the code I'm working with.

        <label>Divisions Participating*</label>
        <div class="radio-check-wrap">
            <ul class="radio-check-group">
                <li ng-repeat="d in divisions">
                    <input type="checkbox" 
                           class="" id="div{{$index}}" 
                           name="div{{$index}}" />
                    <label for="div{{$index}}">{{d.Description}}</label>

Also for clarification there is a $scope.divisions = Api.divisions.query(); and a $scope.tradeshow = {} in the controller.

Any idea why I'm unable to select more than one checkbox at a time?

Problem courtesy of: Mike Fisher


Your checkboxes are storing the selected value on the same scope object (they all have the same ng-model), so as the check is changed, the ng-model is updated to reflect the newly checked box (which removes the check from the previous).

Here's an answer that shows you the two ways to approach the problem: How do I bind to list of checkbox values with AngularJS?

I made the changes for the object array as input data:

You need to store the "selected" value on the item, then compute which are selected. So I've changed your checkboxes to this:

<input type="checkbox" ng-model="d.selected" class="" id="div{{$index}}" name="selectedDivisions[]" />

I've updated your code with methods for getting and storing the selected values:

$scope.divisions = [
  { Description: 'test1' },
  { Description: 'test2' },
  { Description: 'test3' },
  { Description: 'test4' }

// selected divisions
$scope.selection = [];

// helper method
$scope.selectedDivisions = function selectedDivisions() {
  return filterFilter($scope.divisions, { selected: true });

// watch divisions for changes
$scope.$watch('divisions|filter:{selected:true}', function (nv) {
  $scope.selection = (division) {
    return division.Description;
}, true);
Solution courtesy of: comradburk


this seems to do what you want, an array of checkboxes all backed by a single model:

Discussion courtesy of: FriendlyMikhail

This recipe can be found in it's original form on Stack Over Flow.