S'pose we wanted to display a table of cities. Just create a view model for the data:
class City constructor: (@view, row) -> @population = ko.observable row.population @countryName = row.country_name @cityName = row.city_name class @CitiesModel constructor: -> tableOptions = recordWord: 'city' recordWordPlural: 'cities' sortDir: 'desc' sortField: 'population' perPage: 15 unsortedClass: 'glyphicon glyphicon-sort' ascSortClass: 'glyphicon glyphicon-sort-by-attributes' descSortClass: 'glyphicon glyphicon-sort-by-attributes-alt' @table = new DataTable [], tableOptions @table.loading true req = new XMLHttpRequest() req.open 'GET', '/api/cities', true req.onload = => if req.status >= 200 and req.status < 400 response = JSON.parse req.responseText rows = response.results.map (row) => new City @, row @table.rows rows @table.loading false else alert "Error communicating with server" @table.loading false req.onerror = => alert "Error communicating with server" @table.loading false req.send() ko.applyBindings @
And a table, like so:
<div data-bind="with: table"> <div class="pull-right"> <strong>Results per page</strong> <select data-bind="options: [10,25,50], value: perPage"></select> </div> <input type="text" data-bind="textInput: filter" placeholder="Search"/> <table class="table table-striped table-bordered"> <thead> <tr> <th style="width: 34%;" data-bind="click: toggleSort('cityName')" class="sortable"> City <i data-bind="css: sortClass('cityName')"></i> </th> <th style="width: 33%;" data-bind="click: toggleSort('countryName')" class="sortable"> Country <i data-bind="css: sortClass('countryName')"></i> </th> <th style="width: 33%;" data-bind="click: toggleSort('population')" class="sortable"> Population <i data-bind="css: sortClass('population')"></i> </th> </tr> </thead> <tbody> <tr data-bind="visible: showNoData"> <td colspan="3" class="aligncenter"> This table has no data. </td> </tr> <tr data-bind="visible: showLoading"> <td colspan="3" class="aligncenter"> <i data-bind="css: {'icon-spin': showLoading}" class="icon-spinner"></i> Loading data... </td> </tr> <!-- ko foreach: {data: pagedRows, as: '$row'} --> <tr> <td data-bind="text: $row.cityName"></td> <td data-bind="text: $row.countryName"></td> <td data-bind="text: $row.population"></td> </tr> <!-- /ko --> </tbody> </table> <span data-bind="text: recordsText" class="label label-info pull-right"></span> <div data-bind="visible: pages() > 1"> <ul class="pagination"> <li data-bind="css: leftPagerClass, click: prevPage"> <a href="#">«</a> </li> <!-- ko foreach: {data: (new Array(pages()))} --> <li data-bind="css: $parent.pageClass($index() + 1)"> <a href="#" data-bind="text: $index() + 1, click: $parent.gotoPage($index() + 1)"></a> </li> <!-- /ko --> <li data-bind="css: rightPagerClass, click: nextPage"> <a href="#">»</a> </li> </ul> </div> </div> <script type="text/javascript"> document.addEventListener('DOMContentLoaded', function(){ new CitiesModel(); }); </script>
When instanciating with new DataTable
you have can pass in the following options as the second parameter:
recordWord
city
. Default: record
recordWordPlural
city
as our recordWord, we used cities
for recordWordPlural. Default: recordWord + 's'
sortDir
'asc'
sortField
table.rows
will be maintained and sorting will be disabled.perPage
15
unsortedClass
descSortClass
ascSortClass
th
elements indicating the direction of sorting. Set to '' if you would rather have no icons. Default: ''
for eachAdditionally, you can define the match
function on the row class, and the datatable will use it for filtering. If left undefined (as in the example above), the DataTable will automatically search all columns defined on the row. E.g:
row.match:
(filter) -> @population().toLowerCase().indexOf(filter) >= 0 or @countryName .toLowerCase().indexOf(filter) >= 0 or @cityName .toLowerCase().indexOf(filter) >= 0
Knockout DataTable comes packaged with some advanced filtering. Below is a list of example search terms and the results returned.
cityName:atlanta
cItYnAmE:aTlAnTa
countryName:United cityName:L
Note: as of right now, there is no built-in support for multi-word searching with ':'-delimeted searching
countryname:japan 6