Ajax Pagination in CodeIgniter Framework


CodeIgniter have the pagination library by default. But many times we are needed to implement the ajax based pagination in CodeIgniter. Because ajax pagination provides better user experience. Today we will discuss how to create ajax pagination in CodeIgniter framework.

We’ll modify the CodeIgniter’s Pagination library for integrating ajax pagination in CodeIgniter application. Also, this modified Ajax Pagination library provides many customization options for you, some options are given below.

  • Display loading image while data loading.
  • Add a custom function to pagination links.
  • Set a selector to load the pagination data.
  • and many more

For better understanding, we’ll build an example script. In the example code, data will be fetched from the database table and display in the view page with pagination links. Once the pagination link is clicked, more data would be fetched from the database and display instead of previously displayed data. Also, a loader image would appear at the time of data loading.

Before you begin, take a look at the folders and files structure of the example script.

codeigniter-ajax-pagination-tutorial-files-structure-codexworld

This tutorial is divided in step-by-step and you can create the files one by one. However, the source code package contains all the script together with the respective folder.

Database Table Creation

Create a table (posts) in the database (codeigniter_db). The following SQL will create a posts table in the database 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;

Pagination Library

The pagination library helps to generate pagination links and jQuery & Ajax code. This library makes ajax pagination simple for you. You only need to set configuration options and call the create_links() function. We’ve copied the CodeIgniter’s system pagination library, renamed the class to Ajax_pagination, modified and added code for extending Pagination library with Ajax Pagination functionality. Create a file called Ajax_pagination.php, copy & paste the below code and insert this file into the application/libraries folder.

<?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 CodexWorld.com
 * @Ajax pagination functionality has added with this library. 
 * @It will helps to integrate Ajax pagination with loading image in CodeIgniter application.
 * @TutorialLink http://www.codexworld.com/ajax-pagination-in-codeigniter-framework/
 */
class Ajax_pagination{
    var 
$base_url        ''// The page we are linking to
    
var $total_rows      ''// Total number of items (database results)
    
var $per_page        10// Max number of items you want shown per page
    
var $num_links       =  2// Number of "digit" links to show before/after the currently viewed page
    
var $cur_page        =  0// The current page being viewed
    
var $first_link      'First';
    var 
$next_link       '&#187;';
    var 
$prev_link       '&#171;';
    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 '&nbsp;';
    var 
$last_tag_open   '&nbsp;';
    var 
$last_tag_close  '';
    var 
$cur_tag_open    '&nbsp;<b>';
    var 
$cur_tag_close   '</b>';
    var 
$next_tag_open   '&nbsp;';
    var 
$next_tag_close  '&nbsp;';
    var 
$prev_tag_open   '&nbsp;';
    var 
$prev_tag_close  '';
    var 
$num_tag_open    '&nbsp;';
    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 == 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 ) . ' to ' ;
            if( ( 
$curr_offset $this->per_page ) < ( $this->total_rows -) )
            
$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>';
    }
}
// END Pagination Class

Controller (Posts.php)

The Posts controller consits of 3 functions __construct(), index(), and ajaxPaginationData().
__construct() function loads the Post model, Ajax_pagination library and sets the per page data limit into $this->perPage variable.
In index() function, pagination library is initiated with basic configuration, index view is loaded and posts data is passed to the view.
The functionality of ajaxPaginationData() function is same like the index() function. But this method is requested by the ajax when pagination link is clicked.

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
 * Posts Management class created by CodexWorld
 */
class Posts extends CI_Controller {
    
    function 
__construct() {
        
parent::__construct();
        
$this->load->model('post');
        
$this->load->library('Ajax_pagination');
        
$this->perPage 3;
    }
    
    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;
        
$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(){
        
$page $this->input->post('page');
        if(!
$page){
            
$offset 0;
        }else{
            
$offset $page;
        }
        
        
//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;
        
$this->ajax_pagination->initialize($config);
        
        
//get the posts data
        
$data['posts'] = $this->post->getRows(array('start'=>$offset,'limit'=>$this->perPage));
        
        
//load the view
        
$this->load->view('posts/ajax-pagination-data'$datafalse);
    }
}

Model (Post.php)

The Post model contains getRows() function. The getRows() function fetch data from the database and returns the post based on the limit restriction provided by the $params array.

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class 
Post extends CI_Model{

    function 
getRows($params = array())
    {
        
$this->db->select('*');
        
$this->db->from('posts');
        
$this->db->order_by('created','desc');
        
        if(
array_key_exists("start",$params) && array_key_exists("limit",$params)){
            
$this->db->limit($params['limit'],$params['start']);
        }elseif(!
array_key_exists("start",$params) && array_key_exists("limit",$params)){
            
$this->db->limit($params['limit']);
        }
        
        
$query $this->db->get();
        
        return (
$query->num_rows() > 0)?$query->result_array():FALSE;
    }
}

View (posts/)

The view folder (posts/) contains 2 files, index.php and ajax-pagination-data.php.

index.php
In index.php file, the posts are listed with the pagination links when the Post controller loaded. Ajax pagination uses jQuery, so jQuery library (jquery.min.js) should need to be included. You can see only create_links() function is needed to call ($this->ajax_pagination->create_links()) from Pagination library to display the pagination links.
Div with loading class is used to display a loader while data loading. If you wish to change the selector, set the loading selector with the pagination configuration options.

<script src="<?php echo base_url(); ?>assets/js/jquery.min.js"></script>
<div class="container">
    <h1>Ajax Pagination in CodeIgniter Framework</h1>
    <div class="row">
        <div class="post-list" id="postList">
            <?php if(!empty($posts)): foreach($posts as $post): ?>
                <div class="list-item"><a href="javascript:void(0);"><h2><?php echo $post['title']; ?></h2></a></div>
            <?php endforeach; else: ?>
            <p>Post(s) not available.</p>
            <?php endif; ?>
            <?php echo $this->ajax_pagination->create_links(); ?> </div> <div class="loading" style="display: none;"><div class="content"><img src="<?php echo base_url().'assets/images/loading.gif'?>"/></div></div> </div> </div>

ajax-pagination-data.php
This file does the same work like the index.php, but it contains minimal code to display only the posts list and pagination links.

 <?php if(!empty($posts)): foreach($posts as $post): ?>
     <div class="list-item"><a href="javascript:void(0);"><h2><?php echo $post['title']; ?></h2></a></div>
 <?php endforeach; else: ?>
 <p>Post(s) not available.</p>
 <?php endif; ?>
 <?php echo $this->ajax_pagination->create_links(); ?>

18 Comments

  1. Ann Said...
    • CodexWorld Said...
  2. Ronaldus Cricri Said...
  3. Shibnath Roy Said...
  4. Iftikhar Said...
    • CodexWorld Said...
  5. Affan Said...
  6. Kailash Jangir Said...
  7. Abdul Muin Amz Said...
  8. Yasser Said...
  9. Tony Said...
  10. Federico Said...
    • CodexWorld Said...
  11. Federico Said...
    • CodexWorld Said...
  12. Federico Said...
    • CodexWorld Said...

Leave a reply

Connect With CodexWorld