Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Smart pagination algorithm [closed]

Tags:

php

pagination

I'm looking for an example algorithm of smart pagination. By smart, what I mean is that I only want to show, for example, 2 adjacent pages to the current page, so instead of ending up with a ridiculously long page list, I truncate it.

Here's a quick example to make it clearer... this is what I have now:

Pages: 1 2 3 4 [5] 6 7 8 9 10 11 

This is what I want to end up with:

Pages: ... 3 4 [5] 6 7 ... 

(In this example, I'm only showing 2 adjacent pages to the current page)

I'm implementing it in PHP/Mysql, and the "basic" pagination (no trucating) is already coded, I'm just looking for an example to optimize it... It can be an example in any language, as long as it gives me an idea as to how to implement it...

like image 271
jeannicolas Avatar asked Oct 02 '08 18:10

jeannicolas


People also ask

What is the logic of pagination?

The logic in Google's pagination is as follows: there are 10 page links shown at any time (e.g. 1 2 3 4 5 6 7 8 9 10) unless there are less than 10 total pages. the active link (current page) is in the 6th position, except for when the active link is below 6 or less than 4 from the last position.

How does JavaScript pagination work?

JavaScript Pagination concept is applied for moving among the pages with First, Next, Previous and Last buttons or links. Pagination's main motto is to move among the content immediately by clicking links or buttons. Pagination has multiple links or buttons provided for access First, Next, Previous and Last content.

What is pagination programming?

Pagination is a process that is used to divide a large data into smaller discrete pages, and this process is also known as paging. Pagination is commonly used by web applications and can be seen on Google.


2 Answers

Here is some code based on original code from this very old link. It uses markup compatible with Bootstrap's pagination component, and outputs page links like this:

[1] 2 3 4 5 6 ... 100 1 [2] 3 4 5 6 ... 100 ... 1 2 ... 14 15 [16] 17 18 ... 100 ... 1 2 ... 97 [98] 99 100 
<?php  // How many adjacent pages should be shown on each side? $adjacents = 3;  //how many items to show per page $limit = 5;  // if no page var is given, default to 1. $page = (int)$_GET["page"] ?? 1;  //first item to display on this page $start = ($page - 1) * $limit;  /* Get data. */ $data = $db     ->query("SELECT * FROM mytable LIMIT $start, $limit")     ->fetchAll();  $total_pages = count($data);  /* Setup page vars for display. */ $prev = $page - 1; $next = $page + 1; $lastpage = ceil($total_pages / $limit); //last page minus 1 $lpm1 = $lastpage - 1;  $first_pages = "<li class='page-item'><a class='page-link' href='?page=1'>1</a></li>" .     "<li class='page-item'><a class='page-link' href='?page=2'>2</a>";  $ellipsis = "<li class='page-item disabled'><span class='page-link'>...</span></li>";  $last_pages = "<li class='page-item'><a class='page-link' href='?page=$lpm1'>$lpm1</a></li>" .     "<li class='page-item'><a class='page-link' href='?page=$lastpage'>$lastpage</a>";  $pagination = "<nav aria-label='page navigation'>"; $pagincation .= "<ul class='pagination'>";  //previous button  $disabled = ($page === 1) ? "disabled" : ""; $pagination.= "<li class='page-item $disabled'><a class='page-link' href='?page=$prev'>« previous</a></li>";  //pages  //not enough pages to bother breaking it up if ($lastpage < 7 + ($adjacents * 2)) {      for ($i = 1; $i <= $lastpage; $i++) {         $active = $i === $page ? "active" : "";         $pagination .= "<li class='page-item $active'><a class='page-link' href='?page=$i'>$i</a></li>";     } } elseif($lastpage > 5 + ($adjacents * 2)) {     //enough pages to hide some     //close to beginning; only hide later pages     if($page < 1 + ($adjacents * 2)) {         for ($i = 1; $i < 4 + ($adjacents * 2); $i++) {             $active = $i === $page ? "active" : "";             $pagination .= "<li class='page-item $active'><a class='page-link' href='?page=$i'>$i</a></li>";         }         $pagination .= $ellipsis;         $pagination .= $last_pages;     } elseif($lastpage - ($adjacents * 2) > $page && $page > ($adjacents * 2)) {         //in middle; hide some front and some back         $pagination .= $first_pages;         $pagination .= $ellipsis         for ($i = $page - $adjacents; $i <= $page + $adjacents; $i++) {             $active = $i === $page ? "active" : "";             $pagination .= "<li class='page-item $active'><a class='page-link' href='?page=$i'>$i</a></li>";         }         $pagination .= $ellipsis;         $pagination .= $last_pages;     } else {         //close to end; only hide early pages         $pagination .= $first_pages;         $pagination .= $ellipsis;         $pagination .= "<li class='page-item disabled'><span class='page-link'>...</span></li>";         for ($i = $lastpage - (2 + ($adjacents * 2)); $i <= $lastpage; $i++) {             $active = $i === $page ? "active" : "";             $pagination .= "<li class='page-item $active'><a class='page-link' href='?page=$i'>$i</a></li>";         }     } }  //next button $disabled = ($page === $last) ? "disabled" : ""; $pagination.= "<li class='page-item $disabled'><a class='page-link' href='?page=$next'>next »</a></li>";  $pagination .= "</ul></nav>";  if($lastpage <= 1) {     $pagination = ""; }   echo $pagination;  foreach ($data as $row) {     // display your data }  echo $pagination;  
like image 191
changelog Avatar answered Oct 08 '22 16:10

changelog


Kinda late =), but here is my go at it:

function Pagination($data, $limit = null, $current = null, $adjacents = null) {     $result = array();      if (isset($data, $limit) === true)     {         $result = range(1, ceil($data / $limit));          if (isset($current, $adjacents) === true)         {             if (($adjacents = floor($adjacents / 2) * 2 + 1) >= 1)             {                 $result = array_slice($result, max(0, min(count($result) - $adjacents, intval($current) - ceil($adjacents / 2))), $adjacents);             }         }     }      return $result; } 

Example:

$total = 1024; $per_page = 10; $current_page = 2; $adjacent_links = 4;  print_r(Pagination($total, $per_page, $current_page, $adjacent_links)); 

Output (@ Codepad):

Array (     [0] => 1     [1] => 2     [2] => 3     [3] => 4     [4] => 5 ) 

Another example:

$total = 1024; $per_page = 10; $current_page = 42; $adjacent_links = 4;  print_r(Pagination($total, $per_page, $current_page, $adjacent_links)); 

Output (@ Codepad):

Array (     [0] => 40     [1] => 41     [2] => 42     [3] => 43     [4] => 44 ) 
like image 40
Alix Axel Avatar answered Oct 08 '22 16:10

Alix Axel