ko.subscribable.fn.filter = function (search, property) {
return ko.computed(function () {
//search and property could be observables
var searchValue = ko.unwrap(search);
var prop = ko.unwrap(property);
return ko.utils.arrayFilter(this(), function (item) {
if (prop) {
//item[prop] could be an observable
var itemProp = ko.unwrap(item[prop]);
return itemProp.toString().indexOf(searchValue) > -1;
} else {
return item.indexOf(searchValue) > -1;
}
});
}, this);
};
ko.subscribable.fn.orderBy = function (propertyName) {
return ko.computed(function () {
var propName = ko.unwrap(propertyName);
if (propName) {
return this().sort(function (a, b) {
var aProp = ko.unwrap(a[propName]);
var bProp = ko.unwrap(b[propName]);
return aProp < bProp ? -1 : aProp > bProp ? 1 : 0;
});
} else {
return this().sort();
}
}, this);
};
ko.subscribable.fn.currency = function (symbol) {
return ko.computed(function () {
//symbol could be an observable
return accounting.formatMoney(this(), ko.unwrap(symbol));
}, this);
};
ko.subscribable.fn.date = function (format) {
return ko.computed(function () {
//format could be an observable
return moment(this()).format(ko.unwrap(format));
}, this);
};
var Dude = function(name, amount, date) {
this.name = ko.observable(name);
this.amount = ko.observable(amount);
this.date = ko.observable(moment(date));
};
var viewModel = {
dudes: ko.observableArray([
new Dude("hercules", 100, "7/16/2005"),
new Dude("rembrandt", 2000, "1/1/2013"),
new Dude("einstein", 42, "9/19/2013"),
new Dude("einbrandt", 3876, "7/4/1776")
]),
search: ko.observable(""),
orderBy: ko.observable("name"),
};
ko.applyBindings(viewModel);
Name filter:
<input type="text" data-bind="value: search, valueUpdate: 'afterkeydown'" />
Order by:
<select data-bind="value: orderBy">
<option value="name">Name</option>
<option value="amount">Amount</option>
<option value="date">Date</option>
</select>
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Amount</th>
<th>Date</th>
</tr>
</thead>
<tbody data-bind="foreach: dudes.filter(search, 'name').orderBy(orderBy)">
<tr>
<td data-bind="text: name"></td>
<td data-bind="text: amount.currency()"></td>
<td data-bind="text: date.date('dddd MMMM Do YYYY')"></td>
</tr>
</tbody>
</table>
External resources loaded into this fiddle: