Welcome Guest, Not a member yet? Register   Sign In
Pagination using per_page to increment page numbers fix
#1

[eluser]Frank Wong[/eluser]
Problem: Pagination uses per_page attribute to increment page numbers.

Example:
per_page = 5;
Page 1 - /seg1/seg2/
Page 2 - /seg1/seg2/5
Page 3 - /seg1/seg2/10
etc

System:
CI 1.5.4
Windows XP Pro
Apache2
php5

Fixed Pagination.php->create_links():
I left the original code commented out where I made changes.
Hope this helps some people.

----------Begin----------
function create_links()
{
// 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);
// echo $num_pages;
// 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->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;
}

if ( ! is_numeric($this->cur_page))
{
$this->cur_page = 0;
}

if ($this->cur_page==0)
{
$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) * $this->per_page;
}

$uri_page_number = $this->cur_page;
// $this->cur_page = floor(($this->cur_page/$this->per_page) + 1);

// Calculate the start and end numbers. These determine
// which number to start and end the digit links with
$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;
//echo $start." ";
//echo $end;
// Add a trailing slash to the base URL if needed
$this->base_url = rtrim($this->base_url, '/') .'/';

// And here we go...
$output = '';

// Render the "First" link
if ($this->cur_page > $this->num_links)
{
$output .= $this->first_tag_open.'<a href="'.$this->base_url.'">'.$this->first_link.'</a>'.$this->first_tag_close;
}

// Render the "previous" link
// echo $this->num_links;
if (($this->cur_page - $this->num_links) >= 0)
{
// $i = $uri_page_number - $this->per_page;
$i = $this->cur_page - 1;
// echo $i;
if ($i == 0) $i = '';
$output .= $this->prev_tag_open.'<a href="'.$this->base_url.$i.'">'.$this->prev_link.'</a>'.$this->prev_tag_close;
}

// Write the digit links
for ($loop = $start -1; $loop <= $end; $loop++)
{
$i = ($loop * $this->per_page) - $this->per_page;
// $i = $loop;

if ($i >= 0)
{
if ($this->cur_page == $loop)
{
$output .= $this->cur_tag_open.$loop.$this->cur_tag_close; // Current page
}
else
{
// $n = ($i == 0) ? '' : $i;
$n = ($i == 0) ? '' : $loop;
$output .= $this->num_tag_open.'<a href="'.$this->base_url.$n.'">'.$loop.'</a>'.$this->num_tag_close;
}
}
}

// Render the "next" link
if ($this->cur_page < $num_pages)
{
// $output .= $this->next_tag_open.'<a href="'.$this->base_url.($this->cur_page * $this->per_page).'">'.$this->next_link.'</a>'.$this->next_tag_close;
$output .= $this->next_tag_open.'<a href="'.$this->base_url.($this->cur_page + 1).'">'.$this->next_link.'</a>'.$this->next_tag_close;
}

// Render the "Last" link
if (($this->cur_page + $this->num_links) < $num_pages)
{
// $i = (($num_pages * $this->per_page) - $this->per_page);
$i = $num_pages;
$output .= $this->last_tag_open.'<a href="'.$this->base_url.$i.'">'.$this->last_link.'</a>'.$this->last_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;
}
----------End----------
#2

[eluser]wiredesignz[/eluser]
Try to use the code elements in your post, makes reading easier!

Code:
function create_links()
{
// 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);
// echo $num_pages;
// 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->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;
}

if ( ! is_numeric($this->cur_page))
{
$this->cur_page = 0;
}

if ($this->cur_page==0)
{
$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) * $this->per_page;
}

$uri_page_number = $this->cur_page;
// $this->cur_page = floor(($this->cur_page/$this->per_page) + 1);

// Calculate the start and end numbers. These determine
// which number to start and end the digit links with
$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;
//echo $start.” “;
//echo $end;
// Add a trailing slash to the base URL if needed
$this->base_url = rtrim($this->base_url, ‘/’) .’/’;

// And here we go…
$output = ‘’;

// Render the “First” link
if ($this->cur_page > $this->num_links)
{
$output .= $this->first_tag_open.’<a href="’.$this->base_url.‘“>’.$this->first_link.’</a>’.$this->first_tag_close;
}

// Render the “previous” link
// echo $this->num_links;
if (($this->cur_page - $this->num_links) >= 0)
{
// $i = $uri_page_number - $this->per_page;
$i = $this->cur_page - 1;
// echo $i;
if ($i == 0) $i = ‘’;
$output .= $this->prev_tag_open.’<a href="’.$this->base_url.$i.‘“>’.$this->prev_link.’</a>’.$this->prev_tag_close;
}

// Write the digit links
for ($loop = $start -1; $loop <= $end; $loop++)
{
$i = ($loop * $this->per_page) - $this->per_page;
// $i = $loop;

if ($i >= 0)
{
if ($this->cur_page == $loop)
{
$output .= $this->cur_tag_open.$loop.$this->cur_tag_close; // Current page
}
else
{
// $n = ($i == 0) ? ‘’ : $i;
$n = ($i == 0) ? ‘’ : $loop;
$output .= $this->num_tag_open.’<a href="’.$this->base_url.$n.‘“>’.$loop.’</a>’.$this->num_tag_close;
}
}
}

// Render the “next” link
if ($this->cur_page < $num_pages)
{
// $output .= $this->next_tag_open.’<a href=“‘.$this->base_url.($this->cur_page * $this->per_page).’">’.$this->next_link.’</a>’.$this->next_tag_close;
$output .= $this->next_tag_open.’<a href=“‘.$this->base_url.($this->cur_page + 1).’">’.$this->next_link.’</a>’.$this->next_tag_close;
}

// Render the “Last” link
if (($this->cur_page + $this->num_links) < $num_pages)
{
// $i = (($num_pages * $this->per_page) - $this->per_page);
$i = $num_pages;
$output .= $this->last_tag_open.’<a href="’.$this->base_url.$i.‘“>’.$this->last_link.’</a>’.$this->last_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;
}
#3

[eluser]Frank Wong[/eluser]
Thanks, didn't know about the tag.
#4

[eluser]Phil Sturgeon[/eluser]
What was the error you are fixing?
#5

[eluser]Frank Wong[/eluser]
Ah, I realized that it was not very clear what the problem is. Thanks for asking, pyro.

Problem:
The create_links method was incrementing the page segment of the URI by the per_page attribute instead of by 1.

Sample code:
Code:
$this->load->library('pagination');
$config['per_page'] = '5';
$config['uri_segment'] = '4';
$config['base_url'] = site_url('seg1/seg2/seg3/');
$config['total_rows'] = 100;
$this->pagination->initialize($config);
$this->pagination->create_links();

Expected results:
Digit links
Code:
<a href="seg1/seg2/seg3/">1</a>
<a href="seg1/seg2/seg3/2">2</a>
<a href="seg1/seg2/seg3/3">3</a>
<a href="seg1/seg2/seg3/4">4</a>
<a href="seg1/seg2/seg3/5">5</a>
etc...

Observed results:
Digit links
Code:
<a href="seg1/seg2/seg3/">1</a>
<a href="seg1/seg2/seg3/5">2</a>
<a href="seg1/seg2/seg3/10">3</a>
<a href="seg1/seg2/seg3/15">4</a>
<a href="seg1/seg2/seg3/20">5</a>
etc...

NOTE: The previous, next, and last links were incorrect also based on the same issue as illustrated above and the posted code change fix that problem also.
#6

[eluser]Phil Sturgeon[/eluser]
This is not a bug or an error, this is how the system was intended to work. Some pagination systems use page numbers, some use offsets.

Congratulations for your initiative in modifying the code in this way, but it has been done many times before and is even in the Wiki!
#7

[eluser]Frank Wong[/eluser]
Thanks for the explanation, pyro.

Since there are two ways of doing pagination, it would be useful to the community to have two methods for creating links in the pagination library such as

create_links_by_offset()
create_links_by_page_number()

I do see the value in each depending on other implementation factors. I will go ahead and have my pagination library modified to have the two methods for now until code base releases with further implementation for flexibility.
#8

[eluser]ciscoheat[/eluser]
Thank you for this code Frank, I just used it and it works perfectly. You should update the wiki page http://codeigniter.com/wiki/Alternate_Pagination_class/ with your code, since the old one is very outdated.
#9

[eluser]Frank Wong[/eluser]
ciscoheat,

I am glad you were able to make use of it. I will look into the wiki to see if there is a need to update. Thanks.




Theme © iAndrew 2016 - Forum software by © MyBB