Ajax Pagination with Search and Filter in CodeIgniter
In the earlier CodeIgniter tutorial we have shown the ajax pagination integration process in CodeIgniter. Before you begin we recommend you to read our previous CodeIgniter Ajax pagination tutorial. That guide will help you to understand the basic concept of ajax pagination in CodeIgniter.
In this CodeIgniter tutorial, we?ll extend the Ajax pagination functionality with search and filter. Search and filtering features are commonly used in every data list. Here we?ll show you how to implement live search and filter on the list with Ajax Pagination in CodeIgniter. In our example script, we will fetch the posts data from the database and display in the list. Also, Ajax pagination with search and filter functionality will be added to the post list.
Before you get started, take a look at the folders and files structure of CodeIgniter Ajax Pagination with Search.

Database Table Creation
In this example script, we?ll fetch the posts data from the database. The following SQL creates a posts
table with some basic fields.
CREATE TABLE `posts` ( `id` int(11) NOT NULL AUTO_INCREMENT, `title` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `content` text COLLATE utf8_unicode_ci NOT NULL, `created` datetime NOT NULL, `modified` datetime NOT NULL, `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '1=Active, 0=Inactive', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Ajax Pagination Library
The Ajax_pagination
library helps to generate pagination links and get the data without page refresh using jQuery and Ajax. This library (Ajax_pagination.php
) need to be placed into the application/libraries/
directory.
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* Pagination Class
*
* @package CodeIgniter
* @link http://codeigniter.com/user_guide/libraries/pagination.html
*
* Modified by semicolonworld.com
* @Ajax pagination functionality has added with this library.
* @It will helps to integrate Ajax pagination with loading image in CodeIgniter application.
* @TutorialLink javascript:void(0);
*/
class Ajax_pagination{
var $base_url = '';
var $total_rows = '';
var $per_page = 10;
var $num_links = 2;
var $cur_page = 0;
var $first_link = 'First';
var $next_link = '»';
var $prev_link = '«';
var $last_link = 'Last';
var $uri_segment = 3;
var $full_tag_open = '<div class="pagination">';
var $full_tag_close = '</div>';
var $first_tag_open = '';
var $first_tag_close = ' ';
var $last_tag_open = ' ';
var $last_tag_close = '';
var $cur_tag_open = ' <b>';
var $cur_tag_close = '</b>';
var $next_tag_open = ' ';
var $next_tag_close = ' ';
var $prev_tag_open = ' ';
var $prev_tag_close = '';
var $num_tag_open = ' ';
var $num_tag_close = '';
var $target = '';
var $anchor_class = '';
var $show_count = true;
var $link_func = 'getData';
var $loading = '.loading';
/**
* Constructor
* @access public
* @param array initialization parameters
*/
function CI_Pagination($params = array()){
if (count($params) > 0){
$this->initialize($params);
}
log_message('debug', "Pagination Class Initialized");
}
/**
* Initialize Preferences
* @access public
* @param array initialization parameters
* @return void
*/
function initialize($params = array()){
if (count($params) > 0){
foreach ($params as $key => $val){
if (isset($this->$key)){
$this->$key = $val;
}
}
}
// Apply class tag using anchor_class variable, if set.
if ($this->anchor_class != ''){
$this->anchor_class = 'class="' . $this->anchor_class . '" ';
}
}
/**
* Generate the pagination links
* @access public
* @return string
*/
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);
// Is there only one page? Hm... nothing more to do here then.
if ($num_pages == 1){
$info = 'Showing : ' . $this->total_rows;
return $info;
}
// 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;
}
$this->num_links = (int)$this->num_links;
if ($this->num_links < 1){
show_error('Your number of links must be a positive number.');
}
if ( ! is_numeric($this->cur_page)){
$this->cur_page = 0;
}
// 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;
// Add a trailing slash to the base URL if needed
$this->base_url = rtrim($this->base_url, '/') .'/';
// And here we go...
$output = '';
// SHOWING LINKS
if ($this->show_count){
$curr_offset = $CI->uri->segment($this->uri_segment);
$info = 'Showing ' . ( $curr_offset + 1 ) . ' to ' ;
if( ( $curr_offset + $this->per_page ) < ( $this->total_rows -1 ) )
$info .= $curr_offset + $this->per_page;
else
$info .= $this->total_rows;
$info .= ' of ' . $this->total_rows . ' | ';
$output .= $info;
}
// Render the "First" link
if ($this->cur_page > $this->num_links){
$output .= $this->first_tag_open
. $this->getAJAXlink( '' , $this->first_link)
. $this->first_tag_close;
}
// Render the "previous" link
if ($this->cur_page != 1){
$i = $uri_page_number - $this->per_page;
if ($i == 0) $i = '';
$output .= $this->prev_tag_open
. $this->getAJAXlink( $i, $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;
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;
$output .= $this->num_tag_open
. $this->getAJAXlink( $n, $loop )
. $this->num_tag_close;
}
}
}
// Render the "next" link
if ($this->cur_page < $num_pages){
$output .= $this->next_tag_open
. $this->getAJAXlink( $this->cur_page * $this->per_page , $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);
$output .= $this->last_tag_open . $this->getAJAXlink( $i, $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;
?>
<script>
function getData(page){
$.ajax({
method: "POST",
url: "<?php echo $this->base_url; ?>"+page,
data: { page: page },
beforeSend: function(){
$('<?php echo $this->loading; ?>').show();
},
success: function(data){
$('<?php echo $this->loading; ?>').hide();
$('<?php echo $this->target; ?>').html(data);
}
});
}
</script>
<?php
return $output;
}
function getAJAXlink($count, $text) {
$pageCount = $count?$count:0;
return '<a href="javascript:void(0);"' . $this->anchor_class . ' onclick="'.$this->link_func.'('.$pageCount.')">'. $text .'</a>';
}
}
Controller (Posts.php)
The Posts controller contains of 3 functions __construct()
, index()
, and ajaxPaginationData()
.
__construct()
? Post model and Ajax_pagination library is loaded in this function. Also, the per page data limit is set into $this->perPage variable.
index()
? The posts data is fetched using Post model and passes to the view. The pagination library is configured and initiated to display the pagination links.
ajaxPaginationData()
? Like the index() function ajaxPaginationData() doing the same. But this method is loaded via Ajax by clicking the pagination links.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Posts Management class created by semicolonworld
*/
class Posts extends CI_Controller {
function __construct() {
parent::__construct();
$this->load->model('post');
$this->load->library('Ajax_pagination');
$this->perPage = 2;
}
public function index(){
$data = array();
//total rows count
$totalRec = count($this->post->getRows());
//pagination configuration
$config['target'] = '#postList';
$config['base_url'] = base_url().'posts/ajaxPaginationData';
$config['total_rows'] = $totalRec;
$config['per_page'] = $this->perPage;
$config['link_func'] = 'searchFilter';
$this->ajax_pagination->initialize($config);
//get the posts data
$data['posts'] = $this->post->getRows(array('limit'=>$this->perPage));
//load the view
$this->load->view('posts/index', $data);
}
function ajaxPaginationData(){
$conditions = array();
//calc offset number
$page = $this->input->post('page');
if(!$page){
$offset = 0;
}else{
$offset = $page;
}
//set conditions for search
$keywords = $this->input->post('keywords');
$sortBy = $this->input->post('sortBy');
if(!empty($keywords)){
$conditions['search']['keywords'
Comments 1