I'm working on a pagination using Bootstrap and jQuery only.
I've referenced this answer to get me started: Limit the number of visible pages in pagination
The issue that I'm running into is that if there are more than one paginator on the page, the JavaScript will not render both paginators well.
function getPageList(totalPages, page, maxLength) {
if (maxLength < 5) throw "maxLength must be at least 5";
function range(start, end) {
return Array.from(Array(end - start + 1), (_, i) => i + start);
}
var sideWidth = maxLength < 11 ? 1 : 2;
var leftWidth = (maxLength - sideWidth * 2 - 3) >> 1;
var rightWidth = (maxLength - sideWidth * 2 - 2) >> 1;
if (totalPages <= maxLength) {
// no breaks in list
return range(1, totalPages);
}
if (page <= maxLength - sideWidth - 1 - rightWidth) {
// no break on left of page
return range(1, maxLength - sideWidth - 1)
.concat([0])
.concat(range(totalPages - sideWidth + 1, totalPages));
}
if (page >= totalPages - sideWidth - 1 - rightWidth) {
// no break on right of page
return range(1, sideWidth)
.concat([0])
.concat(range(totalPages - sideWidth - 1 - rightWidth - leftWidth, totalPages));
}
// Breaks on both sides
return range(1, sideWidth)
.concat([0])
.concat(range(page - leftWidth, page + rightWidth))
.concat([0])
.concat(range(totalPages - sideWidth + 1, totalPages));
}
jQuery(function() {
// Number of items and limits the number of items per page
var numberOfItems = 25;
var limitPerPage = 2;
// Total pages rounded upwards
var totalPages = numberOfItems;
// Number of buttons at the top, not counting prev/next,
// but including the dotted buttons.
// Must be at least 5:
var paginationSize = 10;
var currentPage;
function showPage(whichPage) {
if (whichPage < 1 || whichPage > totalPages) {
return false;
}
currentPage = whichPage;
// Replace the navigation items (not prev/next):
jQuery(".pagination li").slice(1, -1).remove();
getPageList(totalPages, currentPage, paginationSize).forEach(item => {
jQuery("<li>").addClass("page-item")
.addClass(item ? "current-page" : "disabled more")
.toggleClass("active", item === currentPage)
.append(jQuery("<a href='#'>").addClass("page-link").text(item || "..."))
.insertBefore("#next-page");
});
// Disable prev/next when at first/last page:
jQuery("#previous-page").toggleClass("disabled back", currentPage === 1);
jQuery("#next-page").toggleClass("disabled next", currentPage === totalPages);
return true;
}
// Include the prev/next buttons:
jQuery(".pagination").append(
jQuery("<li>").addClass("page-item back").attr({
id: "previous-page"
}).append(
jQuery("<a href='#'>").addClass("page-link").text("<")
),
jQuery("<li>").addClass("page-item next").attr({
id: "next-page"
}).append(
jQuery("<a href='#'>").addClass("page-link").text(">")
)
);
// Show the page links
showPage(1);
// Use event delegation, as these items are recreated later
jQuery(document).on("click", ".pagination li.current-page:not(.active)", function() {
return showPage(+jQuery(this).text());
});
jQuery("#next-page").on("click", function() {
return showPage(currentPage + 5);
});
jQuery("#previous-page").on("click", function() {
return showPage(currentPage - 5);
});
var ellipsisNext = function() {
jQuery('li#next-page').prev().prev().on("click", function() {
if (jQuery('li#next-page').prev().prev().text() == "...") {
return showPage(currentPage + 5);
}
});
}
var ellipsisBack = function() {
jQuery("li#previous-page").next().next().on("click", function() {
if (jQuery('li#previous-page').next().next().text() == "...") {
return showPage(currentPage - 5);
}
});
}
jQuery('').click(function() {
ellipsisNext();
ellipsisBack();
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<div>
<ul class="pagination"></ul>
</div>
<div>
<ul class="pagination"></ul>
</div>