KO - Templates
by Darksbane
HTML
<script type="text/html" id="default-template">
<ul class="deckContents" data-bind="foreach:sortedItems">
<li>
<div class="left fixedWidth" data-bind="text:name"></div>
<div class="left fixedWidth" data-bind="text:cost"></div>
<div class="left fixedWidth" data-bind="text:category"></div>
</li>
</ul>
</script>
<script type="text/html" id="category-template">
<ul class="deckContents" data-bind="foreach:sortedItems">
<li>
<!-- ko if: $root.outputCategory($index()) -->
<div data-bind="text:category"></div>
<!-- /ko -->
<span class="indented" data-bind="text:name"></span>
<span class="indented" data-bind="text:cost"></span>
<span class="indented" data-bind="text:category"></span>
</li>
</ul>
</script>
<div class='liveExample'>
<p>Your values:</p>
<div data-bind='template: { name: currentTemplate, data: $data}'></div>
<select data-bind="options: sortTypes, value:sortType"></select>
<button data-bind="click:addchicken">add chicken</button>
</div>
CSS
body { font-family: arial; font-size: 14px; }
.liveExample { padding: 1em; background-color: #EEEEDD; border: 1px solid #CCC; max-width: 655px; }
.liveExample input { font-family: Arial; }
.liveExample b { font-weight: bold; }
.liveExample p { margin-top: 0.9em; margin-bottom: 0.9em; }
.liveExample select[multiple] { width: 100%; height: 8em; }
.liveExample h2 { margin-top: 0.4em; }
.left {float:left}
.fixedWidth{width:100px}
.indented{margin:15px}
JavaScript
var categoryPriority = ["Fruit", "Meat", "Dairy"]
function compare(l,r){
if(l > r) return 1;
if(l < r) return -1;
return 0;
}
var BetterListModel = function () {
var self = this;
food = [
{
"name":"Apple",
"quantity":"3",
"category":"Fruit",
"cost":"$1",
},{
"name":"Ice Cream",
"quantity":"1",
"category":"Dairy",
"cost":"$6",
},{
"name":"Pear",
"quantity":"2",
"category":"Fruit",
"cost":"$2",
},{
"name":"Beef",
"quantity":"1",
"category":"Meat",
"cost":"$3",
},{
"name":"Milk",
"quantity":"5",
"category":"Dairy",
"cost":"$3",
}];
self.allItems = ko.observableArray(food);
self.sortType = ko.observable("Name");
self.sortTypes = ko.observableArray(["Name", "Cost", "Category"])
self.addchicken = function(){
self.allItems().push({
"name":"chicken",
"quantity":"5",
"category":"Meat",
"cost":"$3",
});
}
self.currentTemplate= ko.computed(function(){
return self.sortType() === 'Category' ? 'category-template' : 'default-template';
});
self.outputCategory = function(index){ var items = self.sortedItems(); return index==0 || items[index-1].category != items[index].category};
self.sortedItems = ko.computed(function(){
return self.allItems.sort(function(l, r){
var key = self.sortType().toLowerCase();
if(key =="category"){
result = compare(categoryPriority.indexOf(l.category), categoryPriority.indexOf(r.category))
return result != 0 ? result : compare(l.name, r.name);
}
return compare(l[key], r[key]);
});
});
};
ko.applyBindings(new BetterListModel());