Skip to content

Instantly share code, notes, and snippets.

@jakeatoms
Last active December 22, 2015 06:39
Show Gist options
  • Save jakeatoms/6432628 to your computer and use it in GitHub Desktop.
Save jakeatoms/6432628 to your computer and use it in GitHub Desktop.
simple knockoutjs custom binding for sorting a table of data. View in action (with markup) here: http://jsfiddle.net/norepro/bVB96/
ko.bindingHandlers.sort = {
init: function (element, valueAccessor) {
var asc = false;
ko.utils.registerEventHandler(element, 'click', function (event) {
var value = ko.utils.unwrapObservable(valueAccessor()),
sortBy = event.target.getAttribute('data-sort-by'),
list = value.list,
alwaysBy = value.alwaysBy;
asc = !asc;
list.sort(function (left, right) {
var leftValue = left[sortBy],
rightValue = right[sortBy];
if (typeof leftValue === 'string' && typeof rightValue === 'string') {
leftValue = leftValue.toLowerCase();
rightValue = rightValue.toLowerCase();
}
var x = 0;
if (leftValue < rightValue) {
x = -1;
} else if (leftValue > rightValue) {
x = 1;
}
x = asc ? x : -1 * x;
if (alwaysBy) {
x = x ? x : left[alwaysBy] - right[alwaysBy];
}
return x;
});
});
}
};
var viewModel = function () {
var self = this,
//any of these properties could easily be observables
testData = [{
name: 'Baggins, Bilbo',
number: '42',
amountDue: 111,
balance: 121,
dueDate: new Date(2013, 12, 23),
isInstitution: false,
isDue: true
}, {
name: 'Grey, Gandalf',
number: '54',
amountDue: 00,
balance: 121,
dueDate: '',
isInstitution: false,
isDue: false
}, {
name: 'Mordor',
number: '666',
amountDue: 66,
balance: 666,
dueDate: new Date(2010, 10, 18),
isInstitution: true,
isDue: true
}];
self.accounts = ko.observableArray(testData);
return {
accounts: self.accounts
};
}()
ko.applyBindings(viewModel);
table.table tr td {
vertical-align: middle;
}
table.table tr:nth-of-type(odd) {
background: #eee;
}
table.table th {
background: #1c93bc;
color: white;
font-weight: bold;
}
table.table th[data-sort-by]{
cursor: pointer;
}
table.table td, .table th {
text-align: left;
padding: 6px;
}
<table class="table">
<thead data-bind="sort: { list: accounts, alwaysBy: 'dueDate' }">
<tr>
<th data-sort-by="name">Customer name</th>
<th data-sort-by="amountDue">Amount due</th>
<th data-sort-by="balance">Balance</th>
<th data-sort-by="dueDate">Due date</th>
</tr>
</thead>
<tbody data-bind="foreach: accounts">
<tr>
<td> <span data-bind="text: name"></span>
<!-- ko ifnot: isInstitution -->
<br /> <span data-bind="text: number"></span>
<!-- /ko -->
</td>
<td data-bind="text: amountDue"></td>
<td data-bind="text: balance"></td>
<td>
<!-- ko if: isDue --> <span data-bind="text: dueDate"></span>
<!-- /ko -->
<!-- ko ifnot: isDue --> <span class="alert-success">
No payment due
</span>
<!-- /ko -->
</td>
</tr>
</tbody>
</table>
@jakeatoms
Copy link
Author

I'm open to a way to do this without jQuery so long as it's simple :)

@jakeatoms
Copy link
Author

forgot about the built in registerEventHandler with knockout. Now there is no dependency on jquery.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment