Friday, December 30, 2011

Use search with Codeigniter pagination

Like I mentioned in a previous post, Codeigniter is extremely flexible and the following code is a perfect example of this. This post on using search with Codeigniter pagination uses only standard Codeigniter functions and requires no extra classes or functions.

Benefits to using this method

No need to use any caching to pass information across pages
No need to use any JavaScript / jQuery to amend links
You can pass any number of parameters through the $_GET array - these may include number of links per page, result ordering information etc. as it rebuilds the URL at page load

Downsides

You are using GET which isn't really the Codeigniter way

Notes on usage

This solution requires a form submitted through GET

The beauty of this method is that it allows the programmer to use any number of form fields. There is no need to use a session cookie to keep track of what a user is searching for, it is all done through the $_GET array.

The example uses some pretty standard stuff in terms of Codeigniter. I have called my model 'm_db_results', but that will probably be something completely different in your application. You could also improve the script by writing a better method for counting your results, I use this method for brevity only.

For all other info or help, just follow the inline help :)

public function search() {
 
    $this->load->model('m_db_results');                
    $this->load->library('pagination');
 
    //you can add any key => value parameter to your base_url
    //it just needs one to create a well formed GET request
    $config['base_url'] = '/site/search/?search=true';        

    // as we are unsure as to what values are going to passed to your pagination page
    // we need to build the base url on the fly  
    foreach ($_GET as $key=>$value) {
       if ($key != 'search' && $key != 'offset') {
           $config['base_url'] .= '&'.$key.'='.$value;
       }
    }
 
    //this will need to go to a model method which determines the total number of results
    //based on your form/search parameters. In my case the model method takes an array which in this case
    //is based on key/value pairs that are same mapped the same as the form inputs
    $results_info = $this->m_db_results->search($_GET);
 
    //the key to using this is that it will append your uri with the query string segment parameter
    //using this allows in conjunction with the $config['page_query_string'] being set to true
    //as it adds the offset to the URI as &offset=x
    $config['query_string_segment'] = 'offset';
    $config['page_query_string'] = true;

    $config['total_rows'] = count($results_info);
    $config['per_page'] = $number_per_page = 10;
 
    //now instead of using the uri segment to determine the number of results we offset
    //from our results we use the parameter we specified above in the $config['query_string_segment']      
    if (!empty($_GET['offset'])) {
       $offset = $_GET['offset'];
    } else {
       $offset = 0;
    }

   $this->pagination->initialize($config);
 
    //now we run the same method as above but we supply an amount of results we want to be returned and the offset
    //as the second and third parameters
    //and pass off the data to our view
    $data['results'] = $this->m_db_results->search($_GET, $number_per_page, $offset);
    $this->load->view('results-page.php', $data);

}

Further info

Now as your form is submitted through get, it will not be able to use the set_value() method if you normally use that to repopulate your forms. You will have to code it in yourself, more than likely using isset() or empty() to determine if the field has a value.

P.S. If you found this post useful or not, can you leave some feedback in the comments as I want to improve the code as much as I can for other 'igniter fans. Thanks

Labels: , , ,