Sortable Table
by zakkarygrahamm
HTML
<div data-bind="foreach: filters">
<input type="button" data-bind="click: $parent.setActiveFilter, value: title"/>
</div>
<br/>
<table>
<thead>
<tr data-bind="foreach: headers">
<th data-bind="click: $parent.sort, text: title"></th>
</tr>
</thead>
<tbody data-bind="foreach: filteredPeople">
<tr>
<td data-bind="text: countryname"></td>
<td data-bind="text: continent"></td>
<td data-bind="text: lifeexpectancy"></td>
<td data-bind="text: schoolingexpected"></td>
<td data-bind="text: schoolingactual"></td>
<td data-bind="text: percapitagdp"></td>
<td data-bind="text: HDIscore"></td>
</tr>
</tbody>
</table>
CSS
th
{
cursor:pointer;
}
JavaScript
var viewModel = function(){
var self = this;
self.people = ko.observableArray([
{countryname:'James',continent:'Smith',age:38},
]);
self.headers = [
{title:'Country',sortPropertyName:'countryname', asc: true, active: false},
{title:'Continent',sortPropertyName:'continent', asc: true, active: false},
{title:'Life expectancy at birth',sortPropertyName:'lifeexpectancy', asc: true, active: false},
{title:'Expected Years of Schooling',sortPropertyName:'schoolingexpected', asc: true, active: false},
];
self.filters = [
{title:'Show All', filter: null},
{title:'Only Smith', filter: function(item){return item.lastName == 'Smith';}},
{title:'Only Jones', filter: function(item){return item.lastName == 'Jones';}},
{title:'Only Adults', filter: function(item){return item.age >= 18; }}
];
self.activeSort = ko.observable(function(){return 0;}); //set the default sort
self.sort = function(header, event){
//if this header was just clicked a second time
if(header.active) {
header.asc = !header.asc; //toggle the direction of the sort
}
//make sure all other headers are set to inactive
ko.utils.arrayForEach(self.headers, function(item){ item.active = false; } );
//the header that was just clicked is now active
header.active = true;//our now-active header
var prop = header.sortPropertyName;
var ascSort = function(a,b){ return a[prop] < b[prop] ? -1 : a[prop] > b[prop] ? 1 : a[prop] == b[prop] ? 0 : 0; };
var descSort = function(a,b){ return a[prop] > b[prop] ? -1 : a[prop] < b[prop] ? 1 : a[prop] == b[prop] ? 0 : 0; };
var sortFunc = header.asc ? ascSort : descSort;
//store the new active sort function
self.activeSort(sortFunc);
};
self.activeFilter = ko.observable(self.filters[0].filter);//set a default filter
...