3

I am using the <md-checkbox> with the 'indeterminate' attribute provided by Angular Material to update an array based on the checkboxes selected. However, the Array is only updated based on ng-click, not on ng-change. Therefore, checking the "Select All" item, will not insert the values into the array.

Consider this codepen.

How can I update the addData function based on ng-change?

Rafael code
  • 289
  • 1
  • 3
  • 13

1 Answers1

3
  • ng-change does require ng-model but you actually only need a model for this example
  • you have 3 arrays basically holding the same items, you can do with just one
  • add a selected property on each item and use this as model
  • filter the array on items that are selected by using https://docs.angularjs.org/api/ng/filter/filter

Controller:

controller('AppCtrl', function($scope, $filter) {
  $scope.items = [{num: 1},{num: 2}, {num: 3}, {num: 4},{num: 5}];

  $scope.isIndeterminate = function() {
    var selected = $filter('filter')($scope.items, {selected: true}).length;
    console.log(selected);
    return selected !== 0 && selected !== $scope.items.length;
  };

  $scope.allChecked = function() {
   return $filter('filter')($scope.items, {selected: true}).length === $scope.items.length;  
  };

  $scope.toggleAll = function() {
    var selected = $filter('filter')($scope.items, {selected: true}).length;
    var newSelected = selected < $scope.items.length;
    angular.forEach($scope.items, function(item) {
      item.selected = newSelected;   
    });
  };
});

Markup:

  <div>
    <fieldset class="demo-fieldset">
      <legend class="demo-legend">Using
        <md-checkbox> with the 'indeterminate' attribute </legend>
      <div layout="row" layout-wrap="" flex="">
        <div flex-xs="" flex="50">
          <md-checkbox aria-label="Select All" md-indeterminate="isIndeterminate()" ng-click="toggleAll()" ng-checked="allChecked()">
            <span ng-if="isChecked()">Un-</span>Select All
          </md-checkbox>
        </div>
        <div class="demo-select-all-checkboxes" flex="100" ng-repeat="item in items">
          <md-checkbox ng-model="item.selected">
            {{ item.num }}
          </md-checkbox>
        </div>
      </div>
    </fieldset>
    <div ng-repeat="data in items | filter: {selected: true}" style="display: inline-block">
       {{data.num}},
    </div>
  </div>

Adapted codepen: http://codepen.io/kuhnroyal/pen/gMLGxL

Edit per comment: http://codepen.io/kuhnroyal/pen/ZOBaNO

kuhnroyal
  • 7,188
  • 1
  • 34
  • 47
  • Thanks, this is the correct answer to the question asked. Today, however, the client changed their demands, wanting to select several items based on one checkbox. Consider [this codepen](http://codepen.io/rafaelcode/pen/aZBVPJ). What they want is when you select "vegetable", the list underneath will display "carrot, cucumber, potato" etc. Can that be done with the same approach? – Rafael code Jun 22 '16 at 13:24