Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Knockout template to create pagination UI / links similar to StackOverflow

I have a functioning Knockout template for some pagination UI that works with a Knockout-based shared data grid. This template renders an HREF for each "page" of data in the grid.

The template works but it's klunky because if I fetch a lot of data, then I end up with dozens and dozens of navigation page links below the grid. Here's the current template:

<div class="idTemplate_ko_simpleGrid_pageLinks">
    <p>
        <span>Go to page:</span>
        <!-- ko foreach: ko.utils.range(0, maxPageIndex) -->
            <a href="javascript:void(0);"
               class="grid-pagination" 
               data-bind="text: $data + 1, click: function() { $root.currentPageIndex($data) }, css: { selected: $data == $root.currentPageIndex() }"></a>
        <!-- /ko -->
    </p>
</div>

The 'currentPageIndex' value is just a simple ko observable in the model:

this.currentPageIndex = ko.observable(0);

And 'maxPageIndex' is a computed observable in the model:

this.maxPageIndex = ko.computed(function () {
    return Math.ceil(ko.utils.unwrapObservable(this.filteredItems()).length / this.pageSize()) - 1;
}, this);

How can I modify the template and model to enable paging UI similar to StackOverflow?

For example:

prev 1 ... 3 4 5 6 7 ... 69 next

like image 426
Armchair Bronco Avatar asked Aug 21 '12 00:08

Armchair Bronco


3 Answers

This is exactly the pager style I have been using for a while now.

I just finished extracting the pager functionality I used on several projects, into an extension to knockout and template by example.

See https://github.com/remcoros/ko.pager for the source and http://remcoros.github.com/ko.pager/example.html for a working example.

All computations and some convenient properties are provided by the 'Pager' class, which you can create and bind to. But an example working template is included.

See the source example.html for usage.

like image 173
Remco Ros Avatar answered Nov 13 '22 04:11

Remco Ros


First thing I would do is look if there are any custom bindings or libraries out there that do this. If there are, create a custom binding that uses that library.

Back up plan - make your own custom binding. I'd make something like:

<div data-bind="pagination: { maxIndex: maxPageIndex(), numToShow: 7 }">
...
</div>

Then in my custom binding, do something like this:

ko.bindingHandlers.pagination = {
    update: function(element, valueAccessor) {
        if (valueAccessor().maxPageIndex > valueAccessor().numToShow) {
            // use jquery to loop and append new $("<a>") tags to $(element), using "1", then ... and a segment in the middle, followed by ... and the last index.
        }
        else {
            // loop over the regular amount.
        }
    }
};
like image 28
Richard Rout Avatar answered Nov 13 '22 05:11

Richard Rout


Im so nice so I made one for you in exactly two minutes :P (So it probably has bugs) Its based on the first pager i found which was jQuery pagination

http://jsfiddle.net/tymTz/2/

like image 41
Anders Avatar answered Nov 13 '22 04:11

Anders