table filter knockout binding
by wwwroot
HTML
<script src="http://knockoutjs.com/downloads/knockout-3.0.0.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
<table class="table">
<thead>
<tr>
<th>name</th>
<th>category</th>
<th>price</th>
</tr>
<tr>
<th>
<select data-bind="columnFilter: { data: items, filter: 'name', caption: 'all' }, value: nameFilter" />
</th>
<th>
<select data-bind="columnFilter: { data: items, filter: 'category', caption: '--' }" />
</th>
<th>
<select data-bind="columnFilter: { data: items, filter: 'price', caption: '--' }" />
</th>
</tr>
</thead>
<tbody data-bind="foreach: items">
<tr>
<td data-bind="text: name"></td>
<td data-bind="text: category"></td>
<td data-bind="text: price"></td>
</tr>
</tbody>
</table>
CSS
table {
max-width: 100%;
background-color: transparent;
border-collapse: collapse;
border-spacing: 0;
}
.table {
width: 100%;
margin-bottom: 20px;
}
.table th, .table td {
padding: 8px;
line-height: 20px;
text-align: left;
vertical-align: top;
border-top: 1px solid #dddddd;
}
.table th {
font-weight: bold;
}
.table thead th {
vertical-align: bottom;
}
.table caption + thead tr:first-child th, .table caption + thead tr:first-child td, .table colgroup + thead tr:first-child th, .table colgroup + thead tr:first-child td, .table thead:first-child tr:first-child th, .table thead:first-child tr:first-child td {
border-top: 0;
}
.table tbody + tbody {
border-top: 2px solid #dddddd;
}
.table .table {
background-color: #ffffff;
}
.table-condensed th, .table-condensed td {
padding: 4px 5px;
}
JavaScript
ko.bindingHandlers.columnFilter = {
init: function (element, valueAccessor, allBindings) {
var options = valueAccessor();
var data = ko.utils.unwrapObservable(options.data);
var caption = options.caption || '';
$(element).append($('<option></option>').val("_0_").html(caption));
var items = options.filter ? _.map(data, options.filter) : data;
_.forEach(_.uniq(items).sort(), function (item) {
$(element).append($('<option></option>').val(item).html(item));
});
}
};
var JSONdataFromServer = [{
"name": "Peach",
"category": "Fruits",
"price": 1
}, {
"name": "Plum",
"category": "Fruits",
"price": 0.75
}, {
"name": "Donut",
"category": "Bread",
"price": 1.5
}, {
"name": "Milk",
"category": "Dairy",
"price": 4.50
}, {
"name": "Milk",
"category": "Dairy",
"price": 1.99
}, {
"name": "Beer",
"category": "Alco",
"price": 4.50
}];
var viewModel = {
categories: ["Bread", "Dairy", "Fruits", "Vegetables"],
source: ko.observableArray(JSONdataFromServer),
items: ko.observableArray(JSONdataFromServer),
nameFilter: ko.observable()
};
viewModel.nameFilter.subscribe(function (value) {
if (value != "_0_") {
var arr = _.filter(viewModel.items(), {
'name': value
});
console.log(arr);
}
});
ko.applyBindings(viewModel);