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>