PHP pagination loop issue - php

I tried to make a PHP pagination like this:
$count = $this->dataBaseFunctions->countItems();
$resultperPage = 10;
$offset = 0;
$adjacents = 3;
$totalPages = ceil(intval($count) / $resultperPage);
if (isset($_GET['offset'])) {
$offset = trim($_GET['offset']);
}
$j = $adjacents;
while ($j > 0) {
if (($offset / 10) - 1 > 0) {
echo '' . ($offset - 10 - ($j * 10)) . ' ';
}
$j--;
}
/*for ($j = $adjacents; $j > 0; $j--) {
echo '' . ($offset - 10 - ($j * 10)) . ' ';
}*/
echo '[' . ($offset - 10) . '] ';
for ($j = 1; $j < ($adjacents + 1); $j++) {
echo '' . ($offset - 10 + ($j * 10)) . ' ';
}
The result should look like this (Brackets = current clicket page):
[0] 1 2 3
When I click "3" it should look like this (works so far):
0 1 2 [3] 4 5 6
But when I click "1" the result looks like this:
-2 -1 0 [1] 2 3 4
The "0" is not a problem, I just 'echoed' it for debugging.
I know that I dont set the right conditions for not showing pages below 1 but I dont get it how to make it right. Seems like I have tomatoes on my eyes... The echo is just for testing - later I save the whole pagination links into a variable to assign it to the bottom of the page. Its a bit of debugging code you see here but it shows what I try to do. Please let me know if I can improve the question or if there are missing informations like: "why you do ($offset / 10) -1 > 0" ;-)
Later I need to do same stuff in JS but I think I can manage that, when I know what I did wrong in the PHP version.
*Maybe it's a bad Idea what I try to do there?

This one should do the trick:
Now including the $adjacents
$count = $this->dataBaseFunctions->countItems();
$resultperPage = 10;
$offset = 0;
$adjacents = 3;
$totalPages = ceil(intval($count) / $resultperPage);
if (isset($_GET['offset'])) {
$offset = trim($_GET['offset']);
}
$start = ($offset-$adjacents) > 0 ? ($offset-$adjacents) : 0;
$end = ($offset+$adjacents) < $totalPages ? ($offset+$adjacents) : $totalPages;
$pager = "";
for ($i = 0; $i < $totalPages; $i++) {
if ($i >= $start && $i <= $end) {
$pager .= $offset != $i ? '' . $i . ' ' : "[$i] ";
}
}
echo $pager;

Related

PHP pagination function generates more pages than needed [the last page is empty] sometimes. How do I fix this?

I just found a pagination function to display pages of images from a folder, however when paginating it the last few pages seem to be empty and I don't want this. Here's the code I'm working with:
<?php
function show_pagination($current_page, $last_page){
echo '<br><div>';
echo ' <button type="button">First Page</button> ';
echo ' <button type="button">Last Page</button> ';
if( $current_page > 1 ){
echo ' <button type="button"><<Previous</button> ';
}
for($i = 1; $i <= $last_page; $i++){
echo ' <button type="button">'.$i.'</button> ';
}
if( $current_page < $last_page ){
echo ' <button type="button">Next>&gt</button> ';
}
echo '</div><br>';
echo '<div><p>Page '.$current_page.' out of '.$last_page.'</p></div><br>';
}
$folder = 'images/';
$filetype = '*.*';
$files = glob($folder.$filetype);
$total = count($files);
$per_page = 20;
$last_page = (int)($total / $per_page);
if(isset($_GET["page"]) && ($_GET["page"] <=$last_page) && ($_GET["page"] > 0) ){
$page = $_GET["page"];
$offset = ($per_page + 1)*($page - 1);
}else{
//echo "Page out of range showing results for page one";
$page=1;
$offset=0;
}
$max = $offset + $per_page;
if($max>$total){
$max = $total;
}
show_pagination($page, $last_page);
for($i = $offset; $i< $max; $i++){
$file = $files[$i];
$path_parts = pathinfo($file);
$filename = $path_parts['filename'];
echo "<img src='$file' alt='$filename' style='border-style: solid;border-width: 2px;border-color: #4d94ff; margin: 5px'>";
}
show_pagination($page, $last_page);
?>
Any help resolving this minor issue will be greatly appreciated. However I'm calculating the last page seems to work in some cases, but doesn't work in all cases, I'm not sure why.
I' m fairly certain the problem lies in your offset - $offset = ($per_page + 1)*($page - 1).
Keep in mind that each page will show twenty items, not twenty one. For the first page, you want an index of 1. For the second, 21. For the third, 41. And so on.
As such, you'll only want to add the one after the page itself has been calculated. For this, you're probably looking for the following:
$offset = ($per_page * ($page - 1)) + 1;
Which equates to:
$offset = (20 * (1 - 1)) + 1; /* 1 for page 1 */
$offset = (20 * (2 - 1)) + 1; /* 21 for page 2 */
$offset = (20 * (3 - 1)) + 1; /* 41 for page 3 */

Hide the link of current page.

The code which I use to show Links of 10 pages per page in pagination is:
$start = ( floor($page/10) * 10 ) + 1;
for( $i = $start; $i < $totalPages; $i++){
if( $i >= ($start + 10)){
break;
}
else{
}
echo ' ' . $i . ' ';
}
I want to hide the current page link such that if I was on Page 7 it will hide the link 7. can anybody help?
Echo only if the page is not equal to the current page.
if ($page != $i) echo ' ' . $i . ' ';
You need to get the current page and then just use a simple condition. Something like:
$currentPage = $_GET["page"];
$start = ( floor($page/10) * 10 ) + 1;
for( $i = $start; $i < $totalPages; $i++){
if( $i >= ($start + 10)){
break;
}
else {
if ($i!=$currentPage) echo ' ' . $i . ' ';
}
}
Also, I moved echo inside the else {} part because I believe it should be there.

PHP remove page 0 from pagination

I was able to get my pagination script working, and everything works fine except when you go to PAGE 2, you can see a PAGE 0, which if you click on it give you nothing.
I need to fix my current code so that the application does not show a PAGE 0.
Here is the necessary code:
<?php
$total_records = countRecords(); // self explanatory function called here
$total_pages = ceil($total_records / $rec_limit);
$adjacents = 2;
$previousPage = $page - 1;
$nextPage = $page + 1;
$querystring = "";
$start = ($page < $adjacents ? 1 : $page - $adjacents);
$beginning = 1;
$end = ($page > $total_pages - $adjacents ? $total_pages : $page + $adjacents);
foreach($_GET as $key => $value)
{
if($key != "page") $querystring .= "$key=$value&";
}
echo
'<div class="row-fluid">
<div class="span2">'.countRecords()." total records" .'</div>
<div class="container pagination-small">
<ul style="margin: 3px;" class="pager">';
echo #"<li>First</li>";
if ($left_rec < $rec_limit)
{
$last = $page - 1;
echo #"<li><a href=\"$targetpage?page=$previousPage&$querystring\">
Previous</a></li>";
for($i= $start; $i <= $end; $i++)
{
echo #"<li " . ((($page)==$i)? "class=\"active\"" : "") . ">
$i</li>";
}
}
else if($page == 0)
{
for($i= $start; $i <= $end; $i++)
{
echo #"<li " . ((($page)==$i)? "class=\"active\"" : "") . ">
$i</li>";
}
echo #"<li>Next</li>";
}
else if ($page > 0)
{
$last = $page - 2;
echo #"<li><a href=\"$targetpage?page=$previousPage&$querystring\">
Previous</a></li>";
for($i= $start; $i <= $end; $i++)
{
echo #"<li " . ((($page)==$i)? "class=\"active\"" : "") . ">
$i</li>";
}
echo #"<li>Next<li>";
}
echo #"<li>Last</li>";
echo '<ul></div></div>';
I tried to keep the code as short as possible. If there are any errors, just note it's only a typo as I typed it here. The code works, with exception to my problem.
So with that all said, can anyone tell me how to remove PAGE 0 from the pagination? I have done some research, but I have been unsuccessful applying it to my code. So I'm hoping someone can take a look at my code and tell me how I can alter it to make this work.
I appreciate the help.
Thank you in advance.
Logic flaw:
$start = ($page < $adjacents ? 1 : $page - $adjacents);
If you're on Page 1, you'll get
$start = (1 < 2 ? 1 : 1 - 2);
$start = -1; // page negative one? huh?
Then this loop is pointless:
foreach($_GET as $key => $value) { ... }
Why not just
unset($_GET['page']);
$q = http_build_query($_GET);

PHP pagination Adjacents

I was able to create a working pagination system for my application. But the problem I am having is when a user does a search, it can/will display over 100 pages in the pagination.
I am trying to figure out how to show only like 5 on each side of the current page. I would like to create a FIRST page button, and a LAST page button, but I'll deal with that later.
So here is the first part of code that counts the records in the database table:
<?php
function countRecords()
{
// The application takes a lot of user input, which then builds a query here.
// The user input goes into a session variable called $_SESSION['where']
// I'll start with the actual query code
$sql = "SELECT COUNT(DISTINCT CONTAINER_NUMBER) AS TOTAL
FROM 'contTable'" . " WHERE (" . $_SESSION['where'] . ");";
$sqlres = #mysql_query($sql) or die();
$row = mysql_fetch_row($sqlres);
$return $row[0];
}
So code above gets the count from the table depending on the search criteria.
Here is the next piece of code that prints the grid. I'll keep it as short as possible:
function displayrecords()
{
$rec_limit = 100;
$targetpage = "containers.php";
if(isset($_GET['page']))
{
$page = $_GET['page'];
$offset = $rec_limit * ($page - 1);
}
else
{
$page = 1;
$offset = $rec_limit * ($page - 1);
}
$left_rec = countRecords() - ($page * $rec_limit);
$select = "";
$_SESSION['where'] = "";
// user input variables are here that build a variable called $_SESSION['where']
// I'll skip the code down to the query
if ($_SESSION['where'] != "") $select = "SELECT * FROM 'contTable'" . " WHERE
(" . $_SESSION['where'] . ") GROUP BY container, bol LIMIT " . $offset . ",
" . $rec_limit . ";";
}
Please excuse any typos or missing brackets and whatnot. Just know the above code works.
Now here is the code for the rest of the pagination:
$total_records = countRecords();
$total_pages = ceil($total_records / $rec_limit);
$adjacents = 5; // I just added this variable. I don't know what to do with it
$previousPage = $page - 1;
$nextPage = $page + 1;
$querystring = "";
foreach ($_GET as $key => $value)
{
if ($key != "page") $querystring .= "$key=$value&";
}
echo '<ul style="border: 0px solid red; margin: 3px;" class="pager">';
if ($left_rec < $rec_limit)
{
$last = $page - 2;
echo #"<li><a href=\"$targetpage?page=$previousPage&$querystring\">
Previous</a></li>";
for($i = 1; $i <= $total_pages; $i++)
{
echo #"<li " . ((($page+1)==$i)? "class=\"active\"" : "") . ">
$i</li>";
}
}
else if ($page == 0)
{
for($i = 1; $i <= $total_pages; $i++)
{
echo #"<li " . ((($page+1)==$i)? "class=\"active\"" : "") . ">
$i</li>";
}
echo #"<li>Next</li>";
}
else if ($page > 0)
{
$last = $page - 2;
echo #"<li><a href=\"$targetpage?page=$previousPage&$querystring\">
Previous</a></li> ";
for($i = 1; $i <= $total_pages; $i++)
{
echo #"<li " . ((($page+1)==$i)? "class=\"active\"" : "") . ">
$i</li>";
}
echo #"<li>Next</li>";
}
echo '</ul>';
}
So, with all of the code above, I can display a grid, and display the pages at the bottom of the application. But I don't want to show all 100 pages, only 5 on each side of the current page. I know I need to utilize the variable called $adjacents and plug it in to the paging portion of the code. But I'm not exactly sure how to do it.
I hope I am being clear on my request.
Please help.
Instead of looping through all of the pages:
for($i = 1; $i <= $total_pages; $i++)
Try doing something like this:
$start = ($page < $adjacents ? 1 : $page - $adjacents);
$end = ($page > $total_pages - $adjacents ? $total_pages : $page + $adjacents);
for($i= $start; $i <= $end; $i++)
//Here you can loop through the numbers within adjacents of the current page

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.

Categories