Part of the EllisLab Network
   
 
Pagination using per_page to increment page numbers fix
Posted: 10 November 2007 01:43 PM   [ Ignore ]  
Grad Student
Rank
Total Posts:  34
Joined  11-10-2007

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.’’.$this->first_link.’’.$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.’’.$this->prev_link.’’.$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.’’.$loop.’’.$this->num_tag_close;
          }
        }
      }

      // Render the “next” link
      if ($this->cur_page < $num_pages)
      {
//        $output .= $this->next_tag_open.’’.$this->next_link.’’.$this->next_tag_close;
        $output .= $this->next_tag_open.’’.$this->next_link.’’.$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.’’.$this->last_link.’’.$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—————

 Signature 

-Frank
informationideas.com

Profile
 
 
Posted: 10 November 2007 09:40 PM   [ Ignore ]   [ # 1 ]  
Sr. Research Associate
Avatar
RankRankRankRankRank
Total Posts:  3193
Joined  06-10-2007

Try to use the code elements in your post, makes reading easier!

function create_links() 

// If our item count or per-page total is zero there is no need to continue. 
if ($this->total_rows == 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
 Signature 

URI Language Identifier | Modular Extensions - HMVC | View Object | Widget plugin | Access Control library

Profile
 
 
Posted: 11 November 2007 02:29 AM   [ Ignore ]   [ # 2 ]  
Grad Student
Rank
Total Posts:  34
Joined  11-10-2007

Thanks, didn’t know about the tag.

 Signature 

-Frank
informationideas.com

Profile
 
 
Posted: 11 November 2007 07:44 AM   [ Ignore ]   [ # 3 ]  
Sr. Research Associate
Avatar
RankRankRankRankRank
Total Posts:  3133
Joined  06-11-2007

What was the error you are fixing?

 Signature 

————————
Blog | Twitter | GitHub | BitBucket
————————-
PyroCMS - open source modular CMS built with CodeIgniter
PancakeApp - Simple, hosted invoicing/w project management

Profile
 
 
Posted: 11 November 2007 12:12 PM   [ Ignore ]   [ # 4 ]  
Grad Student
Rank
Total Posts:  34
Joined  11-10-2007

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:

$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

<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

<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.

 Signature 

-Frank
informationideas.com

Profile
 
 
Posted: 11 November 2007 12:35 PM   [ Ignore ]   [ # 5 ]  
Sr. Research Associate
Avatar
RankRankRankRankRank
Total Posts:  3133
Joined  06-11-2007

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!

 Signature 

————————
Blog | Twitter | GitHub | BitBucket
————————-
PyroCMS - open source modular CMS built with CodeIgniter
PancakeApp - Simple, hosted invoicing/w project management

Profile
 
 
Posted: 11 November 2007 01:04 PM   [ Ignore ]   [ # 6 ]  
Grad Student
Rank
Total Posts:  34
Joined  11-10-2007

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.

 Signature 

-Frank
informationideas.com

Profile
 
 
Posted: 08 January 2008 02:11 PM   [ Ignore ]   [ # 7 ]  
Summer Student
Total Posts:  21
Joined  12-12-2007

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.

Profile
 
 
Posted: 23 May 2008 02:23 PM   [ Ignore ]   [ # 8 ]  
Grad Student
Rank
Total Posts:  34
Joined  11-10-2007

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.

 Signature 

-Frank
informationideas.com

Profile