Knockout pager

Pager

by nickkell

HTML

<script src="http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-2.0.0.debug.js"></script>
<h2 data-bind="accordion: SearchResults()">
   Results 
</h2>
<table >
    <thead>
        <th>
            Id
        </th>
            <th>
                Name
            </th>
    </thead>
    <tbody data-bind="foreach: SearchResults, pulsate: SearchResults">
        <td data-bind="text: Id">
        </td>
        <td data-bind="text: Name">
        </td>
    </tbody>
    <tfoot data-bind="if: TotalPages() > 0">
        <td data-bind="template: {name: 'page', data: {Pages: Pages, Update: Search, CurrentPage: CurrentPage() } }">
        </td>
    </tfoot>
</table>
<button type="submit" data-bind="click: Search">Search</button>
<script type="text/html" id="page">
    <span data-bind="foreach: Pages">
        <span data-bind="if: typeof(number) == 'number'">
            <a href="#" data-bind="text: text, click: function(){ $parent.Update(number);}, css: {'selected-page': $parent.CurrentPage == number}"></a>
        </span>
        <span data-bind="if: typeof(number) != 'number'">
            <span data-bind="text: text">
            </span>
        </span>
    </span>
</script>
 Current page: <span data-bind="text: CurrentPage"></span>

CSS

th{
 padding: 5px;   
}
td{
 padding: 5px;  
}
tfoot > td{
 border-style:thin;   
}
.selected-page{
 background-color: Black; 
    color: White;  
}

JavaScript

viewModel = {
    SearchResults: ko.observableArray(),
    TotalPages: ko.observable(0),
    CurrentPage: ko.observable(1),
    Search: function(pageNum) {
        console.log('pageNum: ' + pageNum);
        var page = typeof(pageNum) != 'number' ? 1 : pageNum;
        var pageSize = 10;
        var results = [];

        for (var i = 1; i <= pageSize; i++) {
            var rowStart = ((page - 1) * pageSize) + i;
            results.push({
                Id: rowStart,
                Name: "Nick" + rowStart
            });
        }
        viewModel.SearchResults(results);
        viewModel.CurrentPage(page);
        viewModel.TotalPages(10);
    }
};

viewModel.Pages = ko.computed(function() {
    var pages = [];
    var linksEitherSide = 1;
    var firstPage = (viewModel.CurrentPage() - linksEitherSide) < 1 ? 1 : (viewModel.CurrentPage() - linksEitherSide);
    var lastPage = (viewModel.CurrentPage() + linksEitherSide) > viewModel.TotalPages() ? viewModel.TotalPages() : (viewModel.CurrentPage() + linksEitherSide);

    if (viewModel.TotalPages() == 0) return

    if (viewModel.CurrentPage() > 1) {
        pages.push({
            text: '<',
            number: viewModel.CurrentPage() - 1
        });

    }

    if (viewModel.CurrentPage() > 2) {
        pages.push({
            text: 1,
            number: 1
        });


        pages.push({
            text: '...',
            number: null
        });
    }

    for (var i = firstPage; i <= lastPage; i++) {
        pages.push({
            text: i,
            number: i
        });
    }

    if (viewModel.CurrentPage() < viewModel.TotalPages() - 1) {
        pages.push({
            text: '...',
            number: null
        });

        pages.push({
            text: viewModel.TotalPages(),
            number: viewModel.TotalPages()
        });
    }

    if (viewModel.CurrentPage() < viewModel.TotalPages()) {
        pages.push({
            text: '>',
            number: viewModel.CurrentPage() + 1
...