0

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" 
                           ng-model="tradeshow.DivisionLead" 
                           ng-true-value="div{{$index}}" 
                           class="" id="div{{$index}}" 
                           name="div{{$index}}" />
                    <label for="div{{$index}}">{{d.Description}}</label>
                </li>
            </ul>
        </div>

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?

Mike Fisher
  • 913
  • 3
  • 13
  • 27
  • possible duplicate of [How can AngularJS bind to list of checkbox values?](http://stackoverflow.com/questions/14514461/how-can-angularjs-bind-to-list-of-checkbox-values) – Dan Dascalescu Oct 24 '14 at 18:36

2 Answers2

2

this seems to do what you want, an array of checkboxes all backed by a single model: http://vitalets.github.io/checklist-model/

FriendlyMikhail
  • 2,857
  • 23
  • 39
2

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: http://plnkr.co/edit/otVgVMtwUGkIwr2uaSpq?p=preview

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 = nv.map(function (division) {
    return division.Description;
  });
}, true);
Community
  • 1
  • 1
andrew.burk
  • 533
  • 5
  • 9
  • This was great, thanks! However it appears that the JSON I'm sending back needs to be structured differently than expected. It actually needs to be an array of objects. So `Divisions: [{Id: 2},{Id: 4},{Id: 8}]` Your code has a bit of Angular mojo that I'm lost on. Any idea how I'd restructure it to spit it out this way. – Mike Fisher Apr 25 '14 at 17:26
  • 1
    @MikeFisher Are you trying to have arbitrary Id's based on whatever order they show up in? If the Id is part of the division object it's a lot easier, just change what is returned in the watch. I updated the plunk [link]http://plnkr.co/edit/otVgVMtwUGkIwr2uaSpq?p=preview to show how you could return the Id (or any other property on the division object). It's a lot easier if the Id is on the division object as opposed to being an arbitrarily calculated value based on the order. – andrew.burk Apr 28 '14 at 13:32
  • Ok I'm really close. I have it populating as an array of objects. However I need to use this data as part of a larger object to post using `$resource();` The problem is $scope.selection contains the data. I need the data to live in `$scope.tradeshow.Divisions` I've tried changing the `ng-model`, renaming `selection` to `tradeshow.Divisions` yet I'm stumped. What am I missing? – Mike Fisher Apr 28 '14 at 22:09
  • @MikeFisher I updated it so it's now updating a divisions array on a tradeshow object. I also made the change to the return statement in the watch to return exactly how you wanted (you can change the return there to get any property of the division, or the whole object). http://plnkr.co/edit/otVgVMtwUGkIwr2uaSpq?p=preview Hope that helps! – andrew.burk Apr 28 '14 at 22:39