PHP Pagination Function that changes with the page - php

So i wrote a simple pagination function:
function pagination ( $iTotalItems )
{
if( is_array( $iTotalItems ) )
$totalItems = sizeof ( $iTotalItems );
if( is_int( $iTotalItems ) )
$totalItems = $iTotalItems;
$page = (int)( empty( $_GET['page'] ) ? 1 : $_GET['page'] );
if ($page <= 0) $page = 1;
$itemsPerPage = PAG_PER_PAGE;
$prev = $page - 1;
$next = $page + 1;
$prevlabel = "‹ Prev";
$nextlabel = "Next ›";
$totalPages = ceil( $iTotalItems / $itemsPerPage );
$perPage = $page == 'all' ? $totalItems : $itemsPerPage;
$adjacents = 2;
if( $totalItems > $itemsPerPage )
{
$filler = '';
$NumStart = '';
$NumEnd = '';
$pageNavigation = '<div class="Pagination">'. PHP_EOL;
$previousLink = $prev !== 0 ? "<a href='?p=items&page={$prev}'>{$prevlabel}</a>". PHP_EOL : "<span class='noneLink'>{$prevlabel}</span>". PHP_EOL;
$nextLink = $page < $totalPages ? "<a href='?p=items&page={$next}'>{$nextlabel}</a>". PHP_EOL : "<span class='noneLink'>{$nextlabel}</span>". PHP_EOL;
for( $i = 1; $i < $totalPages + 1; $i++ )
{
if( $i <= 10 ) { $NumStart .= $page == $i ? '<span class="noneLink">'.$i.'</span>' : ''.$i.''. PHP_EOL; }
else { $filler = '...'; }
if( $i > $totalPages - 3 ) {$NumEnd .= $page == $i ? "<span class='noneLink'>{$i}</span>" : "<a href='?p=items&page={$i}'>{$i}</a>". PHP_EOL; }
}
}
return $pageNavigation . $previousLink . $NumStart . $filler . $NumEnd . $nextLink . '</div>';
}
Now it works great and all but Im not sure how to make it change depending on the page. For example: with 40 pages and while on page 1 it looks like this.
‹ Prev 1 2 3 4 5 67 8 9 10 ...38 39 40 Next ›
However, even if im at page.. say 20 it still looks the same.
Whats the best and most simple way to code something like this while on page 1:
1 2 3 4 5 6 7 8 9 … 38 39 40 Next ›
and something like this while on page 15:
‹ Prev 1 2 3 … 11 12 13 14 15 16 17 18 19 … 38 39 40 Next ›
Thanks in advance!

Related

How to use PHP pagination in array's

Since I am trying to learn more about PHP I would like to add Pagination to array's
I have a JSON output that I can read and echo via a foreach. But I am not able to show 10 or 20 records.
I have used the code from this page:
But I miss the place where I can store the echo for the array.
$persons = '[
{"FrstName":"Henry","Middlename":"","LastName":"Walton","Online":true,"DeptId":"4"},
{"FrstName":"Klaus","Middlename":"","LastName":"Mikaelson","Online":true,"DeptId":"2"},
{"FrstName":"Kylo","Middlename":"","LastName":"Ren","Online":false,"DeptId":"4"},
{"FrstName":"Stan","Middlename":"","LastName":"Lee","Online":false,"DeptId":"3"},
{"FrstName":"Kevin","Middlename":"","LastName":"McNally","Online":false,"DeptId":"3"},
{"FrstName":"Katherine","Middlename":"","LastName":"Pierce","Online":false,"DeptId":"2"},
{"FrstName":"Clint","Middlename":"","LastName":"Barton","Online":true,"DeptId":"3"},
{"FrstName":"Avery","Middlename":"","LastName":"Walton","Online":true,"DeptId":"4"},
{"FrstName":"Peter","Middlename":"","LastName":"Kap","Online":true,"DeptId":"2"},
{"FrstName":"Denzo","Middlename":"","LastName":"Falc","Online":false,"DeptId":"4"},
{"FrstName":"Eveline","Middlename":"","LastName":"Benzel","Online":false,"DeptId":"3"},
{"FrstName":"Bill","Middlename":"","LastName":"Libuz","Online":false,"DeptId":"3"},
{"FrstName":"April","Middlename":"","LastName":"Gonzo","Online":false,"DeptId":"2"},
{"FrstName":"Harry","Middlename":"","LastName":"Geraldson","Online":true,"DeptId":"3"},
{"FrstName":"Heraldson","Middlename":"","LastName":"McGree","Online":false,"DeptId":"3"}
{"FrstName":"Abraham","Middlename":"","LastName":"Retz","Online":true,"DeptId":"4"},
{"FrstName":"June","Middlename":"","LastName":"Pharee","Online":true,"DeptId":"2"},
{"FrstName":"Anthony","Middlename":"","LastName":"Gonzales","Online":false,"DeptId":"4"},
{"FrstName":"Billy","Middlename":"","LastName":"Scott","Online":false,"DeptId":"3"},
{"FrstName":"Anika","Middlename":"","LastName":"Rose","Online":false,"DeptId":"3"},
{"FrstName":"Kristen","Middlename":"","LastName":"Fontana","Online":false,"DeptId":"2"},
{"FrstName":"Olivia","Middlename":"","LastName":"Menzel","Online":true,"DeptId":"3"},
{"FrstName":"Mark","Middlename":"van","LastName":"Gad","Online":false,"DeptId":"3"}
{"FrstName":"Hope","Middlename":"van","LastName":"Dyne","Online":false,"DeptId":"3"}
]';
$page = ! empty( $_GET['page'] ) ? (int) $_GET['page'] : 1;
$total = count( $persons ); //total items in array
$limit = 10; //per page
$totalPages = ceil( $total/ $limit ); //calculate total pages
$page = max($page, 1); //get 1 page when $_GET['page'] <= 0
$page = min($page, $totalPages); //get last page when $_GET['page'] > $totalPages
$offset = ($page - 1) * $limit;
if( $offset < 0 ) $offset = 0;
$yourDataArray = array_slice( $persons, $offset, $limit );
$link = 'index.php?page=%d';
$pagerContainer = '<div style="width: 300px;">';
if( $totalPages != 0 )
{
if( $page == 1 )
{
$pagerContainer .= '';
}
else
{
$pagerContainer .= sprintf( ' « prev page', $page - 1 );
}
$pagerContainer .= ' <span> page <strong>' . $page . '</strong> from ' . $totalPages . '</span>';
if( $page == $totalPages )
{
$pagerContainer .= '';
}
else
{
$pagerContainer .= sprintf( ' next page » ', $page + 1 );
}
}
$pagerContainer .= '</div>';
echo $pagerContainer;
I would like to know how I can fix this to use pagination for my array.
You need to json_decode() your JSON first to access array methods (count(), array_slice()). Also, your JSON data was invalid, missing some commas, fixed that.
<?php
$persons = '[
{"FrstName":"Henry","Middlename":"","LastName":"Walton","Online":true,"DeptId":"4"},
{"FrstName":"Klaus","Middlename":"","LastName":"Mikaelson","Online":true,"DeptId":"2"},
{"FrstName":"Kylo","Middlename":"","LastName":"Ren","Online":false,"DeptId":"4"},
{"FrstName":"Stan","Middlename":"","LastName":"Lee","Online":false,"DeptId":"3"},
{"FrstName":"Kevin","Middlename":"","LastName":"McNally","Online":false,"DeptId":"3"},
{"FrstName":"Katherine","Middlename":"","LastName":"Pierce","Online":false,"DeptId":"2"},
{"FrstName":"Clint","Middlename":"","LastName":"Barton","Online":true,"DeptId":"3"},
{"FrstName":"Avery","Middlename":"","LastName":"Walton","Online":true,"DeptId":"4"},
{"FrstName":"Peter","Middlename":"","LastName":"Kap","Online":true,"DeptId":"2"},
{"FrstName":"Denzo","Middlename":"","LastName":"Falc","Online":false,"DeptId":"4"},
{"FrstName":"Eveline","Middlename":"","LastName":"Benzel","Online":false,"DeptId":"3"},
{"FrstName":"Bill","Middlename":"","LastName":"Libuz","Online":false,"DeptId":"3"},
{"FrstName":"April","Middlename":"","LastName":"Gonzo","Online":false,"DeptId":"2"},
{"FrstName":"Harry","Middlename":"","LastName":"Geraldson","Online":true,"DeptId":"3"},
{"FrstName":"Heraldson","Middlename":"","LastName":"McGree","Online":false,"DeptId":"3"},
{"FrstName":"Abraham","Middlename":"","LastName":"Retz","Online":true,"DeptId":"4"},
{"FrstName":"June","Middlename":"","LastName":"Pharee","Online":true,"DeptId":"2"},
{"FrstName":"Anthony","Middlename":"","LastName":"Gonzales","Online":false,"DeptId":"4"},
{"FrstName":"Billy","Middlename":"","LastName":"Scott","Online":false,"DeptId":"3"},
{"FrstName":"Anika","Middlename":"","LastName":"Rose","Online":false,"DeptId":"3"},
{"FrstName":"Kristen","Middlename":"","LastName":"Fontana","Online":false,"DeptId":"2"},
{"FrstName":"Olivia","Middlename":"","LastName":"Menzel","Online":true,"DeptId":"3"},
{"FrstName":"Mark","Middlename":"van","LastName":"Gad","Online":false,"DeptId":"3"},
{"FrstName":"Hope","Middlename":"van","LastName":"Dyne","Online":false,"DeptId":"3"}
]';
// Make the JSON an array, so count() and array_slice() work
$persons = json_decode($persons, true);
$page = ! empty( $_GET['page'] ) ? (int) $_GET['page'] : 1;
$total = count( $persons ); //total items in array
// $limit = 10; //per page
// Set limit to 3 for testing:
$limit = 3;
$totalPages = ceil( $total/ $limit ); //calculate total pages
$page = max($page, 1); //get 1 page when $_GET['page'] <= 0
$page = min($page, $totalPages); //get last page when $_GET['page'] > $totalPages
// Uncomment this for testing
// $page = 2;
$offset = ($page - 1) * $limit;
if( $offset < 0 ) $offset = 0;
$yourDataArray = array_slice( $persons, $offset, $limit );
$link = 'index.php?page=%d';
$pagerContainer = '<div style="width: 300px;">';
if( $totalPages != 0 )
{
if( $page == 1 )
{
$pagerContainer .= '';
}
else
{
$pagerContainer .= sprintf( ' « prev page', $page - 1 );
}
$pagerContainer .= ' <span> page <strong>' . $page . '</strong> from ' . $totalPages . '</span>';
if( $page == $totalPages )
{
$pagerContainer .= '';
}
else
{
$pagerContainer .= sprintf( ' next page » ', $page + 1 );
}
}
$pagerContainer .= '</div>';
echo $pagerContainer;
foreach($yourDataArray as $person) {
echo "\n";
echo "First name: " . $person['FrstName'];
echo " - Middle name: " . $person['Middlename'];
echo " - Last name: " . $person['LastName'];
echo " - Online: " . $person['Online'];
echo " - Dept: " . $person['DeptId'];
}
https://3v4l.org/8hR84

Limit the pagination number

I have many table rows on my database which contain at least 100 or more of them. Therefore, I need to limit the pagination numbers that is displayed on my page.
Somethime like this:
Prev 1 2 3 4 5 6 .. 40 41 Next
Should become this:
Prev 1 2 .. 6 7 8 9 10 .. 40 41 Next
The code below is what I use to create a basic pagination:
<?php
require 'php/connect.inc.php';
$per_page = 6;
$pages_query = mysql_query("SELECT COUNT('user_id') FROM users");
$pages = ceil(mysql_result($pages_query, 0) / $per_page);
$page = (isset($_GET['page'])) ? (int)$_GET['page'] : 1;
$start = ($page - 1) * $per_page;
$query = mysql_query("SELECT `user_username` FROM `users` LIMIT $start, $per_page");
while($mysql_fetch_assoc = mysql_fetch_assoc($query)){
echo '<p>', $mysql_fetch_assoc['user_username'] ,'</p>';
}
if ($pages >= 1 && $page <= $pages){
for ($x=1; $x <= $pages; $x++){
echo ($x == $page) ? '<strong>'.$x.'</strong> ' : ''.$x.'';
}
}
?>
It was not easy to get the question but comparing the code and what you want ( Prev 1 2 3 ... 41 42 43 Next ) and readng the comments I hope I can help you.
If I get it right you try to create a navigation like here http://goo.gl/UzD02 (bottom of the site). Your algorithm do it for all of the found pages:
if ($pages >= 1 && $page <= $pages){
for ($x=1; $x <= $pages; $x++){
echo ($x == $page) ? '<strong>'.$x.'</strong> ' : ''.$x.'';
}
}
if $pages = 20 and $page < page you will always get:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
A possible solution would be this
$dots = true;
if ($pages >= 1 && $page <= $pages){
for ($x=1; $x <= $pages; $x++){
if ($x > $page + 1) {
$dots = true;
}
if($x > 5 && $dots) {
echo "...";
$dots = false;
if ($x < $page - 1) {$x = $page - 1;}
elseif ($x < $pages - 3) {$x = $pages - 3;}
} else {
echo ($x == $page) ? '<strong>'.$x.'</strong> ' : ''.$x.'';
}
}
}
I have not tested this code but this the part of the code, where you have to look at and imo it should work. The code also could be better.
EDIT after comment
For the pagination like google just do it like this:
$numberOfPages = 10;
if($pages >= 1 && $page <= $pages){
if($pages + $numberOfPages < $pages) {
$numOfSlectablePages = $pages + $numberOfPages;
} else {
$numOfSlectablePages = $pages;
}
for ($x = $page; $x <= $numOfSlectablePages; $x++){
echo ($x == $page) ? '<strong>'.$x.'</strong> ' : ''.$x.'';
}
}
it's not exactly like google, but I am realy busy right now and i think you get the right direction. If you want it like google just think a little bit about what you have to do or let me know, that you have no idea and I will give an answer on Sunday evening.

Pagination to show max value and limit the rest

Right now my pagination would show up something like this
[1] [2] [3] [4] [5] [6] [7] [8] [9]
How would i make it show up like this
[1] [2] [3] [4] [5]... [9]
<?php
$per_page = 10;
$pages_query = mysql_query ("SELECT COUNT(`message_id`) FROM `messages`") or die(mysql_error());
$pages = ceil(mysql_result ($pages_query, 0) / $per_page);
$page = (isset ($_GET['page'])) ? (int) $_GET['page'] : 1;
$start = ($page - 1) * $per_page;
?>
Relevant if statement that echo out pagination
<?php
if ($pages >=1 && $page <= $pages) {
for ($x=1; $x<=$pages;$x++) {
echo "".$x."";
}
}
?>
Try this :
<?php
$link = "";
// $page = $_GET['page'];
// $pages=20; // Hardcoded for testing purpose
$limit=5 ;
if ($pages >=1 && $page <= $pages)
{
$counter = 1;
$link = "";
if ($page > ($limit/2))
{ $link .= "1 ... ";}
for ($x=$page; $x<=$pages;$x++)
{
if($counter < $limit)
$link .= "".$x." ";
$counter++;
}
if ($page < $pages - ($limit/2))
{ $link .= "... " . "".$pages." "; }
}
echo $link;
?>
OUTPUT :
//At page=1
1 2 3 4 ... 20
//At page=12
1 ... 12 13 14 15 ... 20
//At page=18
1 ... 18 19 20
<?php
if ($pages >=1 && $page <= $pages) {
$counter = 1;
$link = "";
for ($x=1; $x<=$pages;$x++) {
if($counter < 5)
$link .= "".$x."";
$counter++;
}
$link .= "...";
$link .= "".$pages."";
}
echo $link;
?>

PHP : Custom pagination in Wordpress

I use this code for my custom paging :
global $wpdb, $table_prefix, $current_user;
get_currentuserinfo();
$umail = $current_user->user_email;
$paged = $wpdb->get_results("SELECT * FROM {$table_prefix}comments WHERE comment_author_email = '$umail'");
$page = isset($_GET['page']) ? (int) $_GET['page'] : 1;
$pages = COUNT($paged);
$pages = ceil($pages / 2);
$querystring = "";
foreach ($_GET as $key => $value) {
if ($key != "page") $querystring .= "$key=$value&";
}
// Pagination
for ($i = 1; $i <= $pages; $i++) {
echo "<a " . ($i == $page ? "class=\"selected\" " : "");
echo "href=\"?{$querystring}page=$i";
echo "\">$i</a> ";
}
This code paginate my comments look like this : 1 2 3 4 5 6 7 8 9 10 11
How can change code to get paginate look like this: 1 2 3 ... 11
Thanks for any help.
Try the following loop:
$page = 8;//current page
$pages = 15;//count of all pages
$batch_middle = 5;//the approximate number of pages in the middle links to display. Current page will be in the middle
$batch_lr = 1;//number of pages in the left and right links
for($i = 1; $i <= $pages;$i++)
{
//display first links
if ($i <= $batch_lr)
{
echo $i . ' ';
continue;
}
//display last links
if ($i > $pages-$batch_lr)
{
echo $i . ' ';
continue;
}
//display middle links
if ($i>=($page-floor($batch_middle/2)) && $i<=($page+floor($batch_middle/2)))
{
echo $i . ' ';
continue;
}
//placeholder
echo ' ... ';
//move the pointer
$i = ($i < $page) ? ($page-floor($batch_middle/2)-1) : ($pages-$batch_lr) ;
}
//output example 1: 1 2 ... 14 15
//output example 2: 1 2 ... 7 8 9 ... 14 15
//output example 3: 1 2 3 4 5 ... 14 15
//output example 4: 1 ... 6 7 8 9 10 ... 15
Replace $page and $pages with your logic with getting a current page and count of total pages.
Replace the $batch_middle and $batch_lr to configure a number of links in the first, second and third batches of the links

How can I improve this PHP pagination algorithm?

I'm working on a pagination algorithm in PHP. I can guess that it needs room for improvement, so I'd like some thoughts on how to improve it, be it cleaning up the code itself, from a UI/UX standpoint, or anything else you can think of.
The algorithm should output pagination that looks like this:
1 2 3 ... 6 7 8 ... 97 98 99
or this:
1 2 3 4 5 ... 6 7 8 9 10
or this:
1 2 3
Here's my code:
<?php
if(!is_null($_GET['page'])) {
$currentPage = $_GET['page'];
} else {
$currentPage = 1;
}
if($pages != null) {
echo 'Page: ';
}
// Less than 10 pages
if($pages <= 10) {
for($page = 1; $page <= $pages; $page++) {
echo '' . $page . ' ';
}
// Greater than 10 pages, and we're somewhere in the middle of them
} elseif(($pages > 10) && ($currentPage > 4) && ($currentPage < $pages - 3)) {
for($page = 1; $page <= 3; $page++) {
echo '' . $page . ' ';
}
echo '... ';
for($page = $currentPage - 1; $page <= $currentPage + 1; $page++) {
echo '' . $page . ' ';
}
echo '... ';
for($page = $pages - 2; $page <= $pages; $page++) {
echo '' . $page . ' ';
}
// Greater than 10 pages, and we're towards the end of the pages
} else {
for($page = 1; $page <= 5; $page++) {
echo '' . $page . ' ';
}
echo '... ';
for($page = $pages - 5; $page <= $pages; $page++) {
echo '' . $page . ' ';
}
}
I'm not sure if my code is any better than yours, but here is how I solved a similar problem.
It takes a parameter for the amount of pages to generate and creates a div with the class pages containing anchors, the current page has a class of current. This solution seems a little cleaner because there is less repetition.
function generate_pages($total,$current)
{ //Will generate pages and link to ?page=x when passed total pages to output
if($total > 1)
{
$total=intval($total);
$output='<div class="pages">';
$current_page= (false == isset($current)) ? 1 : $current;
for($page=1;$page<$total+1;$page++)
{
$lower=$current_page-3;
$upper=$current_page+3;
$special = ($page==$current_page) ? " class=\"current\"" : "";
if(($page > $lower && $page < $upper) || $page < 2 || $page > ($total-1))
{
if($last_done_page+1 != $page) $output.= '... ';
$output.='<a'.$special.' href="?page='.$page.'">'.$page.'</a>';
$last_done_page=$page;
}
}
$output.='</div>';
return $output;
}
}

Categories