Last active
November 2, 2022 10:54
-
-
Save prajwal89/c21f658f39b4536de8052ad94bcc1928 to your computer and use it in GitHub Desktop.
Google like pagination logic that keeps current page in the middle and keeps number of pages in pagination same if possible.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
function get_pagination_range(int $current_page, int $total_pages, int $each_side): array | |
{ | |
if ($current_page > $total_pages) { | |
return []; //current page should be smaller than total pages | |
} | |
$start = $current_page - $each_side; | |
$end = $current_page + $each_side; | |
if ($start <= 1) { | |
//extend end by difference from 1st page | |
$adjusted_end = $end + ($start * -1) + 1; //+1 bc. we need difference from page 1 (pages generally starts from 1) | |
} else { | |
$adjusted_end = $end; | |
} | |
if ($end > $total_pages) { | |
//reduce start by difference from end page | |
$adjusted_start = $start - ($end - $total_pages); | |
} else { | |
$adjusted_start = $start; | |
} | |
//keep pages inside 1 and total_pages | |
$final_start = max($adjusted_start, 1); | |
$final_end = min($adjusted_end, $total_pages); | |
return range($final_start, $final_end); | |
} | |
get_pagination_range(current_page: 1, total_pages: 23, each_side: 3); //array(7) { [0]=> int(1) [1]=> int(2) [2]=> int(3) [3]=> int(4) [4]=> int(5) [5]=> int(6) [6]=> int(7) } | |
get_pagination_range(current_page: 60, total_pages: 100, each_side: 5); //array(11) { [0]=> int(55) [1]=> int(56) [2]=> int(57) [3]=> int(58) [4]=> int(59) [5]=> int(60) [6]=> int(61) [7]=> int(62) [8]=> int(63) [9]=> int(64) [10]=> int(65) } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Shorter Version
function get_pagination_range(int $current_page, int $total_pages, int $each_side): array
{
if ($current_page > $total_pages) return []; //current page should be smaller than total pages
[$start, $end] = [$current_page - $each_side, $current_page + $each_side];
$start < 1 ? $adjusted_end = $end + ($start * -1) + 1 : $adjusted_end = $end; //extend end by difference from 1st page
$end > $total_pages ? $adjusted_start = $start - ($end - $total_pages) : $adjusted_start = $start; //reduce start by difference from end page
return range(max($adjusted_start, 1), min($adjusted_end, $total_pages)); //keep pages inside 1 and total_pages
}