JSFiddle - React, Tailwind, and code Playground
HTML
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css">
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="test" class="container">
<table class="table table-bordered">
<thead>
<tr>
<th>City</th>
<th>Zip</th>
</tr>
</thead>
<tbody data-bind="foreach: items.pagedItems">
<tr>
<td data-bind="text: city"></td>
<td data-bind="text: zip"></td>
</tr>
</tbody>
</table>
<ul class="pager">
<li data-bind="css: {'disabled': !items.prev.enabled()}">
<a href="#" data-bind="click: items.prev">Previous</a>
</li>
<li class="li-loader">
<span>
<span class="ajax-loader" data-bind="css: {active: items.isLoading}"></span>
</span>
</li>
<li data-bind="css: {'disabled': !items.next.enabled()}">
<a href="#" data-bind="click: items.next">Next</a>
</li>
</ul>
</div>
CSS
.pager {
margin-bottom:0;
}
.li-loader {
display:inline-block;
width: 16px;
height: 32px;
}
.pager li.li-loader>span {
border:none;
}
.ajax-loader {
width:16px;
height:11px;
display:inline-block;
}
.ajax-loader.active {
background-image: url(data:image/gif;base64,R0lGODlhEAALAPQAAP///wAAANra2tDQ0Orq6gYGBgAAAC4uLoKCgmBgYLq6uiIiIkpKSoqKimRkZL6+viYmJgQEBE5OTubm5tjY2PT09Dg4ONzc3PLy8ra2tqCgoMrKyu7u7gAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCwAAACwAAAAAEAALAAAFLSAgjmRpnqSgCuLKAq5AEIM4zDVw03ve27ifDgfkEYe04kDIDC5zrtYKRa2WQgAh+QQJCwAAACwAAAAAEAALAAAFJGBhGAVgnqhpHIeRvsDawqns0qeN5+y967tYLyicBYE7EYkYAgAh+QQJCwAAACwAAAAAEAALAAAFNiAgjothLOOIJAkiGgxjpGKiKMkbz7SN6zIawJcDwIK9W/HISxGBzdHTuBNOmcJVCyoUlk7CEAAh+QQJCwAAACwAAAAAEAALAAAFNSAgjqQIRRFUAo3jNGIkSdHqPI8Tz3V55zuaDacDyIQ+YrBH+hWPzJFzOQQaeavWi7oqnVIhACH5BAkLAAAALAAAAAAQAAsAAAUyICCOZGme1rJY5kRRk7hI0mJSVUXJtF3iOl7tltsBZsNfUegjAY3I5sgFY55KqdX1GgIAIfkECQsAAAAsAAAAABAACwAABTcgII5kaZ4kcV2EqLJipmnZhWGXaOOitm2aXQ4g7P2Ct2ER4AMul00kj5g0Al8tADY2y6C+4FIIACH5BAkLAAAALAAAAAAQAAsAAAUvICCOZGme5ERRk6iy7qpyHCVStA3gNa/7txxwlwv2isSacYUc+l4tADQGQ1mvpBAAIfkECQsAAAAsAAAAABAACwAABS8gII5kaZ7kRFGTqLLuqnIcJVK0DeA1r/u3HHCXC/aKxJpxhRz6Xi0ANAZDWa+kEAA7AAAAAAAAAAAA);
}
JavaScript
// sample data
var data = [
{city:"Fort Dodge", zip:"34889"},
{city:"Fitchburg", zip:"83366"},
{city:"Menomonee Falls", zip:"52534"},
{city:"Norfolk", zip:"02232"},
{city:"Dearborn", zip:"55899"},
{city:"Pomona", zip:"90483"},
{city:"Port Orford", zip:"02565"},
{city:"Clovis", zip:"98500"},
{city:"Sister Bay", zip:"20285"},
{city:"Bethlehem", zip:"57757"},
{city:"Broken Arrow", zip:"18820"},
{city:"Idabel", zip:"65964"},
{city:"Macomb", zip:"43974"},
{city:"Dearborn", zip:"03451"},
{city:"Corinth", zip:"93401"},
{city:"El Paso", zip:"26282"},
{city:"Cortland", zip:"67010"},
{city:"Barre", zip:"52555"},
{city:"Aspen", zip:"62155"},
{city:"New Brunswick", zip:"68095"},
{city:"Garland", zip:"85242"},
{city:"Gloucester", zip:"33586"},
{city:"Beacon", zip:"21493"},
{city:"New Rochelle", zip:"82251"},
{city:"Fairbanks", zip:"66241"},
{city:"Lewiston", zip:"38572"},
{city:"Bismarck", zip:"91912"},
{city:"Hammond", zip:"69642"},
{city:"Uniontown", zip:"31508"},
{city:"Rolla", zip:"92430"}
];
var getFakeJsonRequest = function(page, pageSize){
var start = (page-1)*pageSize,
end = start + pageSize;
while(end > data.length){
Array.prototype.push.apply(data,data);
}
var array = data.slice(start,end);
return {
json: JSON.stringify(array),
delay: 0
};
};
/*
knockout-paged.js - A Pager Plugin for Knockout.JS
Written By: Leland M. Richardson
Desired API:
.paged(Number pageSize);
assumes static data, creates pager with given pageSize
.paged(Number pageSize, String url);
assumes `url` is an AJAX endpoint which returns the requested data with
url parameters "pg" and "perPage"
.paged(Object config);
pass config object with optional + required parameters (most flexible)
//todo: perhaps some "inf-scroll" type functionality?
//todo: restful...