Checkbox list con Select All in Knockout JS
In questo esempio, per Knockout JS, mostro come implementare la selezione / deselezione di tutti gli elementi di una lista di checkbox.
Partendo dal precedente Checkbox list in Knockout JS, per prima cosa va aggiunto, nell'html, la voce Seleziona tutti (select all):
questa checkbox è in bind con la proprietà observable, di tipo computed, con nome selectAll:
Il metodo read si occupa di calcolare lo stato, true/false, in funzione del numero di elementi selezionati.
Se il numero degli elementi presenti ( self.items().length ) coincide con gli elementi selezionati ( self.selectedItems().length ), ovvero sono tutti selezionati, ritorno true e la checkbox è selezionata, negli altri casi ritorno false.
Il metodo write viene invocato quando scatta l'evento click sulla checkbox.
In questo caso, prima, per semplicità, cancello tutti gli elementi selezionati ( self.selectedItems.removeAll() ), poi ciclo su tutti gli elementi e li seleziono ( selected.push(item.id) ), infine li assegno ( ko.utils.arrayPushAll ).
L'html completo è questo:
e il corrispondente JavaScript è questo:
Questo è il risultato:mentre questo è l'esempio funzionante:
Partendo dal precedente Checkbox list in Knockout JS, per prima cosa va aggiunto, nell'html, la voce Seleziona tutti (select all):
HTML
<div>
<label>
<input type="checkbox" data-bind="checked: selectAll">
<span>Seleziona tutti</span>
</label>
</div>
JavaScript
function CheckboxAllViewModel() {
var self = this;
...
self.selectAll = ko.computed({
read: function () {
return self.items().length === self.selectedItems().length;
},
write: function (newState) {
self.selectedItems.removeAll();
if (newState == true) {
var selected = [];
var items = self.items();
items.forEach(function (item) {
selected.push(item.id);
});
ko.utils.arrayPushAll(self.selectedItems, selected);
}
}
});
}
Se il numero degli elementi presenti ( self.items().length ) coincide con gli elementi selezionati ( self.selectedItems().length ), ovvero sono tutti selezionati, ritorno true e la checkbox è selezionata, negli altri casi ritorno false.
Il metodo write viene invocato quando scatta l'evento click sulla checkbox.
In questo caso, prima, per semplicità, cancello tutti gli elementi selezionati ( self.selectedItems.removeAll() ), poi ciclo su tutti gli elementi e li seleziono ( selected.push(item.id) ), infine li assegno ( ko.utils.arrayPushAll ).
L'html completo è questo:
HTML
<div id="sgart-app-ko-checkbox-list" class="app-ko">
<div>
<label>
<input type="checkbox" data-bind="checked: selectAll">
<span>Seleziona tutti</span>
</label>
</div>
<ul data-bind="foreach: items">
<li>
<label>
<input type="checkbox" data-bind="checkedValue: id, checked: $parent.selectedItems">
<span data-bind="text:description"></span>
</label>
</li>
</ul>
<div>Selected id: <span data-bind="text: selectedItems"></span></div>
<!-- visualizza il JSON del view-moel -->
<div style="margin-top:20px;">Json: <span data-bind="text: ko.toJSON($root)"></span></div>
</div>
JavaScript
// view-model
function CheckboxAllViewModel() {
var self = this;
self.items = ko.observableArray();
self.selectedItems = ko.observableArray();
self.selectAll = ko.computed({
read: function () {
return self.items().length === self.selectedItems().length;
},
write: function (newState) {
self.selectedItems.removeAll();
if (newState == true) {
var selected = [];
var items = self.items();
items.forEach(function (item) {
selected.push(item.id);
});
ko.utils.arrayPushAll(self.selectedItems, selected);
}
}
});
}
// eseguo il codice dopo il load del DOM
document.addEventListener("DOMContentLoaded", function () {
// dati iniziali
var exampleItems = [
{ id: 1, description: "Scelta A" },
{ id: 21, description: "Scelta B" },
{ id: 4, description: "Scelta C" },
];
// istanzio un nuovo view-model
var vm = new CheckboxAllViewModel();
ko.utils.arrayPushAll(vm.items, exampleItems);
// recupero il template della view
var view = document.getElementById("sgart-app-ko-checkbox-list");
// binding tra view e view-model
ko.applyBindings(vm, view);
// eventuale preselezione degli item
// vm.selectedItems.push(21);
});
Selected id:
Json:
Da notare:
- l'uso del metodo ko.utils.arrayPushAll(<observableArray>, <array>) per caricare in un solo colpo e in modo più efficiente, un intero array in una proprietà observableArray
- il metodo <observableArray>.removeAll() per rimuovere tutti gli elementi da un observableArray
- oppure il metodo ko.toJSON($root) per visualizzare una rappresntazione JSON del view-model
- in fine ko.computed per creare delle proprietà observable calcolate