JSFiddle - React, Tailwind, and code Playground

by Mi Ku

HTML

<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css">
<table class="table table-striped table-bordered" style="border:1px solid red">
   <tbody data-bind="foreach: pagedList">
        <tr>
            <td data-bind="text: name"></td>
            <td data-bind="text: sales"></td>            
        </tr>
    </tbody>
</table>
<div class="pager">
    <ul><li data-bind="css: { disabled: pageIndex() === 0 }"><a href="#" data-bind="click: previousPage"><</a></li></ul>
    <ul data-bind="foreach: allPages">
        <li data-bind="css: { active: $data.pageNumber === ($root.pageIndex() + 1) }"><a href="#" data-bind="text: $data.pageNumber, click: function() { $root.moveToPage($data.pageNumber-1); }"></a></li>
    </ul>
    <ul><li data-bind="css: { disabled: pageIndex() === maxPageIndex() }"><a href="#" data-bind="click: nextPage">></a></li></ul>
</div>

CSS

/* pager */
    
    .pager {
        margin-right: 38px;
    }
    
    .pager ul {
        margin: 0;
        padding: 0;
    }
    
    .pager li {
        float: left;
        list-style-type: none;
        margin: 0 5px;
        padding: 5px 10px;
    }
    
    .pager li a {
        color: #666;
        font-weight: 700;
        text-decoration: none;
    }
    
    .pager li.selected {
        background: #f3f8eb;
    }

JavaScript

var initialData = [
    { name: "Well-Travelled Kitten", sales: 352, price: 75.95 },
    { name: "Speedy Coyote", sales: 89, price: 190.00 },
    { name: "Furious Lizard", sales: 152, price: 25.00 },
    { name: "Indifferent Monkey", sales: 1, price: 99.95 },
    { name: "Brooding Dragon", sales: 0, price: 6350 },
    { name: "Ingenious Tadpole", sales: 39450, price: 0.35 },
];

var ListViewModel = function (initialData, pageSize) {
    var self = this;
    //window.viewModel = self;
 
    self.list = ko.observableArray(initialData);
    self.pageSize = ko.observable(pageSize);
    self.pageIndex = ko.observable(0);
 
    self.pagedList = ko.dependentObservable(function () {
        var size = self.pageSize();
        var start = self.pageIndex() * size;
        return self.list.slice(start, start + size);
    });
    
    self.maxPageIndex = ko.dependentObservable(function () {
        return Math.ceil(self.list().length/self.pageSize())-1;
    });
    
    self.previousPage = function () {
        if (self.pageIndex() > 0) {
            self.pageIndex(self.pageIndex() - 1);
        }
    };
    
    self.nextPage = function () {
        if (self.pageIndex() < self.maxPageIndex()) {
            self.pageIndex(self.pageIndex() + 1);
        }
    };
    
    self.allPages = ko.dependentObservable(function () {
        var pages = [];
        for (i = 0; i <= self.maxPageIndex() ; i++) {
            pages.push({ pageNumber: (i + 1) });
        }
        return pages;
    });
    
    self.moveToPage = function (index) {
        self.pageIndex(index);
    };
};

ko.applyBindings(new ListViewModel(initialData, 4));