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
Related
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.
Ive trying to make a pagination with CodeIgniter, it should be so simple according the manual of Codeigniter, even in the example is like this
« First < 1 2 3 4 5 > Last »
$config['total_rows'] = $this->searchdesc_model->queryallrows();
$config['per_page'] = '10';
$config['uri_segment'] =4;
$config['full_tag_open'] = '<p>';
$config['full_tag_close'] = '</p>';
$config['cur_tag_open'] = '<b>';
$config['cur_tag_close'] = '</b>';
$config['first_link'] = 'First';
$config['last_link'] = 'Last';
$config['last_tag_open'] = '<p>';
$config['last_tag_close'] = '</p>'
$this->load->library('Company_Creation');
in the view I only call it like this pagination->create_links(); ?> (or I send it through the view when I call it from the controller, still I only get this
1 2 3 >
and there is no way to make it look like the exmaple, may sound so dummy but , anyone could help me with this? or have a problem similar?
Thanks
EDIT 1
$config['total_rows'] = $this->searchdesc_model->queryallrows();
$config['per_page'] = '5';
$config['uri_segment'] =4;
$config['full_tag_open'] = '<p>';
$config['full_tag_close'] = '</p>';
$config['cur_tag_open'] = '<b>';
$config['cur_tag_close'] = '</b>';
$config['first_link'] = ' First';
$config['last_link'] = ' Last';
$config['last_tag_open'] = '<p>';
$config['last_tag_close'] = '</p>';
$config['next_link'] = '';
$config['next_tag_open'] = '<p id="nextbutton" style="padding-left:5px;">';
$config['next_tag_close'] = '</p>';
$config['prev_link'] = '';
$config['prev_tag_open'] = '<p id="prevbutton" style="padding-right:5px;">';
$config['prev_tag_close'] = '</p>';
$config['num_links']=4;
$data['retorno'] = $this->searchdesc_model->queryalldb($config['per_page'],$this->uri->segment(4,0));
$config['total_rows']=1000;
$this->pagination->initialize($config);
I did this according some advices Ive recieve, like you said when are many data it works good, still I'd LOVE to show first and next button all time, I set total_rows after my query (which I call with the right number of rows) , and I tried before too and the results are the same, I also need to show only 4 numbers and I am ustying numb_links ... still doesnt work (I dont know why Ci docs say should work..) any idea?
Thanks!
To produce what the example shows is actually pretty easy. You just need to extend the Pagination's Library to accommodate this. I was able to do this. No matter how many pages you show it still shows first, last, back arrow, and forward arrow.
If you are wanting to show 5 pages at all times with the foward and back stuff you need to have that many results to fill that page. Then you set num_links to what you would want before and after if on the 3rd page. So it would be 2. My changes if you are on the 1st page make it display 4 pages after when applicable. See image below. White is current page. Green is pages available.
Hopefully I've explained everything correctly and this works for you. Let me know.
Controller
$this->pagingConfig = array();
$this->pagingConfig['base_url'] = 'URL';
$this->pagingConfig['total_rows'] = 0;//TOTAL ROWS
$this->pagingConfig['cur_page'] = 0;//CURRENT PAGE NUMBER
$this->pagingConfig['per_page'] = 0;//YOUR RESULTS PER PAGE
$this->pagingConfig['num_links'] = 2;//NUMBER OF LINKS BEFORE AND AFTER CURRENT PAGE IF ON PAGE ONE WILL SHOW 4 PAGES AFTERWARDS IF YOU HAVE ENOUGH RESULTS TO FILL THAT MANY
$this->pagingConfig['first_link'] = "<< First";
$this->pagingConfig['last_link'] = "Last >>";
$this->pagingConfig['full_tag_open'] = "<div class='pagination'>";
$this->pagingConfig['full_tag_close'] = "</div>";
$this->pagingConfig['last_tag_open'] = "";
$this->pagingConfig['first_tag_close'] = "";
$this->pagingConfig['anchor_class'] = "page";
$this->pagination->initialize($this->pagingConfig);
$strPaging = $this->pagination->create_links();
EXTENDED PAGINATION LIBRARY CALL
function create_links()
{
// EDIT: ADDED THIS BECAUSE COULDN'T SEEM TO SET THIS ANYWHERE ELSE
if ($this->anchor_class != '')
{
$this->anchor_class = 'class="'.$this->anchor_class.'" ';
}
// If our item count or per-page total is zero there is no need to continue.
if ($this->total_rows == 0 OR $this->per_page == 0)
{
return '';
}
// Calculate the total number of pages
$num_pages = ceil($this->total_rows / $this->per_page);
// Is there only one page? Hm... nothing more to do here then.
if ($num_pages == 1)
{
return '';
}
// Determine the current page number.
$CI =& get_instance();
if ($CI->config->item('enable_query_strings') === TRUE OR $this->page_query_string === TRUE)
{
if ($CI->input->get($this->query_string_segment) != 0)
{
$this->cur_page = $CI->input->get($this->query_string_segment);
// Prep the current page - no funny business!
$this->cur_page = (int) $this->cur_page;
}
}
else
{
if ($CI->uri->segment($this->uri_segment) != 0)
{
$this->cur_page = $CI->uri->segment($this->uri_segment);
// Prep the current page - no funny business!
$this->cur_page = (int) $this->cur_page;
}
}
$this->num_links = (int)$this->num_links;
if ($this->num_links < 1)
{
show_error('Your number of links must be a positive number.');
}
if ( ! is_numeric($this->cur_page))
{
$this->cur_page = 1;
}
// Is the page number beyond the result range?
// If so we show the last page
if ($this->cur_page > $this->total_rows)
{
$this->cur_page = ($num_pages - 1);
}
// EDIT: DON'T NEED THIS THE WAY I'VE CHANGED IT
// $uri_page_number = $this->cur_page;
// $this->cur_page = floor(($this->cur_page/$this->per_page) + 1);
// EDIT: START OF MODIFIED START AND END TO WORK HOW I WANT
$totalLinks = ($this->num_links*2)+1;
if($totalLinks > ($this->total_rows/$this->per_page))
{
$totalLinks = ceil($this->total_rows/$this->per_page);
}
//first page
if($this->cur_page == 1)
{
$start = 1;
$end = $start + $totalLinks - 1;
}
//middle pages
elseif($this->cur_page + $this->num_links <= $num_pages && $this->cur_page - $this->num_links > 0)
{
$start = $this->cur_page - $this->num_links;
$end = $this->cur_page + $this->num_links;
}
//last couple of pages
elseif(($this->cur_page + $totalLinks) > $num_pages)
{
$start = $num_pages - $totalLinks + 1;
$end = $num_pages;
//check to see if this is in the first half of links so it doesn't jump the paging
if($this->cur_page <= $this->num_links)
{
$start = 1;
$end = $start + $totalLinks - 1;
}
}
//first couple of pages
elseif(($this->cur_page - $totalLinks) < 1)
{
$start = 1;
$end = $start + $totalLinks - 1;
}
// EDIT: END OF MODIFIED START AND END TO WORK HOW I WANT
// EDIT: CODEIGNITERS BASE PAGING SETUP SEE ABOVE FOR MY CHANGES
// $start = (($this->cur_page - $this->num_links) > 0) ? $this->cur_page - ($this->num_links - 1) : 1;
// $end = (($this->cur_page + $this->num_links) < $num_pages) ? $this->cur_page + $this->num_links : $num_pages;
// Is pagination being used over GET or POST? If get, add a per_page query
// string. If post, add a trailing slash to the base URL if needed
if ($CI->config->item('enable_query_strings') === TRUE OR $this->page_query_string === TRUE)
{
$this->base_url = rtrim($this->base_url).'&'.$this->query_string_segment.'=';
}
else
{
$this->base_url = rtrim($this->base_url, '/') .'/';
}
// And here we go...
$output = '';
// Render the "First" link
// EDIT: CHANGED TO ALWAYS SHOW FIRST LINK AT LEAST
if ($this->first_link !== FALSE AND $this->cur_page != 1)
{
$first_url = ($this->first_url == '') ? $this->base_url."1" : $this->first_url;
$output .= $this->first_tag_open.'<a '.$this->anchor_class.'href="'.$first_url.'">'.$this->first_link.'</a>'.$this->first_tag_close;
}
else
{
$output .= $this->cur_tag_open.$this->first_link.$this->cur_tag_close;
}
// Render the "previous" link
// EDIT: CHANGED TO ALWAYS SHOW PREVIOUS LINK AT LEAST
if ($this->prev_link !== FALSE AND $this->cur_page != 1)
{
$i = $this->cur_page-1;
if ($i == 0 && $this->first_url != '')
{
$output .= $this->prev_tag_open.'<a '.$this->anchor_class.'href="'.$this->first_url.'">'.$this->prev_link.'</a>'.$this->prev_tag_close;
}
else
{
$i = ($i == 0) ? '' : $this->prefix.$i.$this->suffix;
$output .= $this->prev_tag_open.'<a '.$this->anchor_class.'href="'.$this->base_url.$i.'">'.$this->prev_link.'</a>'.$this->prev_tag_close;
}
}
else
{
$output .= $this->cur_tag_open.$this->prev_link.$this->cur_tag_close;
}
// EDIT: CHANGED THIS TO ALWAYS SHOW ALL LINKS WANTED EVEN IF ON FIRST PAGE
// Render the pages
if ($this->display_pages !== FALSE)
{
// Write the digit links
for ($loop = $start; $loop <= $end; $loop++)
{
// EDIT: DON'T NEED THIS THE WAY I'VE CHANGED IT
// $i = ($loop * $this->per_page) - $this->per_page;
if ($loop >= 0)
{
if ($this->cur_page == $loop)
{
$output .= $this->cur_tag_open.$loop.$this->cur_tag_close; // Current page
}
else
{
$n = ($loop == 0) ? '0' : $loop;
if ($n == '' && $this->first_url != '')
{
$output .= $this->num_tag_open.'<a '.$this->anchor_class.'href="'.$this->first_url.'">'.$loop.'</a>'.$this->num_tag_close;
}
else
{
$n = ($n == '') ? '' : $this->prefix.$n.$this->suffix;
$output .= $this->num_tag_open.'<a '.$this->anchor_class.'href="'.$this->base_url.$n.'">'.$loop.'</a>'.$this->num_tag_close;
}
}
}
}
}
// Render the "next" link
// EDIT: CHANGED TO ALWAYS SHOW NEXT LINK AT LEAST
if ($this->next_link !== FALSE AND $this->cur_page < $num_pages)
{
$output .= $this->next_tag_open.'<a '.$this->anchor_class.'href="'.$this->base_url.$this->prefix.($this->cur_page+1).$this->suffix.'">'.$this->next_link.'</a>'.$this->next_tag_close;
}
else
{
$output .= $this->cur_tag_open.$this->next_link.$this->cur_tag_close;
}
// Render the "Last" link
// EDIT: CHANGED TO ALWAYS SHOW LAST LINK AT LEAST
if ($this->last_link !== FALSE AND $this->cur_page != $num_pages)
{
$i = (($num_pages));
$output .= $this->last_tag_open.'<a '.$this->anchor_class.'href="'.$this->base_url.$this->prefix.$i.$this->suffix.'">'.$this->last_link.'</a>'.$this->last_tag_close;
}
else
{
$output .= $this->cur_tag_open.$this->last_link.$this->cur_tag_close;
}
// Kill double slashes. Note: Sometimes we can end up with a double slash
// in the penultimate link so we'll kill all double slashes.
$output = preg_replace("#([^:])//+#", "\\1/", $output);
// Add the wrapper HTML if exists
$output = $this->full_tag_open.$output.$this->full_tag_close;
return $output;
}
The only reason you get 1 2 3 > instead of « First < 1 2 3 4 5 > Last » is that you simply don't have enough rows in your result to generate more than 3 pages.
The "First" and "Last" links don't appear by default if you don't need them. It's not very clear from the documentation's example.
You won't get "Previous" links until you advance past page 1, the example is actually on page 3 (the "3" is bold).
Since you're providing your own templates in the configuration instead of using the defaults, your actual results will be slightly different.
If you want to do a quick test to see more links, just reduce your per_page to a lower number or include more rows in your total_rows. The total number of links shown can also be configured with num_links.
For those people who developing their CI app with PostgreSql and can't understand why pagination limit+offset works "weird":
Controller:
...
$offset = ($page-1)*$config["per_page"];
$this->reporting_model->some_fetch_method($id, $config["per_page"], $offset);
...
Model:
...
$this->db->limit($limit_perpage, $offset);
$this->db->where("id", $id);
$this->db->get('some_table');
...
I'm having a problem with my PHP pagination for a project.
It almost works but it doesn't seem to display the numbers correctly.
I want only 6 more page numbers to display after the selected and one before;
(also if you are on page one display 7 after)
For example:
If on Page 1: 1/2/3/4/5/6/7/8
If on Page 2: 1/2/3/4/5/6/7/8
If on Page 5: 4/5/6/7/8/9/10/11
If on Page 10: 9/10/11/12/13/14/15/16
This is my code so far...
if($page == ceil($NumOfPages) && $page != 1){
for($i = 1; $i <= ceil($NumOfPages)-1; $i++){
if($i > 0){
echo "{$i}";
}
}
}
if ($page == ceil($NumOfPages) ) {
$startPage = $page;
}else{
$startPage = 1;
}
for ($i = $startPage; $i <= $page+6; $i++){
if ($i <= ceil($NumOfPages)){
if($i == $page) {
echo "<a href='/page/$i/' title='View movies page $i' id='pagelisel'>$i</a> ";
}else{
echo "<a href='/page/$i/' title='View movies page $i' id='pageli'>$i</a> ";
}
}
}
Any help would be greatly appreciated,
Thanks!
I assumed that (partly for myself... ;) ):
$page is the selected page
$startPage is the first page number you want to show
$numPages is already ceil-ed
First you need to find $startPage. Depending whether $page is the first one (ie has the value one 1, another assumption) or not. Your check is slightly off, as it check if it is equal to the last page.
if($page == 1) {
$startPage = 1;
} else {
$startPage = $page - 1;
}
Then you need to find out the last page number you want to print ($lastPage). So check if $startPage is near the end and set ~$lastPage` accordingly:
if($startPage + 7 > $numPages) {
$endPage = $numPages;
} else {
$endPage = $startPage + 7;
}
Finally, use you for-loop which seem ok, but loop from $startPage to $endPage.
Here's an alternative approach that should work for you as well:
$pageCurrent = $page;
$pagePrevious = $pageCurrent-1;
$pageClass = '';
$pageStart = 1;
$pageEnd = $pageCurrent+6;
$pageMax = ceil($NumOfPages);
if($pageCurrent==1){
echo "1";
}else{
echo "$pagePrevious";
}
for($i = $pageStart; $i <= $pageEnd; $i++){
if($i <= $pageEnd){
if($i == 1 && $pageCurrent != 1){
$pageClass = 'selected';
}else{
$pageClass = '';
}
echo "$i";
}
}
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'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;
}
}