knockout pagination simplified
knockout pagination simplified
by Dejan Vasic
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.6/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.3.7/js/tether.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.5/js/bootstrap.min.js"></script>
<div class="container">
<h2>
paged
</h2>
<p>
current <span data-bind="text: currentPage"></span>
</p>
<div data-bind="foreach: ticketsFiltered">
<div>
<label data-bind="text: ticketName"></label>
</div>
</div>
<div data-bind="component: { name: 'pagination', params: {dataPromise: ticketPromise, changePage: viewPage, maxPagesToDisplay: 5, pageSize: 2}}">
</div>
</div>
JavaScript
var data = [{
ticketName: 'general',
}, {
ticketName: 'child',
}, {
ticketName: 'hello',
}, {
ticketName: 'world',
}, {
ticketName: 'foo',
}, {
ticketName: 'bar',
}, {
ticketName: 'h1',
}, {
ticketName: 'h2',
}, {
ticketName: 'h3',
}, {
ticketName: 'h4',
}, {
ticketName: 'h5',
}, {
ticketName: 'h6',
}, {
ticketName: 'h7'
}, {
ticketName: 'h8'
}, {
ticketName: 'h9'
}];
function FindTickets(data) {
var pageSize = 2;
var me = this;
me.tickets = ko.observableArray();
_.each(data, function(t) {
me.tickets.push(new Ticket(t));
});
me.ticketPromise = new Promise(function(resolve, reject){
resolve(me.tickets());
});
me.currentPage = ko.observable(1);
me.ticketsFiltered = ko.computed(function() {
var chunked = _.chunk(data, pageSize);
return chunked[me.currentPage() - 1];
});
me.viewPage = function(pageNum) {
me.currentPage(pageNum);
}
}
function Ticket(data) {
var me = this;
me.ticketName = ko.observable(data.ticketName);
}
function Pagination(param) {
var me = this;
me.currentPage = ko.observable(1);
me.pages = ko.observableArray();
me.totalPageCount = ko.observable();
me.start = ko.observable(0);
me.end = ko.observable(param.maxPagesToDisplay);
param.dataPromise.then(function(items) {
me.totalPageCount(Math.ceil(items.length / param.pageSize));
if (me.totalPageCount() < param.maxPagesToDisplay) {
me.end(me.totalPageCount());
}
for (var i = 1; i <= me.totalPageCount(); i++) {
me.pages.push(new Page({
number: i,
selectPage: function(pageNum) {
me.currentPage(pageNum);
param.changePage(pageNum);
}
}));
}
});
me.next = function() {
if (me.end() === me.totalPageCount()) {
return;
}
me.start(me.start() + 1);
me.end(me.end() + 1);
}
me.prev = function() {
if (me.start() === 0) {
return;
}
me.start(me.start() - 1);
me.end(me.end() - 1);
}
...