1
\$\begingroup\$

I have written a function that builds an array of paging options for rendering on the view.

I have modelled it after DataTables for jQuery, a live example with lots of data is available here: http://www.companieshousedata.co.uk/a/490

Is there a better way to write this? The function also returns ellipsis (as strings) where necessary.

Model/object:

function PageDirection(data) {
    var self = this;
    self.display = data.display;
    self.value = data.value;        
    self.disabled = function (currentPage, lastPage) {
        return self.value() > lastPage || self.value() < 1 || self.value() == null;
    };
}

Computed observable:

self.pageDirections = ko.computed(function () {     
    var pageIndex = self.pageIndex();
    var lastPage = self.lastPage();

    //Previous
    var directions = [
        new PageDirection({
            display: "Previous",
            value: ko.computed(function() {
                return parseInt(pageIndex, 10) - 1;
            })
        })
    ];

    //6 or less pages
    if (self.lastPage() <= 6) {
        for (var i = 0; i < lastPage; i++) {
            directions.push(new PageDirection({
                display: i + 1,
                value: ko.observable(i + 1)
            }));
        }
    } else {
        if (pageIndex > 4) {
            //1
            directions.push(new PageDirection({
                display: 1,
                value: ko.observable(1)
            }));
            //...
            directions.push(new PageDirection({
                display: "...",
                value: ko.observable(null)
            }));

            if (lastPage - pageIndex <= 3) {
                //last 5
                for (var k = lastPage - 5; k < lastPage; k++) {
                    directions.push(new PageDirection({
                        display: k + 1,
                        value: ko.observable(k + 1)
                    }));
                }                   
            } else {
                //-1
                directions.push(new PageDirection({
                    display: pageIndex - 1,
                    value: ko.observable(pageIndex - 1)
                }));
                //current
                directions.push(new PageDirection({
                    display: pageIndex,
                    value: ko.observable(pageIndex)
                }));
            }

            if (lastPage - pageIndex > 3) {
                //+1
                directions.push(new PageDirection({
                    display: pageIndex + 1,
                    value: ko.observable(pageIndex + 1)
                }));
                //...
                directions.push(new PageDirection({
                    display: "...",
                    value: ko.observable(null)
                }));
            }
        } else {
            //first 5
            for (var l = 0; l < 5 ; l++) {
                directions.push(new PageDirection({
                    display: l + 1,
                    value: ko.observable(l + 1)
                }));
            }
            //...
            directions.push(new PageDirection({
                display: "...",
                value: ko.observable(null)
            }));

        }
        if (lastPage - pageIndex > 3) {
            //last
            directions.push(new PageDirection({
                display: lastPage,
                value: ko.observable(lastPage)
            }));
        }       
    }

    //Next
    directions.push(new PageDirection({
        display: "Next",
        value: ko.computed(function () {
            return parseInt(pageIndex, 10) + 1;
        })
    }));

    return directions;
});

View (for reference):

<span data-bind="foreach: pageDirections">
    <span data-bind="text: display, click: $parent.navigate.bind($parent), css: { 'inactive': disabled($parent.pageIndex(), $parent.lastPage()), 'active': $parent.pageIndex() == value() }"></span>
</span>
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.