AngularJS add value of checkboxes to an array

All we need is an easy explanation of the problem, so here it is.

I have this code:

<tr ng-repeat="doc in providers">      
  <td><input type="checkbox" ng-true-value="{{doc.provider.Id}}" ng-false-value="" ng-model="ids"></td> 
</tr>

{{ids}}

i want to get the values of the checkboxes on an array

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

ng-true-value only accepts strings so you’ll need to use a workaround. This has been a feature request for some time. In the meantime, you can do this:

Create an ids object in the controller like:

$scope.ids = {};

and change ng-model to reference a key in that object. You can use the default true/false checkbox values:

<td><input type="checkbox" ng-model="ids[doc.provider.Id]"></td>

Then you can loop over the keys in ids checking for true.

Here is a fiddle

Method 2

I found that this directive provided the functionality I was looking for. The main problem I ran into with the more common solutions is that I have two arrays which I needed to store data compatible with a multi select list. The checklistModel directive provides this very basic functionality and works with multiple models.

Method 3

I will start by saying that I really don’t like the options for doing this in angular. I can’t even say that this is better than the accepted answer, but it does keep the data in the model.

Markup:

<tr ng-repeat='(index, doc) in provider'>
    <td><input type='checkbox' ng-true-value='{{doc.provider.Id}}' ng-model='ids[index]' /></td>
</tr>

<span ng-repeat='id in ids'>{{id}} </span>

Now just $watch the array value and filter when it changes in the controller (make sure to pass the object equality parameter):

$scope.ids = [];

$scope.updateIds = function() {
    $scope.ids = $scope.ids.filter(function(id) {
        return !!id;
    });
};

$scope.$watch('ids', $scope.updateIds, true);

When I started answering this question, I thought the most idiomatic options would be to add an ng-change directive on the input:

<input type='checkbox' ng-true-value='{{doc.provider.Id}}' ng-model='ids[index]' ng-change='updateIds()'/>

Unfortunately this does not work as expected. The UI doesn’t update properly when removing values. I also want to point out that you can do this without the repeat directive:

<input type='checkbox' ng-true-value='1' ng-model='ids.0' />
<input type='checkbox' ng-true-value='2' ng-model='ids.1' />
<input type='checkbox' ng-true-value='3' ng-model='ids.2' />
<input type='checkbox' ng-true-value='4' ng-model='ids.3' />
<input type='checkbox' ng-true-value='5' ng-model='ids.4' />
<input type='checkbox' ng-true-value='6' ng-model='ids.5' />

In this case, the $watch is definitely better than adding the ng-change to each input. Finally, here is a working plunkr. The $watch function does end up running twice each time a box is checked or unchecked, but that’s really how it has to be!

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply