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...