PHP - pagination count incorrectly - php

So I have a simple pagination system on my website. But there's a problem with my calculation for the next page. whenever the page is on page 2 the next page is 13 instead of 3. I have tested the calculation and it always comes out with 3 as result. Here is my code:
<?php
$applied_filters = array("parent" => null, "child" => null);
if(isset($_GET['cat'])) {
$applied_filters["parent"] = $_GET['cat'];
if(isset($_GET['sub']))
$applied_filters["child"] = $_GET['sub'];
}
if(isset($_GET['page'])) {
$page = $_GET['page'];
} else {
$page = 1;
}
$products_per_page = 9;
$start_from = ($page-1) * $products_per_page;
$pagination_url = "winkel.php?";
if($applied_filters["parent"] != null) {
$pagination_url .= "cat=" . $applied_filters["parent"];
if($applied_filters["child"] != null) {
$pagination_url .= "&sub=" . $applied_filters["child"] . "&page=";
} else {
$pagination_url .= "&page=";
}
} else {
$pagination_url .= "page=";
}
echo $page . '<br>'; // shows 2
$nextpage = $page + 1; //shows 3
echo $nextpage;
?>
<ul class="pagination">
<?php if($page > 1) { ?>
<li>«
</li>
<?php } ?>
<li class="active"><?= $page ?>
</li>
<?php if($page < $max_pages) { echo $nextpage; // shows 3?>
<li>»
</li>
<?php } ?>
I also have some URL code for the filters on my website:
<?php
// link filters
if(isset($_GET['cat'])) {
if(isset($_GET['cat']) && isset($_GET['sub'])) {
if($_GET['cat'] != "alles")
$result_products = $db->get_by_cat("products", $_GET['cat'], $_GET['sub'], $start_from, $products_per_page);
} else if (isset($_GET['cat'])) {
if($_GET['cat'] != "alles")
$result_products = $db->get_by_cat("products", $_GET['cat'], null, $start_from, $products_per_page);
}
}
if(isset($_POST['clearbrand'])) {
unset($_POST['brandfilter']);
unset($_POST['applybrand']);
}
$filtered_brands = null;
if(isset($_POST['brandfilter'])) $filtered_brands = $_POST['brandfilter'];
// form filters
if(isset($_POST['applybrand'])) {
if(isset($_GET['cat'])) {
$result_products = $db->get_by_checkbox("products", "brand", $_POST['brandfilter'], $_GET);
} else {
$result_products = $db->get_by_checkbox("products", "brand", $_POST['brandfilter']);
}
}
?>
So, does anybody know why my pagination counts from 2 to 13?
Thanks in advance

Your problem is here:
<?php if($page > 1) { ?>
<li>«</li>
<?php } ?>
<li class="active"><?= $page ?></li>
<?php if($page < $max_pages) { echo $nextpage; // shows 3?>
<li>»</li>
<?php } ?>
If $page is greater than 1 (which it is on page 2), you add $page - 1 to the $pagination_url, basically putting a "1" at the end.
Then, in the second if statement, if $page is less than $max_pages, you also add $nextpage (which is 3) to the $pagination_url, putting a "3" after the "1" you added before. Therefore, $pagination_url will now have "13" at the end.
You'll want to change this to:
<?php if($page > 1) { ?>
<li>«</li>
<?php } ?>
<li class="active"><?= $page ?></li>
<?php if($page < $max_pages) { echo $nextpage; // shows 3?>
<li>»</li>
<?php } ?>

Related

Sorting not working on next page of pagination PHP BS-4

I already created a table that has limit and it is working well with pagination
if(isset($_GET['page']) && !empty($_GET['page'])){
$currentPage = $_GET['page'];
}else{
$currentPage = 1;
}
$startFrom = ($currentPage * $showRecordPerPage) - $showRecordPerPage;
$totalEmpSQL = "SELECT * FROM producttable";
$allEmpResult = mysqli_query($conn, $totalEmpSQL);
$totalProducts = mysqli_num_rows($allEmpResult);
$lastPage = ceil($totalProducts/$showRecordPerPage);
$firstPage = 1;
$prev = $currentPage - 1;
$next = $currentPage + 1;
$sortertype = "name";
$sorterorder = "ASC";
$sort = "";
if(isset($_GET['sort'])){
$sort = $_GET['sort'];
}
if ($sort == 'nameasc') { // If you Sort it with value of your select options
$sortertype = "name";
$sorterorder = "ASC";
} elseif ($sort == 'namedesc') { // else if you do not pass any value from select option will return this
$sortertype = "name";
$sorterorder = "DESC";
}
$empSQL = "SELECT id,name, price,description
FROM `producttable` ORDER BY $sortertype $sorterorder LIMIT $startFrom, $showRecordPerPage";
$empResult = mysqli_query($conn, $empSQL);
while($row = mysqli_fetch_assoc($empResult)) {}
**for pagination
<ul class="pagination justify-content-start" >
<li class="page-item <?php if($currentPage <= 1){ echo 'disabled'; } ?>">
<a class="page-link"
href="<?php if($currentPage <= 1){ echo '#'; } else { echo "?page=" . $prev; } ?>">Prev</a>
</li>
<?php for($i = 1; $i <= $lastPage; $i++ ): ?>
<li class="page-item <?php if($currentPage == $i) {echo 'active'; } ?>">
<a class="page-link" href="inde.php?page=<?= $i; ?>"> <?= $i; ?> </a>
</li>
<?php endfor; ?>
<li class="page-item <?php if($currentPage >= $lastPage) { echo 'disabled'; } ?>">
<a class="page-link"
href="<?php if($currentPage >= $lastPage){ echo '#'; } else {echo "?page=". $next; } ?>">Next</a>
</li>
</ul>
**and also manage to create a working sorting options that displays the type of order and doesnt reset when changed
<select name="sort" id="myselect" onchange="sort(this.value);" class="py-1" >
<option value="nameasc" <?php if($sort == 'nameasc'):?> selected="selected"<?php endif;?>>Name:Asc</option>
<option value="namedesc" <?php if($sort == 'namedesc'):?> selected="selected"<?php endif;?>>Name:Desc</option>
</select>
<script type="text/javascript">
function sort(option){
window.location = window.location.pathname+'?sort='+option;
}
</script>
the only problem is that when the page goes to the next page, the sorting options resets and also the table reset to default sorting. Is there anyway to make the pagination connect to the sorting options part?
You are not reading the GET value received for the sort
$sort = $_GET['sort'];
So your code should be
$sort = $_GET['sort']; // this line is missing
if ($sort == 'nameasc') { // If you Sort it with value of your select options
$sortertype = "name";
$sorterorder = "ASC";
} elseif ($sort == 'namedesc') { // else if you do not pass any value from select option will return this
$sortertype = "name";
$sorterorder = "DESC";
}

How to create pagination that shows previous and next 3 pages

I want to show a pagination which only shows the recent and next 3 pages, but I can't get it working.
Here's my current code:
$stmt = MySQL::connection3()->prepare("SELECT COUNT(ID) AS TOTAL FROM products");
$stmt->execute();
$row = $stmt->fetch();
$total_pages = ceil(intval($row["TOTAL"]) / $results_per_page);
foreach (range(1, $total_pages) as $i) {
if ($i == $page) {
?>
<li class="page-item active">
<?php echo $i ?>
</li>
<?php
} else {
?>
<li class="page-item">
<?php echo $i ?>
</li>
<?php
}
}
Thanks!
I create this example you can run and adapt with your code:
<style>.active{color:green!important}</style>
<?php
echo get_pagination_links('10','100');
function get_pagination_links($current_page, $total_pages)
{
$links = "";
if ($total_pages >= 1 && $current_page <= $total_pages) {
$i = max(2, $current_page - 3);
for (; $i < min($current_page + 4, $total_pages); $i++) {
if($i==$current_page){
$links .= "<li class='page-item active'><a href='?page=$i;' class='page-link'>$i</a></li>";
}else{
$links .= "<li class='page-item'><a href='?page=$i;' class='page-link'>$i</a></li>";
}
}
return $links;
}
}
?>
Output:
7-8-9-10-11-12-13
obviously I didn't connect a database and therefore I used a static result

PHP, generate previous and next links from array with numbers

I have an array like this:
$pages = (1, 29, 209, 389, 440, 527)
And I want to make simple HTML navigation through these pages. Only 'first', 'last', 'prev' and 'next' links.
And when I click the 'next'/'prev' link they had to change accordingly.
E.g. when I am at page 389 prev and next to be 209 and 440. If I am at page 440 prev and next to be 389 and 527.
Here is one simple approach:
$pages = array(1, 29, 209, 389, 440, 527);
$current = isset($_GET['page']) ? $_GET['page'] : $pages[0];
// current page
$key = array_search($current, $pages);
echo 'current page: ' . $pages[$key] . '<br />';
// previous page
$prev = $key - 1;
if ($prev >= 0 && $prev < count($pages)) {
echo 'prev | ';
} else {
echo 'prev | ';
}
// next page
$next = $key + 1;
if ($next >= 0 && $next < count($pages)) {
echo 'next';
} else {
echo 'next';
}
Assuming the keys will always be in order, then the first page will always be at $pages[0], and to get the last you could use $pages[key(array_slice($pages, -1, 1, true))]
function printPager($pageList,$currentPage)
{
$links="";
if(($currentIndex = array_search($currentPage, $pageList))!== NULL)
{
$links .=
//first
($currentIndex!=0?"<a href='/".($pageList[0])."'>First</a> ":"") .
//prev
(isset($pageList[$currentIndex-1])?"<a href='/".($pageList[$currentIndex-1])."'>Prev</a> ":"").
//next
(isset($pageList[$currentIndex+1])?"<a href='/".($pageList[$currentIndex+1])."'>Next</a> ":"").
//last
($currentIndex!=count($pageList)-1?"<a href='/".($pageList[count($pageList)-1])."'>Last</a>":"");
}
echo $links;
}
printPager(array(20,4,10,14),20);
try this:
<?php
$pages = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
$active = 1;
$last = false;
$next = false;
if (isset($_GET['page']))
{
$active = $_GET['page'];
$last = $active - 1;
$next = $active + 1;
if (!in_array($next, $pages))
{
$next = false;
}
if (($last < 0) or !in_array($last, $pages))
{
$last = false;
}
}
?>
<ul>
<li>
<- LAST
</li>
<?php foreach ($pages as $page): ?>
<li><?= $page ?> <?= $page == $active ? ' is active!' : ''?></li>
<?php endforeach; ?>
<li>
NEXT ->
</li>
</ul>
<ul>
<?php
$pages = [1,4,89,100,121,224,443,527];
$thisPage = $_GET['page'];
foreach($pages as $key => $page){
if($thisPage == $page){
$thisPageKey = $key;
}
}
foreach($pages as $key => $page){
if($key==0){
echo '<li>first</li>';
}
if($key+1==count($pages)){
echo '<li>last</li>';
}
if(array_key_exists($thisPageKey-1, $pages) && $thisPage == $page){
echo '<li>prev</li>';
}
if(array_key_exists($thisPageKey+1, $pages) && $thisPage == $page){
echo '<li>next</li>';
}
}
?>
</ul>
You could try this
$pages=array(1, 29, 209, 389, 440, 527);
foreach ( $array_keys=array_keys($pages) as $array_keys) {
$pages_invert[ $pages[$array_keys] ]=$array_keys;
}
echo 'first ('.$pages[0].')';
echo ' | ';
if( $pages_invert[$_GET['page_id']]-1 >= 0 ) echo 'previous ('.$pages[$pages_invert[$_GET['page_id']]-1].') ';
else echo 'previous';
echo ' | ';
echo 'current ('.$_GET['page_id'].')';
echo ' | ';
if( $pages_invert[$_GET['page_id']]+1 <= 5 ) echo 'next ('.$pages[$pages_invert[$_GET['page_id']]+1].')';
else echo 'next';
echo ' | ';
echo 'last ('.$pages[count($pages)-1].')';
The foreach command makes inversion of your original array for jumps from current to previous and next array keys at $pages array.
To preview how the arrays looks, put this code:
any line arter your $pages array definition
<?
echo '<pre>';
print_r($pages);
echo '</pre>';
echo '<pre>';
print_r($pages_invert);
echo '</pre>';
?>
Please notice the minimum items in the $pages array is 3 items.

Pagination does not work perfectly

I have the following code:
$max = 4;
$page = isset($_GET['page']) ? ($_GET['page']) : '1';
$init = $page - 1;
$init= $max * $init;
$strCount = "SELECT COUNT(*) AS 'total_mytable' FROM mytable";
$varstrCount = $crud->viewdatas($strCount);
$total = 0;
if(count($varstrCount)){
foreach ($varstrCount as $row) {
$total = $row["total_mytable"];
}
}
$result = "SELECT * FROM mytable ORDER BY id_mytable LIMIT $init,$max";
$varresult = $crud->viewdatas($result);
content of page:
<?php
if(count($varresult)){
foreach ($varresult as $res) {
?>
<h5><?php echo $res['title'] ?></h5>
<?php
}
}
?>
<?php
$max_links = 10;
$previous = $page - 1;
$next = $page + 1;
$pgs = ceil($total / $max);
if($pgs > 1 ){
if($previous > 0){
echo "<li><a href='".BASE_URL."/category/$previous' aria-label='Previous'><span aria-hidden='true'>«</span></a></li>";
} else{
}
for($i=$page-$max_links; $i <= $pgs-1; $i++) {
if ($i <= 0){
}else{
if($i != $page{
if($i == $pgs){ //if end insert 3 dots
echo "<li><a href='".BASE_URL."/category/".($i)."'>".$i."</a></li> ...";
}else{
echo "<li><a href='".BASE_URL."/category/".($i)."'>".$i."</a></li>";
}
} else{
if($i == $pgs){ //if end insert 3 dots
echo "<li>".$i."</li> ...";
}else{
echo "<li>".$i."</li>";
}
}
}
}
if($next <= $pgs){
echo "<li><a href='".BASE_URL."/category/$next' aria-label='Next'><span aria-hidden='true'>»</span></a></li>";
}else{
}
}
?>
The result:
And I not understand the reason for the active number stay right off the paging menu
In the code I defined max-links for 10, but no show number 5 and if I define max links for 3 changes nothing , displays the same result as the image.
Thanks for any help
echo "<li>".$i."</li>";
on the above line add up a href, seems like you have css formatting for li>a because of which you are not getting the required formatting on only li. so for getting better formatting for all paging links current, prev, next. you need to add up a tags.
echo "<li><a>".$i."</a></li>"; //in your else part

Display images with pagination from mysql

I had a php page to display images from a mysql database. It displays all the images uploaded in 1 page one after the other. How can i display 5 or 6 images per page with pagination?
Here is my php page.
<?Php
include("init.php");
include("template/header.php");
?>
<div class="view_albums"><h3> View Albums </h3>;
<?php
$album_id = $_GET['album_id'];
$images = get_images($album_id);
if (empty($images)) {
echo 'There are no images ';
} else {
foreach ($images as $image) {
?> <div class="box"> <?php
echo ' <img class="box1" src="uploads/thumbs/', $image['album'], '/', $image['id'], '.', $image['ext'], '" title="Uploaded on ', date('l F j, Y \a\t g:i A',$image['timestamp']),'"> [delete]';
?> <?php
}
}
?>
</div>
</div>
<?php
include("template/footer.php");
?>
try to use the below pagination function
function genPagination($total,$currentPage,$baseLink,$nextPrev=true,$limit=10)
{
if(!$total OR !$currentPage OR !$baseLink)
{
return false;
}
//Total Number of pages
$totalPages = ceil($total/$limit);
//Text to use after number of pages
$txtPagesAfter = ($totalPages==1)? " page": " pages";
//Start off the list.
$txtPageList = '<br />'.$totalPages.$txtPagesAfter.' : <br />';
//Show only 3 pages before current page(so that we don't have too many pages)
$min = ($page - 3 < $totalPages && $currentPage-3 > 0) ? $currentPage-3 : 1;
//Show only 3 pages after current page(so that we don't have too many pages)
$max = ($page + 3 > $totalPages) ? $totalPages : $currentPage+3;
//Variable for the actual page links
$pageLinks = "";
//Loop to generate the page links
for($i=$min;$i<=$max;$i++)
{
if($currentPage==$i)
{
//Current Page
$pageLinks .= '<b class="selected">'.$i.'</b>';
}
else
{
$pageLinks .= ''.$i.'';
}
}
if($nextPrev)
{
//Next and previous links
$next = ($currentPage + 1 > $totalPages) ? false : 'Next';
$prev = ($currentPage - 1 <= 0 ) ? false : 'Previous';
}
return $txtPageList.$prev.$pageLinks.$next;
}
think it will help you

Categories