Indeterminate Checkbox Directive
by Arvind Pal
HTML
<div data-ng-repeat="person in model.people" class="person">
<label>
<input type="checkbox" data-indeterminate-checkbox data-child-list="person.fruits" data-property="eaten" data-ng-model="person.allEaten"> {{person.name}} [All eaten: {{person.allEaten}}]
</label>
<div data-ng-repeat="fruit in person.fruits" class="child-list">
<label>
<input type="checkbox" data-ng-model="fruit.eaten"> {{fruit.type}}
</label>
</div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.js"></script>
CSS
.person {
margin-bottom: 20px;
}
.child-list {
margin-left: 20px;
}
JavaScript
var app = angular.module('combo', []);
app.controller('MainCtrl', ['$scope', function($scope) {
$scope.model = {
allEaten: false,
people: [
{
name: "Bob",
fruits: [
{ type: 'Apple', eaten: false },
{ type: 'Banana', eaten: false },
{ type: 'Pear', eaten: true },
{ type: 'Tomato', eaten: false },
{ type: 'Grapefruit', eaten: true },
]
},
{
name: "Joe",
fruits: [
{ type: 'Apple', eaten: true },
{ type: 'Banana', eaten: true },
{ type: 'Pear', eaten: true },
{ type: 'Tomato', eaten: true },
{ type: 'Grapefruit', eaten: true },
]
}
]
};
}]);
/**
* Directive for an indeterminate (tri-state) checkbox.
* Based on the examples at http://stackoverflow.com/questions/12648466/how-can-i-get-angular-js-checkboxes-with-select-unselect-all-functionality-and-i
*/
app.directive('indeterminateCheckbox', [function() {
return {
scope: true,
require: '?ngModel',
link: function(scope, element, attrs, modelCtrl) {
var childList = attrs.childList;
var property = attrs.property;
// Bind the onChange event to update children
element.bind('change', function() {
scope.$apply(function () {
var isChecked = element.prop('checked');
// Set each child's selected property to the checkbox's checked property
angular.forEach(scope.$eval(childList), function(child) {
child[property] = isChecked;
});
});
});
// Watch the children for changes
scope.$watch(childList, function(newValue) {
var hasChecked = false;
var hasUnchecked = false;
// Loop through the children
angular.forEach(newValue,...