I am having difficulties understanding how to limit the number of pages with pagination. I am trying to list my articles in my DB but I have over 500 pages! I would only like to show a max of about 15 page numbers at a time. I can't seem to understand the answers given in the other questions.
Here is my code for the Pagination:
<?php
require 'core/init.php';
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
if(!isset($_GET['page'])){
$_GET['page'] = 1;
}
if(! (int)$_GET['page']){
$_GET['page'] = 1;
}
if($_GET['page'] < 1){
$_GET['page'] = 1;
}
$perPage = 18;
$start = ($page > 1) ? ($page * $perPage) - $perPage : 0;
$articles = DB::getInstance()->query("SELECT SQL_CALC_FOUND_ROWS * FROM articles ORDER BY added DESC LIMIT {$start}, {$perPage}");
foreach($articles->results() as $article){ ?>
<div class="article-container">
<h2><?php echo $article->title; ?></h2>
</div>
<?php
}
// pagination
$total = DB::getInstance()->query("SELECT FOUND_ROWS() as total");
$total = $total->results()[0];
foreach ($total as $total => $value) {
}
$pages = ceil($value / $perPage);
$maxpage = 15;
?>
<div class="pagination">
<?php if($_GET['page'] >= 2){
echo 'Prev';
}
for ($i=1; $i <= $pages; $i++) : ?>
<a href="?page=<?php echo $i; ?>" <?php if($page === $i) { echo 'class="pageSelected"'; } ?>><?php echo $i; ?></a>
<?php endfor;
if((int)$_GET['page'] != $i - 1 ){
echo 'Next';
}
?>
</div>
This works as expected but it only spits out the number of pages from 1 to 500. What is the best/easiest way to show something like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 ... >
?
You need to change your for-cycle, the starting point and ending point
$count = 9;
$startPage = max(1, $page - $count);
$endPage = min( $pages, $page + $count);
for($i = $startPage; $i < $endPage; $i++) {
// write out the link to the page
}
then if the page is 250 it will show only 241, 242, ..., 250, ..., 257, 258
Related
I am sorry if the question is very basic or someone might post this question before but i can't figure out this code. Any help appreciated
Pagination works good but it shows 2 more blank pages even there are no posts on that page.
php:
<?php
$page = (isset($_GET['page']) && $_GET['page'] > 0) ? (int)$_GET['page'] : 1;
$perpage = 10;
//$limit = ($page > 1) ? (((($page *2)+1)-3)* $perpage) - $perpage : 0;
$limit = ((($page*2)+1)-3)*$perpage;
$query = mysqli_query($dbc, "SELECT SQL_CALC_FOUND_ROWS * FROM test WHERE Category='Pharma' LIMIT {$limit}, {$perpage}");
$records = mysqli_fetch_all($query);
$total = mysqli_query($dbc, "SELECT FOUND_ROWS() as total");
$total = mysqli_fetch_assoc($total)['total'];
$pages = ceil($total/$perpage);
?>
//prev
<?php
if($page>1){
?>
<a class="page-link" href="?page=<?php $pagep = $page -1; echo $pagep; ?>" tabindex="-1">Previous</a>
<?php
}
?>
//next
<?php
if($page<$pages){
?>
<a class="page-link" href="?page=<?php $pagen = $page +1; echo $pagen; ?>">Next</a>
<?php
}
?>
I tried to change the query as i know i fetch $total up here not the $query but when i fetch $query pagination not working. Thanks in advance.
I have this algorithm I made for pagination.
The $array variable is a result set from the query after the page number and limit has been set. It's a result from a PDO::fetchAll() function.
The $array["totalCount"] contains the count of ALL the rows in the table, not only that set but all the rows.
What I want is to limit the number of pages displayed, and make it somehow like google style pagination, I've search a lot of similar questions online, but what makes me struggle is to guess how I can implement it in my algorithm which is much different from others.
Thanks in advance.
public static function renderPaginationBar($obj, $params) {
$array = $obj->getAll($params);
$set = $params["set"];
$perSet = $params["limit"];
$pages = ceil((int)$array["totalCount"] / (int)$perSet);
if($pages > 1 && $set <= $pages) {
$query = preg_replace('/set=\d*/i', '', http_build_query($_GET));
?>
<ul class="pagination">
<?php
if($set > 1) {
?>
<li><<< Inicio</li>
<li><<</li>
<?php
}
for($i = 1; $i <= $pages; $i++) {
$class = $set == $i ? "active" : "";
?>
<li class="<?php echo $class; ?>"><?php echo $i; ?></li>
<?php
}
if($set < $pages) {
?>
<li>>></li>
<li>Ăšltimo >>></li>
<?php
}
?>
</ul>
<?php
}
unset($array["totalCount"]);
return $array;
}
you can try displaying it as a dropdown between the 'next' and 'prev' button if you want.. it would be easier to display all the page numbers..
or you can first get the value of current page, add 5 and store it as '$add' and minus 5 and store it as '$minus' then insert this in the page buttons:
<input type="submit" value="<?php echo $page_num;?>" <?php if($pagenum > $add || $pagenum < $minus){ echo "style='display:none'";?>>
it will hide the buttons that are more than 5 and less than 5 the current page
replace yor 'for' with this:
$get_add = $params["set"] + 5;
$get_minus = $params["set"] - 5;
for($i = 1; $i <= $pages; $i++) {
$class = $set == $i ? "active" : "";
?>
<li class="<?php echo $class; ?>" <?php if($i > $get_add || $i < $get_minus){ echo "style='display:none;position:absolute'";?>><?php echo $i; ?></li>
<?php
}
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);
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.
The pagination here works fine, but addition to pagination, as the limit per page is 3 suppose total 8 items in database so i want to display "
showing 1 t0 3 item of 8" on page one, "showing 4 to 6 items of 8" on page two and so on. please help
$recordsLimit = 3;
$page = isset($_GET['page']) ? intval($_GET['page']): 1;
$totalProducts = countProducts($selectedCategoryId);
$totalPages = ceil($totalProducts / $recordsLimit);
$pageNumber = $recordsLimit * ($page - 1);
$products = getProductsByCatId($selectedCategoryId, $pageNumber, $recordsLimit);
<?php if($totalProducts > $recordsLimit) : ?>
<div class="pagination">
<span>Page <?php echo $page.' of '.$totalPages; ?></span>
<?php for($i=1; $i <= $totalPages; $i++) :
if($i == $page) { ?>
<strong><?php echo $i; ?></strong>
<?php } else { ?>
<?php echo $i; ?>
<?php }
endfor; ?>
<?php endif; ?>
Try:
echo "Showing ".( $page == 1 ? 1 : ($page -1) * $recordsLimit +1 )." to ".($page * $recordsLimit)." item of ".$totalProducts;
Simply use this:
<?php $firstNum = (($page-1)*$recordsLimit+1) ?>
showing <?php echo $firstNum; ?> to <?php echo $firstNum+2;?> items of <?php echo $totalProducts;?>
To fix the problem with Tom's code where the last page has an incorrect "to" number I added an offset variable. For this to work the $recordsLimit variable has to match the "showposts" argument in the query. The OP did not show his query so I'm showing the one I used.
$total_results = $wp_query->found_posts;
$recordsLimit = 10;
$args['post_type'] = 'listings';
$args['showposts'] = $recordsLimit;
$args['paged'] = $paged;
$wp_query = new WP_Query($args);
$page = (get_query_var('paged')) ? get_query_var('paged') : 1;
$countoffset = ($page * $recordsLimit)-($total_results);
$countfrom = ( $page == 1 ? 1 : ($page -1) * $recordsLimit +1 );
$countto = ($page * $recordsLimit);
if(($total_results - $countfrom) < $recordsLimit) {$countto = ($countto - $countoffset);}
echo 'Showing '.$countfrom.' to '.$countto.' of '.$total_results.' total results';