1

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>
ghdiep
  • 13
  • 4

1 Answers1

0

I have slightly modified your snippet. The error were due to the reference to the pagination elements through the class name instead of the id, since this will break the

jQuery(".pagination li").slice(1, -1).remove();

that I have replaced with

jQuery("#pag1 li").slice(1, -1).remove();
jQuery("#pag2 li").slice(1, -1).remove();

Of course for the same reason, if you want the click handler to be specific on each paginator element you must change that code as 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("#pag1 li").slice(1, -1).remove();
    jQuery("#pag2 li").slice(1, -1).remove();
    getPageList(totalPages, currentPage, paginationSize).forEach(item => {

      var el=jQuery("<li>").addClass("page-item")
        .addClass(item ? "current-page" : "disabled more")
        .toggleClass("active", item === currentPage)
        .append(jQuery("<a href='#'>").addClass("page-link").text(item || "..."));

      el.insertBefore( jQuery('.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 previous-page").attr({
      id: "previous-page"
    }).append(
      jQuery("<a href='#'>").addClass("page-link").text("<")
    ),
    jQuery("<li>").addClass("page-item next next-page").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">

<nav>
  <ul id="pag1" class="pagination"></ul>
</nav>

<nav>
  <ul id="pag2" class="pagination"></ul>
</nav>
loretoparisi
  • 15,724
  • 11
  • 102
  • 146