I have a sorted, static list to display with KO, and wanted to show category headers whenever the category changed (since the list is sorted by category). I'm still genning up on KO, is this the "KO" way to do this, or is there a better approach? In particular the syntax to access the previous item in the list is a bit hairy, which makes me suspect I'm missing a feature that would improve this. :-)
Live Copy | Source
HTML:
<table>
<tbody data-bind="foreach: items">
<!-- ko if: $index() === 0 || $parent.items()[$index() - 1].category() !== category() -->
<tr class="category">
<td colspan="2" data-bind="text: category"></td>
</tr>
<!-- /ko -->
<tr>
<td data-bind="text: item"></td>
<td class="num" data-bind="text: quantity"></td>
</tr>
</tbody>
</table>
JavaScript: (Obviously this is just a quick and dirty VM for the example)
function Item(category, item, quantity) {
this.category = ko.observable(category);
this.item = ko.observable(item);
this.quantity = ko.observable(quantity);
}
var vm = {
items: ko.observableArray([
new Item("Fruit", "Apples", 27),
new Item("Fruit", "Oranges", 17),
new Item("Fruit", "Kiwis", 3),
new Item("Vegetables", "Celery", 16),
new Item("Vegetables", "Carrots", 72),
new Item("Sundries", "Toothpaste", 10),
new Item("Sundries", "Washing-up liquid", 8)
])
};
ko.applyBindings(vm, document.body);
Result: (there's some trivial CSS that isn't relevant)
If you modify your observable array and construct it to contain an array of items with associated quantities you can do the following:
JS:
function Item(category, itemList) {
this.category = ko.observable(category);
this.itemList = ko.observableArray(itemList);
}
var vm = {
items: ko.observableArray([
new Item("Fruit", [{"item": "Apples", "qty": 27 },
{"item": "Oranges", "qty": 17},
{"item": "Kiwis", "qty": 3}]),
new Item("Vegetables", [{"item": "Celery", "qty": 16},
{"item": "Carrots", "qty": 72}]),
new Item("Sundries", [{"item": "Toothpaste", "qty": 10},
{"item": "Washing-up liquid", "qty": 8}]),
])
};
ko.applyBindings(vm, document.body);
HTML:
<table>
<tbody data-bind="foreach: items">
<tr class="category">
<td colspan="2" data-bind="text: category"></td>
</tr>
<!-- ko foreach: itemList -->
<tr>
<td data-bind="text: item"></td>
<td class="num" data-bind="text: qty"></td>
</tr>
<!-- /ko -->
</tbody>
</table>
See JSFiddle here: http://jsfiddle.net/y4yPv/2/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With