-
Notifications
You must be signed in to change notification settings - Fork 4
Flexible Paging Plugin
Want a better paging solution than what CI provides.
Paging can displayed in number of ways, as links, as a select box like in phpmyadmin, or maybe even as links with a javascript attach for ajax purposes -> which I do frequently.
Then I realize that I don't need CI to generate the links for me, but I just need the values needed to form the paging.
So I made the following code which you can insert in a CodeIgniter plugin.
<?
function paging($page,$rp,$total,$limit)
{
$limit -= 1;
$mid = floor($limit/2);
if ($total>$rp)
$numpages = ceil($total/$rp);
else
$numpages = 1;
if ($page>$numpages) $page = $numpages;
$npage = $page;
while (($npage-1)>0&&$npage>($page-$mid)&&($npage>0))
$npage -= 1;
$lastpage = $npage + $limit;
if ($lastpage>$numpages)
{
$npage = $numpages - $limit + 1;
if ($npage<0) $npage = 1;
$lastpage = $npage + $limit;
if ($lastpage>$numpages) $lastpage = $numpages;
}
while (($lastpage-$npage)<$limit) $npage -= 1;
if ($npage<1) $npage = 1;
//echo $npage; exit;
$paging['first'] = 1;
if ($page>1) $paging['prev'] = $page - 1; else $paging['prev'] = 1;
$paging['start'] = $npage;
$paging['end'] = $lastpage;
$paging['page'] = $page;
if (($page+1)<$numpages) $paging['next'] = $page + 1; else $paging['next'] = $numpages;
$paging['last'] = $numpages;
$paging['total'] = $total;
$paging['iend'] = $page * $rp;
$paging['istart'] = ($page * $rp) - $rp + 1;
if (($page * $rp)>$total) $paging['iend'] = $total;
return $paging;
}
?>
You have to pass 4 parameters:
$page is the current page, this is the number of the current page and not the limit and start values usually used in sql queries. you can convert it into a start for sql query like so:
$start = (($page-1) * $rp);
$rp is results per page. $total is the total number of results. $limit is the number of page values you want to display, this will allow you limit the number of pages to display if the result of your query results in too many pages. Like in google search results, where the current page is also displayed in the middle.
You can then pass it to a variable, and it will return an array. with the following values:
$paging = paging($page,$rp,$total,$limit);
$paging['start'] = starting page value. $paging['end'] = ending page value $paging['last'] = last page
$paging['total'] = number of results $paging['istart'] = starting result number for current page $paging['iend'] = ending result number for current page
The last three values can be use for something like: Displaying 1 to 10 of 100 items.
In CI you can pass it on to a $data which you can use for views like so:
$data['pg'] = $paging;
You can then use it like this.
<div class="pages">
<div class="inside">
<a href="<?=site_url('models/page/'.$pg['first'])?>" title="Go to First Page" class="first"><span>«</span></a>
<a href="<?=site_url('models/page/'.$pg['prev'])?>" title="Go to Previous Page" class="prev"><span>‹</span></a>
<? for ($i=$pg['start'];$i<=$pg['end'];$i++) {
if ($i==$pg['page']) $current = 'current'; else $current="";
?>
<a href="<?=site_url("models/page/$i")?>" title="Go to Page <?=$i?>" class="page <?=$current?>"><span><?=$i?></span></a>
<? } ?>
<a href="<?=site_url('models/page/'.$pg['next'])?>" title="Go to Next Page" class="next"><span>›</span></a>
<a href="<?=site_url('models/page/'.$pg['last'])?>" title="Go to Last Page" class="last"><span>»</span></a>
</div>
</div>
This is just a simple links example. As I said you can get really creative on how you want to display your paging. You can simply change it to a select box.
You can use it as is or modify it, but give me some credit if you are going to include it on your own framework or something.
Have fun and let me know how you used it.
Paulo P. Marinas
Thank you Paulo for this solution... It really helped me a lot.
I created a plugin (as you suggested) in my system/application/plugins/ folder, but because I needed to show the links produced by your function more than once on a page, I decided to create another little function which takes as parameters the array returned by your function and a $links parameter.
Here it is:
function pagination($link, $paging_data) {
$links = "";
// The first page
$links .= anchor($link . '/' . $paging_data['first'], 'First', array('title' => 'Go to the first page', 'class' => 'first_page'));
$links .= "\n";
// The previous page
$links .= anchor($link . '/' . $paging_data['prev'], '<', array('title' => 'Go to the previous page', 'class' => 'prev_page'));
$links .= "\n";
// The other pages
for ($i = $paging_data['start']; $i <= $paging_data['end']; $i++) {
if ($i == $paging_data['page'])
$current = ' current';
else
$current = "";
$links .= anchor($link . '/' . $i, $i, array('title' => 'Go to page ' . $i, 'class' => 'page' . $current));
$links .= "\n";
}
// The next page
$links .= anchor($link . '/' . $paging_data['next'], '>', array('title' => 'Go to the next page', 'class' => 'next_page'));
$links .= "\n";
// The last page
$links .= anchor($link . '/' . $paging_data['last'], 'Last', array('title' => 'Go to the last page', 'class' => 'last_page'));
$links .= "\n";
return $links;
}
I have a class named Components in which I have functions for creating navigational menus and other components/modules for my site, so I included here this tiny function. So now I am using it like this:
Load the Components library in the controller:
$this->load->library('components');
Including it into a view:
$paging_current_page = ...;
$paging_results_per_page = 10;
$paging_total = ...;
$paging_limit = 6;
$data['pagination_links'] = $this->components->pagination("categories/view/page", paging($paging_current_page, $paging_results_per_page, $paging_total, $paging_limit));
$this->load->view('views/categories', $data);
And in the 'categories' view, where I need to show the links, I have the following:
<?= $pagination_links ?>