I am trying to get a nice paginator to work but I'm having trouble with getting the upcoming/middle numbers to work properly.
The goal is to show the first and last 5 pages of a result set regardless of what page your on, but these first and last 5 can only show if there are enough pages to allow it.
The pagination would look something like this: << 1 2 3 4 5 - 12 13 14 - 78 79 80 81 82 >>
With only a few pages: << 1 2 3 4 5 6 7 8 9 10 >>
And how to avoid this?: << 1 2 3 4 5 - 5 6 7 - 7 8 9 10 11 >>
My code so far is:
function pagination_links($page, $num_rows, $results_per_page, $each_direction = 3)
{
$total_pages = $num_rows ? ceil($num_rows / $results_per_page) : 1 ;
if($total_pages < 2)
{
return null;
}
$page = ((is_numeric($page)) && ($page >= 1) && ($page <= $total_pages)) ? (int)$page : 1 ;
$output = null;
if($page > 1)
{
$output .= '<div class="pageBtn"><<</div>' ;
}
else
{
$output .= '<div class="pageBtnDis"><<</div>' ;
}
for($i=1;$i<$total_pages;$i++)
{
if($page != $i)
{
$output .= '<div class="pageBtn">' . $i . '</div>' ;
}
else
{
$output .= '<div class="pageBtnSet">' . $i . '</div>' ;
}
if($i > 4)
{
break ;
}
}
for($i = $page - $each_direction; $i <= $page + $each_direction; $i++)
{
if(($i > 5) && ($i <= $total_pages-5))
{
if($page != $i)
{
$output .= '<div class="pageBtn">' . $i . '</div>' ;
}
else
{
$output .= '<div class="pageBtnSet">' . $i . '</div>' ;
}
}
}
for($i = $total_pages-5;$i<$total_pages;$i++) {
if($page != $i)
{
$output .= '<div class="pageBtn">' . $i . '</div>' ;
}
else
{
$output .= '<div class="pageBtnSet">' . $i . '</div>' ;
}
}
if($page < $total_pages)
{
$output .= '<div class="pageBtn">>></div>' ;
}
else
{
$output .= '<div class="pageBtnDis">>></div>' ;
}
return $output ;
}
I think the current best solution is to use Digg Style Pagination Class. It greatly simplifies the creation and styling of your pagination markup.
The Pager PEAR class is highly customizable and I've had a lot of success with it.
Related
I want to limit the pages out of the total number of pages.
Example: 1 2 3 4 5 6 >> out of 30
Example2: << 5 6 7 8 9 10 >> out of 30
Here is my code:
$page = !empty($_GET['page']) ? (int) $_GET['page'] : 1;
// records per page
$per_page = 5;
// total records in database
$total_count = Mp3_Model::count_all();
// instantating the $pagination
$pagination = new Pagination($page, $per_page, $total_count);
// find the records for this page
$sql = "SELECT * FROM mp3 ";
$sql .= " LIMIT {$per_page} ";
$sql .= " OFFSET {$pagination->offset()}";
$mp3s = Mp3_Model::find_by_sql($sql);
foreach ($mp3s as $mp3) {
echo $mp3->titlu;
}
and this is the pagination:
<?php
if ($pagination->total_pages() > 1) {
if ($pagination->has_previous_page()) {
echo '<li>«</li>';
}
for ($i = 1; $i <= $pagination->total_pages(); $i++) {
echo '<li';
if ($_GET['page'] == $i) {
echo ' class="active"';
}
echo '>' . $i . '</li>';
}
if ($pagination->has_next_page()) {
echo '<li>» </li>';
}
}
?>
You can use jQuery pagination, it is a much better solution.
I'm trying to accomplish this, with the 360 grid system: http://imgur.com/4ZFll
From a database i'm getting products which will be displayed in lines with 4 on each.
It's working perfectly if there is exactly 4 products under each category, but if there is less than 4 products in a category, the design is messed up, because the div's not closed properly.
Problem is that sometimes there's only 3 or less products on a line.
Is there any of you who knows how to accomplish this?
for($i=0 ; $i<$countprod ; $i++){
$prevprod = $products[$i-1]['name'];
$curprod = $products[$i]['name'];
if($curprod != $prevprod){
echo '<div class="grid_12 alpha omega"><h2>'.$products[$i]['catname'].'</h2></div>';
}
if ($i == 0){ echo '<div class="grid_3 '; }
if ($i % 4 == 0) { echo ' alpha">'; }
elseif($i % 4 == 3) { echo '</div><div class="grid_3 omega">'; }
else{ echo '</div><div class="grid_3">';
}
echo $product[$i]['image'];
if ($i % 4 == 3) {
echo '</div><div class="clear"></div>';
echo '<div class="grid_3';
}
}
(sorry about the title, i didnt know what to call this question :) )
echo '<div class="grid_3';
You aren't closing this tag.
Have a try with
$countprod = count($product);
$prevprod = '';
$close_div = false;
for ($i=0; $i<$countprod; $i++){
$curprod = $products[$i]['name'];
if($curprod != $prevprod){
if ($close_div) echo '</div>';
echo '<div class="grid_12 alpha omega"><h2>'.$products[$i]['catname'].'</h2></div>';
}
if ($i % 4 == 0) {
echo '<div class="grid_3 alpha">';
$close_div = true;
}
elseif ($i % 4 == 3) {
echo '</div><div class="grid_3 omega">';
$close_div = true;
}
else {
echo '</div><div class="grid_3">';
$close_div = true;
}
echo $product[$i]['image'];
if ($i % 4 == 3) {
echo '</div><div class="clear"></div>';
$close_div = false;
}
$prevprod = $curprod;
}
$p = 10; // Current number of products
$ppr = 4; // Products per row
$x = $i % $ppr;
if($x != 0){
$countprod = $p + ($ppr - $x);
}
echo $countprod; // 12 (4 * 3)
Loop with FOR if there is no product just print empty DIV, if that's what you have asked...
I need to make a paging with this format:
1 2 3 4 5 ... 205
i use now this for loop:
$nav = '';
for($pageNum = 1; $pageNum <= $maxPage; $pageNum++)
{
if ($pageNum == $p)
{
$nav .= '<li class=\"current\">$pageNum</li>';
}
else
{
$nav .= '<li>$pageNum</li>';
}
}
i need to use a php break or continue??
Here there ara an example http://www.programacion.com/articulo/paginar_los_resultados_de_una_consulta_en_php_149
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;
}
}
I asked a similar question like this yesterday but after waiting for ever I figured out part of the problem but now I'm stuck again I'm trying to display ... when the search results are to long because my pagination links will keep on displaying and will not stop until every link is displayed on the page.
For example I'm trying to achieve the following in the example below. Can some one help me fix my code so I can update my site. Thanks
This is what I want to be able to do.
First Previous 1 2 ... 5 6 7 8 9 10 11 12 13 ... 199 200 Next Last
Here is my pagination code that displays the links.
$display = 20;
if (isset($_GET['p']) && is_numeric($_GET['p'])) {
$pages = $_GET['p'];
} else {
$q = "SELECT COUNT(id) FROM comments WHERE user_id=3";
$r = mysqli_query ($mysqli, $q) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($mysqli));
$row = mysqli_fetch_array ($r, MYSQLI_NUM);
$records = $row[0];
if ($records > $display) {
$pages = ceil ($records/$display);
} else {
$pages = 1;
}
}
if (isset($_GET['s']) && is_numeric($_GET['s'])) {
$start = $_GET['s'];
} else {
$start = 0;
}
//content goes here
if ($pages > 1) {
echo '<br /><p>';
$current_page = ($start/$display) + 1;
if ($current_page != 1) {
echo 'First';
}
if ($current_page != 1) {
echo 'Previous ';
}
for ($i = 1; $i <= $pages; $i++) {
if ($i != $current_page) {
echo '' . $i . ' ';
} else {
echo '<span>' . $i . '</span> ';
}
}
if ($current_page != $pages) {
echo 'Next';
}
if ($current_page != $pages) {
echo 'Last';
}
echo '</p>';
}
Instead of the loop just use something like this:
if($current_page > 8 && $pages > 11) {
echo '1 ';
echo '2 ';
echo '...';
}
for ($i = max(1, $current_page - 4); $i < min($current_page + 4, $pages); $i ++) {
echo '' . $i . ' ';
}
if ($current_page < $pages - 8 && $pages > 11) {
echo '...';
echo '' . ($pages - 1) . ' ';
echo '' . $pages . ' ';
}