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:
recordWordcity. Default: recordrecordWordPluralcity as our recordWord, we used cities for recordWordPlural. Default: recordWord + 's'sortDir'asc'sortFieldtable.rows will be maintained and sorting will be disabled.perPage15unsortedClassdescSortClassascSortClassth 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:atlantacItYnAmE:aTlAnTacountryName:United cityName:LNote: as of right now, there is no built-in support for multi-word searching with ':'-delimeted searching
countryname:japan 6