checkedInArray and allItemsSelected example
HTML
<div>
<input type="checkbox" data-bind="checked: allItemsSelected" />
Check All
</div>
<div data-bind="foreach: items">
<div>
<input type="checkbox" data-bind="checkedInArray: { array: $parent.selectedItems, value: $data }" />
<span data-bind="text: name"></span>
</div>
</div>
JavaScript
// ko.utils.addOrRemoveItem isn't included until version 2.3.0
if (!ko.utils.addOrRemoveItem) {
ko.utils.addOrRemoveItem = function(array, value, included) {
var existingEntryIndex = array.indexOf ? array.indexOf(value) : ko.utils.arrayIndexOf(array, value);
if (existingEntryIndex < 0) {
if (included)
array.push(value);
} else {
if (!included)
array.splice(existingEntryIndex, 1);
}
};
}
ko.bindingHandlers.checkedInArray = {
init: function (element, valueAccessor) {
ko.utils.registerEventHandler(element, "click", function() {
var options = ko.utils.unwrapObservable(valueAccessor()),
array = options.array, // don't unwrap array because we want to update the observable array itself
value = ko.utils.unwrapObservable(options.value),
checked = element.checked;
ko.utils.addOrRemoveItem(array, value, checked);
});
},
update: function (element, valueAccessor) {
var options = ko.utils.unwrapObservable(valueAccessor()),
array = ko.utils.unwrapObservable(options.array),
value = ko.utils.unwrapObservable(options.value);
element.checked = ko.utils.arrayIndexOf(array, value) >= 0;
}
};
function ViewModel() {
for (var items = [], i = 0; i < 500; i++) {
items[i] = {
id: i,
name: 'Item ' + i
};
}
this.items = ko.observableArray(items);
this.selectedItems = ko.observableArray();
this.allItemsSelected = ko.computed({
read: function() {
return this.selectedItems().length === this.items().length;
},
write: function(value) {
this.selectedItems(value ? this.items.slice(0) : [] );
},
owner: this
});
}
ko.applyBindings(new ViewModel());