mrforbes design - a web design and development studio

Blog - One Byte at a Time

Technology moves fast. Its hard to keep up. By the time you've mastered one tool, another has come along to replace it. You can't catch up, so just take it one byte at a time.

Really Simple Paging with CodeIgniter

Tuesday, August 14th, 2007 at 12:03 am

The built in CodeIgniter paging library is fairly simple to use by itself.. however, where its functionality ends is at the point that most developers will want to customize, which is really as it should be. However, some beginning CodeIgniterers (eh?) or PHPers may find this drop-off point a little disconcerting, and may want something a little more simple. This tutorial will aim to take care of them.

Basically, my method involves passing the necessary data to a paging function within the controller. If you are using multiple controllers, I would suggest either extending the paging library, or creating another class and loading it.. but again, the idea is to keep it really simple - so you’ll have to work that out on your own.

Here’s the paging function:

  1. Your controller:
  2.  
  3. function _paging($limit=10,$total_rows, $page,$uri_segment=3)
  4. {
  5.      $this->load->library(‘pagination’);
  6.      $config[‘uri_segment’] =$uri_segment;
  7.      $config[‘base_url’] = site_url(‘/yourcontrollername/’.$page.‘/’);
  8.      $config[‘total_rows’] = $total_rows;
  9.      $config[‘per_page’] = $limit;
  10.      $config[‘num_links’] = 10;
  11.                        
  12.      $config[‘full_tag_open’] = ‘<div class="pagination">’;
  13.      $config[‘full_tag_close’] = ‘<div class="clear"></div></div>’;
  14.                        
  15.      $config[‘first_link’] = ‘&laquo;’;
  16.      $config[‘last_link’] = ‘&raquo;’;
  17.      $config[‘next_link’] = ‘&raquo;’;
  18.      $config[‘prev_link’] = ‘&laquo;’;
  19.        
  20.      $this->pagination->initialize($config);
  21.  
  22.      return $this->pagination->create_links();
  23. }

Ok, that probably doesn’t make a lot of sense.. there’s some stuff missing, and we’ll go over that here.

First, this function is a helper, and gets called by another function within the controller… basically, any other function which needs paging applied. So, lets say for example that we want to load a list of fruits in inventory at your local organic market (because organic rocks!)

So, we’re going to have a function which gets the fruits from the database, and begins like this:

  1. function get_fruits()
  2. {
  3.      if($this->uri->segment(3) == ) $offset = 0;
  4.      else $offset = $this->uri->segment(3);
  5. }

Wait a minute…. what kind of beginning is that? Well, the first thing we want to do, is figure out what page we’re on. Since CodeIgniter’s paging class appends the page number onto the end of the URI, we check to see if it has a value.. if not, we assign the offset to 0, otherwise, we set it equal to that value (so on page 2, the offset would be 1). This isn’t the TRUE offset, in the sense that we don’t want to search our database from record one. Later on, we’ll multiply the page number by the limit (the number of records we are returning on each page, to get the true offset). So, the offset is in essence the page number - 1. If our limit is 20 for example, then when we do the math, page 2 will start at record 20. Page 3 will start at record 40 (2*20) and so on.

  1. function get_fruits()
  2. {
  3.      if($this->uri->segment(3) == ) $offset = 0;
  4.      else $offset = $this->uri->segment(3);
  5.      $limit = 20;
  6.      $offset*=  $limit;
  7. }

Here, we have set the total number of rows returned on the page for this function, and determined the starting point for the database by multiplying our page number ($offset) by it.

An important thing to keep in mind. The offset doesn’t have to be at segment 3. It is always the last segment. You can either hard code where that is in your page, or you can figure it out dynamically - but that’s beyond the scope of this tutorial. Why would it NOT be 3? Say for example you offered a drop-down where the user could select WHICH type of fruit to view, such as citrus. You’d need to maintain that choice as you went through the paging, so it would probably be easiest to add it in as a segment. At which point, the offset would be at uri->segment(4).

Let’s return to the function:

  1. function get_fruits()
  2. {
  3.      if($this->uri->segment(3) == ) $offset = 0;
  4.      else $offset = $this->uri->segment(3);
  5.      $limit = 20;
  6.      $offset*=  $limit;
  7.  
  8.      $this->load->model(‘model_fruits’);
  9.      $results = $this->model_fruits->get_fruits($limit $offset);
  10. }

The next two lines are where you’d load your database functions (the model, which should be in the model folder), and then call the function get_fruits(), passing in the $offset you determined in the first 3 lines.
In the case of the example of loading just ‘citrus’, you could also pass that uri->segment to the get_fruits function, and go from there.

At this point, we’re going to flip over to models/model_fruits.php to look at how we’re going to get the data out of the database. Please refer to the CodeIgniter user guide for information on how a model should be setup.

  1. Your model:
  2.  
  3. function get_fruits($limit,$offset)
  4. {
  5.      $this->db->limit($limit,$offset);
  6.      $query = $this->db->get(‘fruits’);
  7.      if($query->num_rows() > 0)
  8.      {
  9.            $results[‘results’] = $query->result();
  10.      
  11.            $this->db->select(‘COUNT(*) as $totalRows’);
  12.            $query = $this->db->get(‘fruits’);
  13.            $row = $query->row();
  14.            $results[‘totalRows’] = $row->totalRows;   
  15.  
  16.            return $results;
  17.      }
  18.      else return FALSE;
  19.    
  20. }

Yes, that’s a bit longer section of code. If you aren’t familiar with CodeIgniter’s active record class, here’s the lowdown on what the above means.

  1. First, we set the database limit and offset as passed from our controller. This will handle the records that are returned for the page.
  2. Next, we set our actual query to a variable ($query makes sense). CodeIgniter’s query object is returned into this variable, and at that point we can retrieve the data from it.
  3. We then use the built-in num_rows() function to make sure we got some data back. If we didn’t, none of this other stuff really matters.
  4. Assuming we got data, we start an array named ‘$results’ and insert a key into it, again called ‘results’, to store the actual database data returned by our query.
  5. At this point, we need to get the total number of rows, so our _paging function knows how many page links to create. We don’t want to use the $query->num_rows() to set it, because it is already being limited to the value passed by the controller. Instead, we do another database call to get the COUNT(*), which quickly returns the number of rows in a table that match the query. You COULD select a column and run the query without a limit, and then use $query->num_rows, but its very inefficient for the database, and is poor practice. You also must be aware to give the COUNT(*) a different name, because you can’t tell CodeIgniter to return $row->COUNT(*)… it will think you’re trying to run a function!
  6. We run the query again, set a variable to only the first row of our dataset (since only one row is returned) and then set another key in the $results array to the totalRows data we just retrieved. At that point, we send the data and the total rows back to the controller. If by any chance our query had returned no records, we send back a ‘false’ signal so the controller knows what happened.

So now we’re back at our controller. We’ve gotten our data from the database in the model, and are ready to go to work with it. The controller’s get_fruits() function now looks like this:

  1. function get_fruits()
  2. {
  3.      if($this->uri->segment(3) == ) $offset = 0;
  4.      else $offset = $this->uri->segment(3);
  5.      $limit = 20;
  6.      $offset*=  $limit;
  7.  
  8.      $this->load->model(‘model_fruits’);
  9.      $results = $this->model_fruits->get_fruits($limit $offset);
  10.  
  11.      if($results!=false)
  12.      {
  13.          $results[‘paging’] = $this->_paging($limit,$results[‘totalRows’], ‘get_fruits’,3);
  14.      }
  15.  
  16.      $this->load->view(‘list_fruits’,$results);
  17. }

So, we make sure that our model didn’t tell the controller that there was no data (because there’s no point doing the paging on zero records), and then we call the paging function, written at the top of this tutorial. We pass it the limit, the total rows from the database, and tell it which segment we are using as the page number, and it does the rest, spitting back a div with paged links inside. All that’s left now is to display the links in the view.

  1. Your View:
  2.  
  3. < ? if(isset($paging)) { print $paging; } ?>

That’s all there is to it. The CodeIgniter paging class is fairly simple to use on its own, but with a small function we can make it just a little bit easier. Isn’t that what everybody wants?

Site Tags:

Leave a Reply