Page 1 of 1
Advanced pagination
Posted: Fri Oct 27, 2006 1:33 pm
by tom1971
Hello fellas...
I've created a simple page which fetches results from a mysql database and displays them with pagination. Currently it doesn't limit the number of pages shown, so if there are 26 pages and page 14 was selected, it would look something like this:
Prev 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 Next
I think there are too far too many pages displayed I would rather display the links in a phpbb style, something like this:
Prev 1 2 3 ... 24 25 26 Next
If that's too hard, how about braking up the page numbers in every 10 or 15, so it displays 10 or 15 pages instead of all pages, in this case 26, and then take you to the next page that displays the next, (or previous), 10 or 15 pages and so forth...
Has anyone done this before?
If you need the code I'm using I can post it.
Any help will be greatly appreciated
Thanks
Posted: Fri Oct 27, 2006 1:39 pm
by Burrito
this is one I wrote.
I abandoned the <form> method so don't use that (unless you wanna clean it up some)....this means you'll have to have sessions working for this method to work:
Code: Select all
// pagination method sets paginate property and also returns results ...burrito
public function pagination($increments=10,$type="sess")
{
$this->paginate = '';
if($type == "sess")
{
$start = (isset($_GET['start']) ? $_GET['start'] : 0);
$page = (isset($_GET['page']) ? $_GET['page'] : 1);
$this->query = (isset($this->query) ? $this->query : $_SESSION['query']);
$_SESSION['query'] = $this->query;
}
else
{
$start = (isset($_POST['start']) ? $_POST['start'] : 0);
$page = (isset($_POST['page']) ? $_POST['page'] : 1);
$this->query = (isset($_POST['query']) ? $_POST['query'] : $this->query);
$this->query = stripslashes($this->query);
$this->paginate .= '<form method="post" style="margin:0px;padding:0px">';
$this->paginate .= '<input type="hidden" name="query" value="'.$this->query.'">';
$this->paginate .= '<input type="hidden" name="start" value="'.$start.'">';
$this->paginate .= '<input type="hidden" name="page" value="'.$page.'">';
}
$this->select();
$nu = $this->numrows;
$this->query .= " LIMIT $start,$increments";
$pages = ceil($nu/$increments);
$result = $this->select();
$next = ($start + $increments);
$prev = ($start - $increments);
$nextpage = ($page + 1);
$prevpage = ($page - 1);
if($type == "sess")
{
$this->paginate .= ($start != 0 ? "<a href=\"{$_SERVER['PHP_SELF']}?start=$prev&page=$prevpage\" class=\"paginate\">««Prev</a> " : '');
}
else
{
$this->paginate .= ($start != 0 ? "<label onClick=\"this.form.start.value=$prev,this.form.page.value=$prevpage,this.form.submit()\" style=\"cursor:pointer;cursor:hand\" class=\"paginate\">««Prev</label>" : '');
}
// if there are 10 or less pages, just show them all
if($pages > 1 && $pages <= 10)
{
$this->paginate = '<span class="paginate"><b>Goto Page:</b></span> '.$this->paginate;
$thstart = 0;
for($i=1;$i<$pages+1;$i++)
{
if($type == "sess")
{
$this->paginate .= ($page == $i ? "<span class=\"paginate\"><b>$i</b></span>," : "<a href=\"{$_SERVER['PHP_SELF']}?start=$thstart&page=$i\" class=\"paginate\">$i</a>,");
}
else
{
$this->paginate .= ($page == $i ? "<label class=\"paginate\">$i</label>" : "<label onClick=\"this.form.start.value=$thstart,this.form.page.value=$i,this.form.submit()\" style=\"cursor:pointer;cursor:hand;text-decoration:underline\" class=\"paginate\">$i</label>");
}
$thstart += $increments;
}
$this->paginate = substr($this->paginate,0,strlen($this->paginate) -1);
}
// if there are more than 10 pages, create elipses between extra pages
else if($pages > 10)
{
$this->paginate = '<span class="paginate"><b>Goto Page:</b></span> '.$this->paginate;
$thstart = 0;
for($i=1;$i<4;$i++)
{
if($type == "sess")
{
$this->paginate .= ($page == $i ? "<span class=\"paginate\"><b>$i</b></span>," : "<a href=\"{$_SERVER['PHP_SELF']}?start=$thstart&page=$i\" class=\"paginate\">$i</a>,");
}
else
{
$this->paginate .= ($page == $i ? "<label class=\"paginate\">$i</label>" : "<label onClick=\"this.form.start.value=$thstart,this.form.page.value=$i,this.form.submit()\" style=\"cursor:pointer;cursor:hand;text-decoration:underline\" class=\"paginate\">$i</label>");
}
$thstart += $increments;
}
// remove last comma unless it's page 3 or 4 or 5
$this->paginate = ($page != 4 && $page != 3 && $page != 5? substr($this->paginate,0,strlen($this->paginate) -1) : $this->paginate);
if($page >= 6)
$this->paginate .= "...";
if($page > 2 && $page < ($pages - 1))
{
for($i=$page-1;$i<$page+2;$i++)
{
if($i != 2 && $i != 3 && $i != ($pages-2) && $i != ($pages-1))
{
$thstart = ($i * $increments) - $increments;
if($type == "sess")
{
$this->paginate .= ($page == $i ? "<span class=\"paginate\"><b>$i</b></span>," : "<a href=\"{$_SERVER['PHP_SELF']}?start=$thstart&page=$i\" class=\"paginate\">$i</a>,");
}
else
{
$this->paginate .= ($page == $i ? "<label class=\"paginate\">$i</label>" : "<label onClick=\"this.form.start.value=$thstart,this.form.page.value=$i,this.form.submit()\" style=\"cursor:pointer;cursor:hand;text-decoration:underline\" class=\"paginate\">$i</label>");
}
}
}
// remove the last comma if necessary
$this->paginate = ($page < ($pages - 4) ? substr($this->paginate,0,strlen($this->paginate) -1) : $this->paginate);
}
if($page < $pages -4)
$this->paginate .= "...";
for($i=$pages-2;$i<$pages+1;$i++)
{
$thstart = ($i * $increments) - $increments;
if($type == "sess")
{
$this->paginate .= ($page == $i ? "<span class=\"paginate\"><b>$i</b></span>," : "<a href=\"{$_SERVER['PHP_SELF']}?start=$thstart&page=$i\" class=\"paginate\">$i</a>,");
}
else
{
$this->paginate .= ($page == $i ? "<label class=\"paginate\">$i</label>" : "<label onClick=\"this.form.start.value=$thstart,this.form.page.value=$i,this.form.submit()\" style=\"cursor:pointer;cursor:hand;text-decoration:underline\" class=\"paginate\">$i</label>");
}
}
// remove the last comma
$this->paginate = substr($this->paginate,0,strlen($this->paginate) -1);
}
if($type == "sess")
{
$this->paginate .= ($start < ($nu - $increments) ? " <a href=\"{$_SERVER['PHP_SELF']}?start=$next&page=$nextpage\" class=\"paginate\">Next »»</a>" : '');
}
else
{
$this->paginate .= ($start < ($nu - $increments) ? " <label onClick=\"this.form.start.value=$next,this.form.page.value=$nextpage,this.form.submit()\" style=\"cursor:pointer;cursor:hand\" class=\"paginate\">Next »»</label>" : '');
}
if($type != "sess")
$this->paginate .= '</form>';
return $result;
}
Posted: Fri Oct 27, 2006 2:04 pm
by tom1971
thanx for your help Burrito, but this seems too complex for me.
Can you clean it up for me? I don't need the search form.
And what do you mean by: "this means you'll have to have sessions working for this method to work"?
thanx
Posted: Fri Oct 27, 2006 2:07 pm
by RobertGonzalez
This is a fork of the phpBB paging code, in procedural style (just like the app). Keep in mind that utilized a version of their append_sid function as well, which you will see here. If you haven't created that function you will get a fatal error 'call to undefined function'...
Code: Select all
<?php
/*
NOTE: $lang is an array var that stores the sites language, like 'Next', 'Previous' and 'Go to page'
You will need to either edit that in this function or utilize one for this function
*/
/**
* @return str
* @param $base_url
* @param $num_items
* @param $per_page
* @param $start_item
* @param $add_prenext_text = 1
* @desc Returns the pagination string
*/
function generate_pagination($base_url, $num_items, $per_page, $start_item, $add_prevnext_text = 1)
{
global $lang;
$get_connector = ( strstr($base_url, "?") ) ? '&' : '?';
$total_pages = ceil($num_items/$per_page);
if ( $total_pages == 1 )
{
return '';
}
$on_page = floor($start_item / $per_page) + 1;
$page_string = '';
if ( $total_pages > 10 )
{
$init_page_max = ( $total_pages > 3 ) ? 3 : $total_pages;
for($i = 1; $i < $init_page_max + 1; $i++)
{
//$page_string .= ( $i == $on_page ) ? '<b>' . $i . '</b>' : '<a href="' . $base_url . "start=" . ( ( $i - 1 ) * $per_page ) . '">' . $i . '</a>';
$page_string .= ( $i == $on_page ) ? '<b>' . $i . '</b>' : '<a href="' . append_sid($base_url . $get_connector . "start=" . ( ( $i - 1 ) * $per_page ) ) . '">' . $i . '</a>';
if ( $i < $init_page_max )
{
$page_string .= ", ";
}
}
if ( $total_pages > 3 )
{
if ( $on_page > 1 && $on_page < $total_pages )
{
$page_string .= ( $on_page > 5 ) ? ' ... ' : ', ';
$init_page_min = ( $on_page > 4 ) ? $on_page : 5;
$init_page_max = ( $on_page < $total_pages - 4 ) ? $on_page : $total_pages - 4;
for($i = $init_page_min - 1; $i < $init_page_max + 2; $i++)
{
//$page_string .= ($i == $on_page) ? '<b>' . $i . '</b>' : '<a href="' . $base_url . "start=" . ( ( $i - 1 ) * $per_page ) . '">' . $i . '</a>';
$page_string .= ($i == $on_page) ? '<b>' . $i . '</b>' : '<a href="' . append_sid($base_url . $get_connector ."start=" . ( ( $i - 1 ) * $per_page ) ) . '">' . $i . '</a>';
if ( $i < $init_page_max + 1 )
{
$page_string .= ', ';
}
}
$page_string .= ( $on_page < $total_pages - 4 ) ? ' ... ' : ', ';
}
else
{
$page_string .= ' ... ';
}
for($i = $total_pages - 2; $i < $total_pages + 1; $i++)
{
//$page_string .= ( $i == $on_page ) ? '<b>' . $i . '</b>' : '<a href="' . $base_url . "start=" . ( ( $i - 1 ) * $per_page ) . '">' . $i . '</a>';
$page_string .= ( $i == $on_page ) ? '<b>' . $i . '</b>' : '<a href="' . append_sid($base_url . $get_connector . "start=" . ( ( $i - 1 ) * $per_page ) ) . '">' . $i . '</a>';
if( $i < $total_pages )
{
$page_string .= ", ";
}
}
}
}
else
{
for($i = 1; $i < $total_pages + 1; $i++)
{
//$page_string .= ( $i == $on_page ) ? '<b>' . $i . '</b>' : '<a href="' . $base_url . "start=" . ( ( $i - 1 ) * $per_page ) . '">' . $i . '</a>';
$page_string .= ( $i == $on_page ) ? '<b>' . $i . '</b>' : '<a href="' . append_sid($base_url . $get_connector . "start=" . ( ( $i - 1 ) * $per_page ) ) . '">' . $i . '</a>';
if ( $i < $total_pages )
{
$page_string .= ', ';
}
}
}
if ( $add_prevnext_text )
{
if ( $on_page > 1 )
{
//$page_string = ' <a href="' . $base_url . "start=" . ( ( $on_page - 2 ) * $per_page ) . '">' . $lang['previous_page'] . '</a> ' . $page_string;
$page_string = ' <a href="' . append_sid($base_url . $get_connector . "start=" . ( ( $on_page - 2 ) * $per_page ) ) . '">' . $lang['previous_page'] . '</a> ' . $page_string;
}
if ( $on_page < $total_pages )
{
//$page_string .= ' <a href="' . $base_url . "start=" . ( $on_page * $per_page ) . '">' . $lang['next_page'] . '</a>';
$page_string .= ' <a href="' . append_sid($base_url . $get_connector ."start=" . ( $on_page * $per_page ) ) . '">' . $lang['next_page'] . '</a>';
}
}
$page_string = $lang['goto_page'] . ' ' . $page_string;
return $page_string;
}
?>
Then you call it like this...
Code: Select all
<?php
$sql = "SELECT * FROM `mytable` ORDER BY `myfield` ASC";
if (!$result = mysql_query($sql))
{
die('Could not get info: ' . mysql_error());
}
$info_list = array();
while ($row = mysql_fetch_array($result))
{
$info_list[] = $row;
}
/**************************************************************************************************
*
* Set paging information
*
**************************************************************************************************/
$total_items = count($info_list); // example: 47
$per_page = 40;
$start = 0;
if (!isset($_GET['show_all']))
{
$start = ( isset($_GET['start']) ) ? intval($_GET['start']) : $start;
if ($start <> 0)
{
// Start was set and is now at least 10
$page_limit = ( ($total_items - $start) < $per_page) ? $total_items : ($start + $per_page);
}
else
{
$page_limit = $per_page;
}
}
else
{
$start = 0;
$page_limit = $total_items;
}
echo generate_pagination(basename(__FILE__), $total_items, $per_page, $start);
?>
Posted: Fri Oct 27, 2006 2:23 pm
by tom1971
feyd | Please use Code: Select all
and [syntax="..."] tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read: [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url] to learn how to do it too.[/color]
thanx for your help Everah..
But, again this seems too hard for me to understand.
I am a newbie.
Here is the code i use:
Code: Select all
$Limit = 10; //Number of results per page
$SearchString=$_POST["SearchString"]; // Get the search tearm
If($SearchString == "") $SearchString=$_GET["SearchString"]; // Get the search tearm
If($SearchString == "") {
Echo"Nothing to Search For";
exit();
}
$page=$_GET["page"]; //Get the page number to show
If($page == "") $page=1; //If no page number is set, the default page is 1
//Get the number of results
$SearchResult=mysql_query("SELECT * FROM article_news WHERE title LIKE '%$SearchString%' ORDER BY title") or die(mysql_error());
$NumberOfResults=mysql_num_rows($SearchResult);
//Get the number of pages
$NumberOfPages=ceil($NumberOfResults/$Limit);
$SearchResult=mysql_query("SELECT * FROM article_news WHERE title LIKE '%$SearchString%' ORDER BY title LIMIT " . ($page-1)*$Limit . ",$Limit") or die(mysql_error());
While($row = mysql_fetch_object($SearchResult)) {
echo "<table border='0'>";
echo "<tr><td width=50 align=center>";
Echo $row->id. "";
echo "</td><td width=150 align=center>";
Echo $row->date . "";
echo "</td><td width=250 align=left>";
Echo "<A HREF=\"http://www.mydomain.com/about/news.php?articleid=$row->id\">$row->title</A><br>";
echo "</table>";
}
$Nav="<b>Goto page </b>";
If($page > 1) {
$Nav .= "<A HREF=\"?page=" . ($page-1) . "&SearchString=" .urlencode($SearchString) . "\"><b><< Previous</b></A>";
}
For($i = 1 ; $i <= $NumberOfPages ; $i++) {
If($i == $page) {
$Nav .= " <B>$i</B> ";
}Else{
$Nav .= " <A HREF=\"?page=" . $i . "&SearchString=" .urlencode($SearchString) . "\">$i</A> ";
}
}
If($page < $NumberOfPages) {
$Nav .= "<A HREF=\"?page=" . ($page+1) . "&SearchString=" .urlencode($SearchString) . "\"><b> Next >> </b></A>";
}
Echo "<BR><BR>" . $Nav;
It works fine, but how can I break that up?
feyd | Please use Code: Select all
and [syntax="..."] tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read: [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url] to learn how to do it too.[/color]
Posted: Fri Oct 27, 2006 3:00 pm
by RobertGonzalez
The only way to break it up is with logic. Basically, during the loop, check to see if $i is more than 3 (or however many) and if it is, instead of throwing all of the $i number of pages into the list, throw out a '...' instead. There is a lot more to it, but that is the logic in essence. Try looking through what burrito and I posted to see if you can spot that logic, then try to apply it to your code.
Posted: Fri Oct 27, 2006 5:45 pm
by tom1971
Everah wrote:The only way to break it up is with logic. Basically, during the loop, check to see if $i is more than 3 (or however many) and if it is, instead of throwing all of the $i number of pages into the list, throw out a '...' instead. There is a lot more to it, but that is the logic in essence. Try looking through what burrito and I posted to see if you can spot that logic, then try to apply it to your code.
I've been going around in circles getting nowhere.. I spent hours..
I'm not gonna spend anymore time trying to figure out something that's out of my league.
Like I said I am a newb, and I want something simple to brake up the page links in 5 or 10 or whatever.
If you can help me I'd appreciate it.
No more riddles or lessons, or "logic" please..

It reminds me of my grammar school days!!!
Nothing complex or sophisticated like the phpBB, (I gave up on that as you can see). Just a simple solution with concrete and solid advise or preferebly the
code for the "brake" to add to my existing code. Is it possible?
thanx
Posted: Fri Oct 27, 2006 5:57 pm
by RobertGonzalez
Our community has a little mantra around here: We will help you solve the problem, but we won't do it for you unless you pay us. Basically, we volunteer our time to help. But we charge to do work. If this is something that is absolutely necessary for your web site, and you have no unction to learn it (not that that is a bad thing) then you may want to consider posting your project in the Job hunt forum. I am sure there are plenty of developers that would be willing to take this on for a few bucks.
Posted: Fri Oct 27, 2006 6:07 pm
by georgeoc
This forum is meant to guide you through solving problems yourself - I don't expect Everah or Burrito will want to write your code for you. If you have a think about what rules you'd like your system to follow, post them here and we can come up with a solution together.
Taking the phpBB system as a start, you need to think about these questions:
- Do you want to display a list of all pages, or only a selection - 14 15 16
- If only a selection, how many pages before and after the current page should be displayed? - 12 13 14 15 16 17 18
- Should the current page be a hyperlink or not? Should it be highlighted? - 14 15 16
- Do you want the first and last page(s) to always be displayed? - 1 2 3 ... 14 15 16 ... 23 24 25
- Should there be previous and next buttons?
- Should there be first and last buttons?
Posted: Fri Oct 27, 2006 7:14 pm
by tom1971
I respect the Forum rules by all means.
Right now I'd skip the phpbb format and possibly deal with that in the future.
I'm happy with the code I'm using for the time being. You can see it
here
<< Previous 1 2 3
4 5 6 Next >>
I've got it to display four articles per page. What I want is to, say, display page links 1 through 4. Then click on "next" and get page links 5 through 8 to display. And so forth and so on... And vise-versa...
And that's what I'm looking for. The code to be able to break up those page links, four at a time or five at a time or ten at a time, depending on how many page links I want to be displayed.
I'm trying to avoid this from happening:
Prev 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 Next
Posted: Sat Oct 28, 2006 9:35 am
by RobertGonzalez
That logic is a little different, but not hugely different. What you have now is
<< Previous 1 2 3 4 5 6 Next >>
What you want is
<< Previous 1 2 3 4 Next >>
and then on to
<< Previous 5 6 7 8 Next >>
And so on, is that correct?
Posted: Sat Oct 28, 2006 10:21 am
by bokehman
Here's how I have done the links in the past:
example!
Code: Select all
function pagination_links($current_page, $num_rows, $results_per_page, $each_direction = 5)
{
$word_for_previous = 'previous';
$word_for_next = 'next';
$total_pages = $num_rows ? ceil($num_rows / $results_per_page) : 1 ;
$current_page = ((is_numeric($current_page)) and ($current_page >= 1) and ($current_page <= $total_pages)) ? (int)$current_page : 1 ;
$output = null;
if($current_page > 1)
{
$output .= '<a href="'.htmlentities($_SERVER['PHP_SELF']).'?page='.($current_page - 1).'">'.$word_for_previous.'</a> | '."\n";
}
for($i = $current_page - $each_direction; $i <= $current_page + $each_direction; $i++)
{
if(($i > 0) and ($i <= $total_pages))
{
$output .= isset($spacer) ? $spacer : null ;
$spacer = ' | '."\n";
if($current_page != $i)
{
$output .= '<a href="'.htmlentities($_SERVER['PHP_SELF']).'?page='.$i.'">'.$i.'</a>'."\n";
}
else
{
$output .= $i."\n";
}
}
}
if($current_page < $total_pages)
{
$output .= ' | <a href="'.htmlentities($_SERVER['PHP_SELF']).'?page='.($current_page + 1).'">'.$word_for_next.'</a>'."\n";
}
return '<p class="pagination-links">'."\n".$output."\n".'</p>';
}
Posted: Sat Oct 28, 2006 10:21 am
by tom1971
Everah wrote:That logic is a little different, but not hugely different. What you have now is
<< Previous 1 2 3 4 5 6 Next >>
What you want is
<< Previous 1 2 3 4 Next >>
and then on to
<< Previous 5 6 7 8 Next >>
And so on, is that correct?
Yes Everah, that is correct. And the code I'm using is above, in the middle of this thread.
Posted: Sat Oct 28, 2006 11:51 am
by Burrito
if you disect mine a bit, you'll see it's exactly like phpBB's.
<< Prev 1,2,3...7,8,9...15,16,17 Next >>
look at the section that starts right after this comment:
// remove last comma unless it's page 3 or 4 or 5
example here:
http://www.burritostand.com/hearing/license.php
How paging for foreach loop
Posted: Wed Nov 01, 2006 6:33 am
by dharprog
Hi,
How can i do paging for foreach loop in php ? cos if the data is coming from database i can use offset and or limit from the query when it comes to foreach loop means some array how can i do paging if the elements lot and to limit in the page?
How can i do? Plz help anybody?
Thank YOu...