CodeIgniter and jQuery – Real Live Search with Pagination


Spread it!

  • Share

In this tutorial, we will create a search page with CodeIgniter and jQuery. We’re not gonna create only a default search page using CodeIgniter framework, but also a real time search with jQuery’s support. And one more, enable GET method in CodeIginter that was stupidly disable by default. Enjoy the tut and don’t forget the … beer!

You can take a look at the demo or download it right now, then close this page immediately if you want to. But I highly recommend that you should read the whole tutorial, so you will not miss any interesting in this entry.

Try to search with the keywords: jquery, html, code …

1. The stuffs I’m using


2. Configuring CodeIgniter


At first, download CodeIgniter (CI) with the link above and extract package to your workspace. Note, your web site will be located in CodeIginiter folder by default. Then, you need to make some changes to Codeiginter within the CI config section. In this tutorial, we’re using PHP to connect to MySQL database to get data.

Open the system/application/config/autoload.php, find the following code:

/*
| -------------------------------------------------------------------
|  Auto-load Libraries
| -------------------------------------------------------------------
| These are the classes located in the system/libraries folder
| or in your system/application/libraries folder.
|
| Prototype:
|
|   $autoload['libraries'] = array('database', 'session', 'xmlrpc');
*/

$autoload['libraries'] = array();

Change the code above as below:

$autoload['libraries'] = array('database');

Because we’re gonna use Database to store and fetch from, so we load the database library. That’s all what it means. And each time you run your web page, it will automatically load the database connection.

The second, open up database.php in the same folder then find following code and change it to your database setting.

$db['default']['hostname'] = "localhost";
$db['default']['username'] = "root";
$db['default']['password'] = "root";
$db['default']['database'] = "aext";

The next important part in CI Configuration is you have to config you default url of your website. This is a base url inside config.php file.
Open this file in then find and edit your base_url as below:

/*
|---------------------------------------------------------------------
| Base Site URL
|---------------------------------------------------------------------
|
| URL to your CodeIgniter root. Typically this will be your base URL,
| WITH a trailing slash:
|
|   http://example.com/
|
*/
$config['base_url'] = "http://project/tutorial/";

In CodeIgniter 1.7.2, there’re already some changes. Who follows the tutorial will need to activate the following, in autoload.php to make the base_url() function works:

/*
| -------------------------------------------------------------------
|  Auto-load Helper Files
| -------------------------------------------------------------------
| Prototype:
|
|   $autoload['helper'] = array('url', 'file');
*/

$autoload['helper'] = array('url');

Default using of base_url when you want to call it in your view is as example below:

    <link media="screen" type="text/css"
                         href="<?php echo base_url(); ?>css/style.css" />

2. Database


Wow, it’s a large database file size if you build a search engineer. So, I will use my old Wordpress database and the search will fetch data from my posts table. If you are setting up a search for a series of articles or a site with lots of product-related content, a MySQL FULLTEXT search can make it very easy to find articles or products related to the keywords used by a searcher. Read this entry to know more about FULLTEXT.

Add FULLTEXT to the data fileds you want to index. In this tutorial, I will search through table wp_post and the result will be based on the search term within post_title and post_content fileds.

ALTER TABLE `wp_posts` ADD FULLTEXT (
`post_title` ,
`post_content`
);

So, if I’m using FULLTEXT search, my search query is simple:

SELECT * FROM wp_posts WHERE  MATCH ( post_title, post_content ) AGAINST (?)  AND post_status='publish'

(?) is your search term.

Download the sample data file in my attachment then import to your database.

3. Understanding the CodeIgniter


CI is a framework was help php developers build a website base on Model–View–Controller architecture.

Model View Controller Diagram

MVC in CodeIginter:

  • Model: Collection of php classes and functions stored in system/application/models
  • View: The view is represented by PHP file. All the PHP files for displaying located in system/application/views
  • Controller: The controller communicates with the View and Model. These files located in system/application/controllers

Let’s begin to work with CodeIgniter!

4. Building the Model


Go to system/application/models and create a new file called search_model.php.

The main function that used to get results from database by search keyword is:

    // Get total posts by search query
    function get_posts($query, $post_per_page,$current_page) {

        $offset=($current_page-1)*$post_per_page;
        if($current_page==1) {
            $offset = 0;
        }

        $sql = "SELECT * FROM wp_posts WHERE  MATCH ( post_title, post_content ) AGAINST (?)  AND post_status='publish' LIMIT ?,?";
        $query = $this->db->query($sql, array($query, $offset, $post_per_page));

        return $query->result_array();
    }

Of course, we only need the posts with status is published because wordpress stores a lot of posts in the table for revision.
Next, create a function that will calculate the total of rows, we need that number for pagination.

    // Get the number of rows, use for pagination
    function get_numrows($query) {

        $rows=0;

        $sql = "SELECT * FROM wp_posts WHERE  MATCH ( post_title, post_content ) AGAINST (?)  AND post_status='publish'";
        $query = $this->db->query($sql, array($query));

        $rows=$query->num_rows();

        return $rows;
    }

The next function highlight the search keywords. Continue to write some code in your Controller:

    function highlightWords($string,$words,$ajax=false){

        $words=explode(' ',$words);

        for($i=0;$i<sizeOf($words);$i++) {

            if($ajax==true)
            {
                $string=str_ireplace($words[$i], '<strong class=\"highlight\">'.$words[$i].'<\/strong>', $string);
            } else {
                $string=str_ireplace($words[$i], '<strong class="highlight">'.$words[$i].'</strong>', $string);
            }

        }

        return $string;
    }

Because FULLTEXT will find the results by each word in the search phrase, so we need to split our search phrase first. This function will split the keyword into parts then highlight each word in the result.

Furthermore, you need a function that clean up the HTML format for displaying. The purpose of this function I will talk later in jQuery part.

    function cleanHTML($input, $ending='...') {

        $output = strip_tags($input);

        $output = substr($output, 0, 100);
        $output .= $ending;

        return $output;
    }

The completed code of the Model:

<?php

class Search_model extends Model {

    // Get total posts by search query
    function get_posts($query, $post_per_page,$current_page) {

        $offset=($current_page-1)*$post_per_page;
        if($current_page==1) {
            $offset = 0;
        }

        $sql = "SELECT * FROM wp_posts WHERE  MATCH ( post_title, post_content ) AGAINST (?)  AND post_status='publish' LIMIT ?,?";
        $query = $this->db->query($sql, array($query, $offset, $post_per_page));

        return $query->result_array();
    }

    // Get the number of rows, use for pagination
    function get_numrows($query) {

        $rows=0;

        $sql = "SELECT * FROM wp_posts WHERE  MATCH ( post_title, post_content ) AGAINST (?)  AND post_status='publish'";
        $query = $this->db->query($sql, array($query));

        $rows=$query->num_rows();

        return $rows;
    }

    function highlightWords($string,$words,$ajax=false){

        $words=explode(' ',$words);

        for($i=0;$i<sizeOf($words);$i++) {

            if($ajax==true)
            {
                $string=str_ireplace($words[$i], '<strong class=\"highlight\">'.$words[$i].'<\/strong>', $string);
            } else {
                $string=str_ireplace($words[$i], '<strong class="highlight">'.$words[$i].'</strong>', $string);
            }

        }

        return $string;
    }

    function cleanHTML($input, $ending='...') {

        $output = strip_tags($input);

        $output = substr($output, 0, 100);
        $output .= $ending;

        return $output;
    }

}

?>

5.Building the Controller


Now go to system/application/controllers and create a new file. Name this file as search.php. After create the file, the first thing we must do with this file is create a constructor which loads the model of search. Our search model is sear_model that we already created above.

class Search extends Controller {

    function Search()
    {
        parent::Controller();

        $this->load->model('search_model');

    }

Here is the most important part for our search. Because we will create 2 search methods which are default HTTP request and ajax request; therefore, we have to create a function that identifies each other request is.

The function below is used for knowing that is an ajax request.

    function isAjax() {
        return (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH']=="XMLHttpRequest");
    }

You can add this function to your search_model then call it by:

$this->search_model->isAjax()

But it’s in here is fine.

By default, GET data is simply disallowed by CodeIgniter since the system utilizes URI segments rather than traditional URL query strings. The following line will make GET supported.

    function index()

    {       

        parse_str($_SERVER['QUERY_STRING'],$_GET);

Put this line into your index() method. Now, continue working with the index() by separating each method request. We will process the default HTTP Request first. For displaying, we need 4 files. Actually, we just want to create 3 files: search.php, search_form.php and search_result.php. However, we need to separate the search.php into search_header.php and search_footer.php to make it easier to edit later.

  • search_header.php: Header HTML goes here
  • search_form.php: Form search
  • search_result.php: Even when it has results or not, you need to display here
  • search_footer.php: HTML for footer goes here

We’re gonna make a default search page when have no request (It means no one submits search query). It’ll load the default view and pass variable search_term to search form. It’s an empty value, but without it, your form will get error.

    function index()
    {       

        parse_str($_SERVER['QUERY_STRING'],$_GET);

        if($this->isAjax()) {

            // Calm down, I'll do it later !!!!

        } else {

            if(!empty($_GET['Query'])) {

                ...........

            } else {

                $data['search_term']="";

                // load the default view
                $this->load->view('search_header');
                $this->load->view('search_form', $data);
                $this->load->view('search_footer');

            }
        }
    }

We don’t need to display the results in the default search page because it doesn’t have any result, right?
Inside the condition block when it has GET value of query, we will process the default HTTP request method here.

    $query = trim($_GET['query']);
    $clean_query= mysql_real_escape_string($query);

    $post_per_page=5;
    $current_page=1;

    if(!empty($_GET['page'])) {
        $current_page=intval(trim($_GET['page']));
    }

    $totalrows=$this->search_model->get_numrows($clean_query);

    $totalpages=ceil($totalrows/$post_per_page);

    $posts = $this->search_model->get_posts($clean_query, $post_per_page, $current_page);

    $has_next=true;
    if($current_page==$totalpages) {
        $has_next=false;
    }

    $has_prev=true;
    if($current_page<=1) {
        $has_prev=false;
    }

You maybe knew the easiest way to do pagination in CodeIginter suchs by using Pagination class, take a look at the CI Pagination Guide. However, it’s not as they said. It’s hard to customize, you need to write another pagination class to fit your needs. That’s why I don’t like it. The following code to paginate the result is just a simple code. Because we’ve talked about that over forum to forum. Please change it to your one pagination. Thank you!

We are passing all variables to the $data array to display it in view.

    $data['search_term']=$clean_query;
    $data['total_posts']=$totalrows;
    $data['current_page']=$current_page;
    $data['next_page']=$current_page+1;

    $data['has_next']=$has_next;
    $data['has_prev']=$has_prev;

    $data['prev_page']=$current_page-1;
    $data['total_page']=$totalpages;
    $data['posts']=$posts;

    // load the default view
    $this->load->view('search_header');
    $this->load->view('search_form', $data);
    $this->load->view('search_result', $data);
    $this->load->view('search_footer');

Now, we are on the topic of this entry. Build a ajax live search with jQuery and CodeIgniter. The code is similar to default HTTP request but may varies a little bit which is the results. The results in ajax respond are different. In this tutorial, I will make ajax response in JSON format.

A little bit thing but helpful to understand how is this form gonna get the result. It’s JSON format. The well-formatted JSON in this tutorial is:

    {"results":[
        {
            "postid":30,
            "summary":"Some summary of this post go here ...",
            "title":"This is a title",
            "url":"http://link-to-this-post",
        },
        {
            "postid":294,
            "summary":"Some summary of this post go here ...",
            "title":"This is a title",
            "url":"http://link-to-this-post",
        },
        {
            "postid":384,
            "summary":"Some summary of this post go here ...",
            "title":"This is a title",
            "url":"http://link-to-this-post",
        },
       ],
       "paging":{
            "start_idx":1,
            "end_idx":5,
            "total":6,
            "current":"1",
            "pages":2,
            "has_next":true,
            "has_prev":false,
       }
    }

The values in array paging is used for pagination. The start_idx and end_idx are the values that shows us the range in total of posts displayed in current page. The has_next and has_prev are boolean values that the next and previous button depend on. Here below is the ajax part:

    function index()
    {       

        parse_str($_SERVER['QUERY_STRING'],$_GET);

        if($this->isAjax()) {

            $query = trim($_GET['query']);
            $clean_query= mysql_real_escape_string($query);

            $post_per_page=5;
            $current_page=1;

            if(!empty($_GET['page'])) {
                $current_page=intval(trim($_GET['page']));
            }

            $clean_query= mysql_real_escape_string($query);         

            $posts = $this->search_model->get_posts($clean_query, $post_per_page, $current_page);

            $totalrows=$this->search_model->get_numrows($clean_query);

            $totalpages=ceil($totalrows/$post_per_page);

            if($current_page==1) {
                $start_idx=1;
            } else {
                $start_idx=($current_page*$post_per_page)-4;
            }   

            $end_idx=$start_idx+4;
            if($current_page==$totalpages) {
                $end_idx=$totalrows;
            }

            echo '{"results":[';

            foreach($posts as $post) {

              echo '{
                      "postid":'.$post['ID'].',
                      "summary":"'.$this->search_model->highlightWords($this->search_model->cleanHTML($post['post_content']), $clean_query, true).'",
                      "title":"'.$this->search_model->highlightWords($post['post_title'], $clean_query, true).'",
                      "url":"'.$post['guid'].'",
                    },';
            }

            echo '],';

            $has_next='false';
            $has_prev='false';
            if($current_page<$totalpages) {
                $has_next='true';
            }

            if($current_page>1)
            {
                $has_prev='true';
            }

            echo '
                    "paging":{
                        "start_idx":'.$start_idx.',
                        "end_idx":'.$end_idx.',
                        "total":'.$totalrows.',
                        "current":"'.$current_page.'",
                        "pages":'.$totalpages.',
                        "has_next":'.$has_next.',
                        "has_prev":'.$has_prev.',
                    }
                }
            ';  

        } else {

            // blah blah blah blah blah blah

        }
    }

When you display the results as JSON format, you need to make sure your data is cleaned up. Because some HTML tags will break the JSON format, then your jQuery code can not read it. That’s why I created a function to clean up HTML format earlier.

6. The View – Display your works


100% percent of people who are viewing the tut have already click to check the demo before reading, right? So, the demo you saw at the top of this entry is the result of all code below.

The search_header.php file: link to your css file and jQuery library, do some javascripts for the form, that’s all!

<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Search</title>

<link rel="stylesheet" media="screen" href="<?php echo base_url(); ?>css/reset.css">
<link rel="stylesheet" media="screen" href="<?php echo base_url(); ?>css/global.css">

<script type="text/javascript" src="<?php echo base_url(); ?>js/jquery.js"></script>
<script type="text/javascript" src="<?php echo base_url(); ?>js/search_pod.js"></script>

</head>
<body>

<!-- Begin Content -->
<div id="content">

    <div class="maincontent">

       <!-- Begin Search -->

All the javascript and css file will be located at root folder base on base_url that we declared at above. It’s not inside folder system/application/view.

Next, create search_footer.php file in system/application/view with content as:

       <!-- End Search -->

    </div>

    <div class="clearfix">&nbsp;</div>

</div>
<!-- End Content -->

</body></html>

The search_form.php contains the search form and the panel that data returned will be displayed in. Create a file name search_form.php in the same folder which contains following code below:

  <!-- Start SearchForm -->
  <div id="search">
     <form id="search_form" method="GET" action="<?php echo base_url(); ?>search">
         <fieldset>
            <img src="<?php echo base_url(); ?>/images/ajax-loader.gif"
                 id="ajaxloader" alt="Loading Results..." style="display: none;">
            <input name="query" id="search_val" value="<?php printf($search_term); ?>"
                   tabindex="1" autocomplete="off" type="text">
         </fieldset>

         <!-- Begin Livesearch Panel -->
         <div id="livesearch" style="display: none;">
            <div class="loader" id="loader_div"><p>Loading Results...</p></div>
            <div class="livesearch_body">
               <dl class="livesearch_results">
                  <dt><span>Live Search Results</span>
                  <div class="livesearch_subnav">
                    <a href="#" class="livesearch_close" id="livesearch_result_close_link">Close LiveSearch</a>
                    <div class="clearfix">&nbsp;</div>
                  </div>
                  <div class="clearfix" id="subnavclear">&nbsp;</div>
                  </dt>
                </dl>
             </div>
             <div class="livesearch_nav">
                <div class="livesearch_navbody"></div>
             </div>
         </div>
          <!-- End Livesearch Panel -->

      </form>
  </div>
  <!-- End SearchForm -->

The result after users input something is like image below:

CodeIgniter and jQuery Live Search - Slide Down

Your search_result.php:

        <!-- Begin search result -->
        <dl id="search_results" class="results_browse">

        <?php if(count($posts)>0): ?>
        <dt>

            <div class="results_paging">
                <a class="livesearch_next" href="<?php echo base_url(); ?>search?query=<?php echo $search_term; ?>&page=<?php if(!$has_next) printf($current_page."#"); else printf($next_page); ?>" title="Next results page"><em>Next</em></a>

                <!-- list markup is IMPORTANT for ie6 compatibility (no whitespace) -->
                <ul class="pagelist">
                <?php for($i=1; $i<=$total_page; $i++) {

                        if($i==$current_page):

                ?>

                 <li><a href="<?php echo base_url(); ?>search?query=<?php printf($search_term); ?>&page=<?php printf($i); ?>" class="active"><?php printf($i); ?></a></li>
                <?php   else: ?>

                <li><a href="<?php echo base_url(); ?>search?query=<?php printf($search_term); ?>&page=<?php printf($i); ?>"><?php printf($i); ?></a></li>

                <?

                        endif;

                      }

                ?>
                </ul>

                <a class="livesearch_prev" href="<?php echo base_url(); ?>search?query=<?php echo $search_term; ?>&page=<?php if(!$has_prev) printf($current_page."#"); else printf($prev_page); ?>" title="Previous results page"><em>Previous</em></a>

            </div>
            <span class="results_meta">There were <?php echo $total_posts; ?> articles found for your query: - Page <?php echo $current_page; ?> of <?php echo $total_page; ?></span>
            <div class="clearfix">&nbsp;</div>
        </dt>
        <?php foreach($posts as $post):?>
        <dd id="">
        <a href="<?php echo $post['guid']; ?>">
        <p>
        <b><?php echo $this->search_model->highlightWords($post['post_title'], $search_term); ?></b>

        <?php echo $this->search_model->highlightWords($this->search_model->cleanInput($post['post_content']), $search_term); ?>
        </p></a>
        </dd>
        <?php endforeach;?>
        <dt>
        <div class="clearfix">&nbsp;</div>
        </dt>

        <?php else: ?>

        <dt>
            <span class="results_meta">There were no results</span>
            <div class="clearfix">&nbsp;</div>
        </dt>

        <dt>
        <div class="clearfix">&nbsp;</div>
        </dt>

        <?php endif; ?>

        </dl>
        <!-- End search result -->

Each variable you called in this result was passed by the controller:

    $data['search_term']=$clean_query;
    $data['total_posts']=$totalrows;
    $data['current_page']=$current_page;
    $data['next_page']=$current_page+1;

    $data['has_next']=$has_next;
    $data['has_prev']=$has_prev;

    $data['prev_page']=$current_page-1;
    $data['total_page']=$totalpages;
    $data['posts']=$posts;

    ....

    $this->load->view('search_result', $data);

The CSS code is in the download file. It’s a very long code of CSS, so I decided not to post it here.

7. Work with jQuery


We need to use jquery to send request and display the data responded. Create javascript file name search.js in the js folder. Of course, this js folder is at root folder, not in views folder of Codeigniter. You can see the clear link of this file at the header which was created earlier.
The jQuery code was modified from the Knowledge Base of Mediatemple. I removed some unnecessary and complicated code. If we’re gonna make a live search, we’ll only need as enough as in this tutorial.

Declare some variables:

var SEARCH_BOX_DEFAULT_TEXT = 'Enter the keywords:';

var AJAX_PENDING_TIMER;
var CURRENT_PAGE = 1;
var CURRENT_LIMIT = 5;

AJAX_PENDING_TIMER is the time which is used for the time delay before performing the search function.

Now, create the initial function. We will set up the value of search field, perform the search in condition and the button to close the livesearch panel.

function init() {

    var sTextBox   = $("#search_val");

    sTextBox.focus(function() {
        if(this.value == SEARCH_BOX_DEFAULT_TEXT) {
            this.value = '';
        }
    });
    sTextBox.blur(function() {
        if(this.value == '') {
            this.value = SEARCH_BOX_DEFAULT_TEXT;
        }
    });
    sTextBox.blur();

    sTextBox.keyup(function() {
        var q    = $("#search_val").val();
        if( q == SEARCH_BOX_DEFAULT_TEXT || q == '' || q == undefined || q.length<=3) {
            HideLiveSearch();
        }
        else {
            clearTimeout(AJAX_PENDING_TIMER);
            CURRENT_PAGE = 1;
            AJAX_PENDING_TIMER = setTimeout("PerformLiveSearch()",300);
        }

    });

    $("#livesearch_result_close_link").click(function() {
        HideLiveSearch();
    });

}

Look at the keyup event, we only perform livesearch when users input more than 3 characters. It’s for saving HTTP request.
Add these line at the bottom of javascript file:

$(document).ready(function() {
    init();
});

The completed code of PerformLiveSearch() function:

var AJAX_IS_RUNNING = false;
function PerformLiveSearch() {

    if(AJAX_IS_RUNNING == true) {
        return;
    }

    var query      = $("#search_val");
    var q_val      = (query.val() && query.val() != SEARCH_BOX_DEFAULT_TEXT) ? query.val() : '';    

    if(q_val == '') {
        return;
    }
    AJAX_IS_RUNNING = true;

    $.ajax({
        url:        './search',
        data: {
            query: q_val,
            output: 'json',
            page: CURRENT_PAGE,
            limit: CURRENT_LIMIT
        },
        type:       'GET',
        timeout:    '5000',
        dataType:   'json',
        beforeSend: function() {
            // Before send request
            // Show the loader
            AJAX_IS_RUNNING = true;
            ShowLoaders();
        },
        complete: function() {
            // When Sent request
            // Hide the loader
            AJAX_IS_RUNNING = false;
            HideLoaders();
        },
        success: function(data, textStatus) {
            AJAX_IS_RUNNING = false;
            HideLoaders();
            $('#livesearch').slideDown();

            // clear the results
            $(".livesearch_results dd").remove();
            var resultsNav = $('.livesearch_results dt');

            if( data['results'].length ) {

                // add the new results (in reverse since the
                // append inserts right after the header and not
                // at the end of the result list
                var current = resultsNav;
                for(i=data['results'].length;i>0;i--) {
                    current.after(
                        ResultRowHTML(data['results'][i-1])
                    );
                }
            }
            else {
                resultsNav.after('<dd id=""><p>No articles found with these search terms</p></dd>');
            }

            // Pagination at the bottom of LiveSearch panel
            UpdateResultFooter(data['paging'],".livesearch_navbody");

        },

        // We're gonna hide everything when get error
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            AJAX_IS_RUNNING = false;
            HideLoaders();
            HideLiveSearch();
        }
    });

}

The result will be displayed by a function name DisplayResult. Parameter is the value in data['results'] array.

function DisplayResult(row) {
    var output = '<dd id="">';
    output += '<a href="' + row['url'] + '">';
    output += '<p>';
    output += '<b>' + row['title'] + '</b>';
    output += row['summary'];
    output += '</p></a></dd>';
    return output;
}

The Pagination function by jQuery:

function Pagination(p,selector) {

    $(selector + " *").remove();

    if(p['start_idx'] != undefined) {
        var html = '<span class="livesearch_legend">' + p['start_idx'] + ' - ' + p['end_idx'] + ' of ' + p['total'] + ' Results</span>';
        html += '<a class="livesearch_next" href="javascript:void(0);" title="Next 5 Results"><em>Next</em></a>';
        html += '<a class="livesearch_prev" href="javascript:void(0);" title="Previous 5 Results"><em>Previous</em></a>';
        html += '<div class="clearfix">&nbsp;</div>';

        $(selector).append(html);
    }
    else {
        var html = '<span class="kbls_legend">0 Results</span>';
        html += '<a class="livesearch_next" href="javascript:void(0);" title="Next 5 Results"><em>Next</em></a>';
        html += '<a class="livesearch_prev" href="javascript:void(0);" title="Previous 5 Results"><em>Previous</em></a>';
        html += '<div class="clearfix">&nbsp;</div>';

        $(selector).append(html);
    }

    $(selector + " .livesearch_next").click(function() {
        NextPage(p);
    });
    $(selector + " .livesearch_prev").click(function() {
        PrevPage(p);
    });

}

This function just rends the html code to display pagination. The range of post and number of total post depend on data['results']. The Next and Previous button are handled by:

function NextPage(p) {
    if(p['has_next']) {
        AJAX_IS_RUNNING = false;
        CURRENT_PAGE++;
        PerformLiveSearch();
    }
}
function PrevPage(p) {
    if(p['has_prev']) {
        AJAX_IS_RUNNING = false;
        CURRENT_PAGE--;
        PerformLiveSearch();
    }
}

The link to next page and previous page is automatically increased and decreased if it has next page and previous page.
The ajax loader when ajax is running or not will be in these functions:

function ShowLoaders() {
    $('#ajaxloader').fadeIn('fast');

    if( $('#livesearch').css('display') == 'block' ) {
        var h = $('#livesearch').height() - 5;
        var w = $('#livesearch').width() - 45;
        $('#loader_div').width(w);
        $('#loader_div').height(h);
        $('#loader_div p').css('margin-top',(h/2)+20);
        $('#loader_div').fadeIn('fast');
    }
}

function HideLoaders() {
    $('#ajaxloader').fadeOut('fast');
    $('#loader_div').hide();
}

You can find where the ajax loader by searching in the search_form.php file:

.........

         <fieldset>
            <img src="<?php echo base_url(); ?>/images/ajax-loader.gif"
                 id="ajaxloader" alt="Loading Results..." style="display: none;">
            <input name="query" id="search_val" value="<?php printf($search_term); ?>"
                   tabindex="1" autocomplete="off" type="text">
         </fieldset>

.........

And hide the LiveSearch panel:

function HideLiveSearch() {
    $('#livesearch').slideUp();
    $('#ajaxloader').fadeOut('fast');
}

8. One more step


The default URL in our address bar when you use CodeIgniter framework is:

http://<you-codeigniter>/index.php/<your-controller-filename>

So, write in your .htaccess file with following content to re-write your URL

http://<you-codeigniter>/<your-controller-filename>

The code for URL rewrite is:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /

    #Removes access to the system folder by users.
    #Additionally this will allow you to create a System.php controller,
    #previously this would not have been possible.
    #'system' can be replaced if you have renamed your system folder.
    RewriteCond %{REQUEST_URI} ^system.*
    RewriteRule ^(.*)$ /index.php/$1 [L]

    #Checks to see if the user is attempting to access a valid file,
    #such as an image or css document, if this isn't true it sends the
    #request to index.php
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ /index.php/$1 [L]
</IfModule>

WOW


What’s wow? Just relax after working. Feel free to give me a comment. I’m not sure if I corrected all the whole things, but it seems work fine in my demo. Enjoy it and download the source code. Cheer!

  • Digg This Post
  • Tweet This Post
  • Stumble This Post
  • Submit This Post To Delicious
  • Submit This Post To Reddit
  • Submit This Post To Mixx
  • Share on your Facebook
  • Submit this post to Dzone
  • Submit this post to Designbump
  • Submit this post to TheWebBlend

Author: Lam Nguyen

I'm Lam Nguyen, a 21 year old web developer writing about everything related to web design. I am owner of AEXT.NET and WhoFreelance.com Web Community News. You can catch me on twitter.


65 User Comments

  1. dhewoy 14. Oct, 2009 at 4:39 am #

    is awesome

  2. Marco Barbosa 14. Oct, 2009 at 5:27 am #

    Fantastic!!

    It’s been some time since I read a good advanced Code Igniter tutorial!

    I sure will keep watching your next posts Lam Nguyen :)

    Thank you!

  3. albert lumu 14. Oct, 2009 at 7:51 am #

    This is so cool! As a side effect it shows how to “integrate” codeigniter with wordpress.

    Cool!

  4. Julian 14. Oct, 2009 at 8:30 am #

    Nice article! ;)

  5. Lam Nguyen 14. Oct, 2009 at 10:57 am #

    Thanks for your interesting! :D

  6. Marek Stasikowski 15. Oct, 2009 at 6:53 am #

    Why do you insert chunks of HTML into the model? Isn’t that something awful and to-be-avoided at all cost?

  7. Lam Nguyen 15. Oct, 2009 at 10:40 am #

    @Marek Stasikowski No, I did not ??? I just wrote a function to highlight the keywords! And to highlight them, of course, you have to have a html tags.
    Uhm, let me think. Maybe writing this function with parameter is HTML is better.
    Thanks :D

  8. Killian 16. Oct, 2009 at 3:24 am #

    Nice article, but you should watch out for some characters : in the demo, try to type \ or ‘, then press Enter, you may be surprised :)

  9. amnesia7 16. Oct, 2009 at 7:03 am #

    Wow, looks really cool, but…..

    when I type the word “code” in the search box and let the ajax run the search rather than hitting Enter it display 1 to 5 of 38 so I scroll down and click Next and then I scroll down and click Next again but this second time the page reloads and I’m back to the start again. If I hit Enter though I get to go through all the other search results using the 1, 2, 3, 4 Prev, Next…..

  10. Marek Stasikowski 16. Oct, 2009 at 7:05 am #

    Yeah, could be useful, just remember not to over-extend your fancy stuff with options :)
    And sorry, I made a mistake; you stated you should write it in your controller, but still the header for that part of the post is called: “4. Building the Model” – hence the mistake.

    After all, I still think HTML should only be present in the View layer, and there only.

    Cheers and good luck with your effort, this is a really nice idea.

  11. Lam Nguyen 16. Oct, 2009 at 11:03 am #

    @Killian: yes, I was really surprised :D
    @amnesia7: It caused by number of characters to display. Sometime, you content will break line; and JSON format will be brake by the line break. Just change from 100 to 50 displayed character, it’s ok now.
    @Marek Stasikowski: Thanks for your comments. And this is not my idea. I saw it on Mediatemple, and I want to write some code for the tutorial :D . Thanks! :D

  12. Polprav 20. Oct, 2009 at 5:41 am #

    Hello from Russia!
    Can I quote a post in your blog with the link to you?

  13. jack 26. Oct, 2009 at 9:38 pm #

    I can not setting.

    Fatal error: Class ‘Controller’ not found in D:\AppServ\www\www\LiveSearch\system\application\controllers\search.php on line 3

    $config['base_url'] = “http://localhost/www/LiveSearch/”;

    what’s wrong?

  14. Lam Nguyen 26. Oct, 2009 at 10:42 pm #

    Did you merge all files downloaded with your CodeIgniter folder? The problem you got seem to be caused by missing the Controller class of CodeIgniter.

    In my download, I just attached files that I worked on.

  15. PHP 28. Oct, 2009 at 2:11 am #

    $offset=($current_page-1)*$post_per_page;
    if($current_page==1) {
    $offset = 0;
    }
    if statement and assignment in it is completely useless because on page 1 result of offset will be 0 (1-1=0, 0 * some = 0). No need to assign it to 0 again.

  16. tsukisu 08. Nov, 2009 at 9:03 pm #

    This is what I have searched for long!
    Thank you for your work.

    Please continue to make good tools for codeigniter users.

  17. Mark 10. Nov, 2009 at 5:29 pm #

    I’ve downloaded the files and i get this error in my firebug:

    A PHP Error was encountered

    Severity: Notice
    Message: Undefined index: query
    Filename: controllers/search.php
    Line Number: 24

    Line 24 is: $query = trim($_GET['query']);

    I’ve included: parse_str($_SERVER['QUERY_STRING'],$_GET);

    if I changed line 24 to $query = “string”; everything works fine (ajax, results, etc..) Just the query is not dynamic.. which is the whole goal of this code…haha!

  18. Mark 10. Nov, 2009 at 7:52 pm #

    SOLVED:

    http://codeigniter.com/forums/viewthread/132757/

  19. Lam Nguyen 10. Nov, 2009 at 11:30 pm #

    Glad to hear that, Mark!

  20. Vasy 22. Nov, 2009 at 12:18 pm #

    Anyone having problems with IE7 or IE8 ?

  21. Seo World 23. Nov, 2009 at 5:16 pm #

    Great work there. Awesome code, powerfull search script.

  22. Richard 27. Nov, 2009 at 3:38 pm #

    I’m trying to append your code to this table
    CREATE TABLE IF NOT EXISTS `notes` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `title` varchar(25500) NOT NULL,
    `unique_id` varchar(255) NOT NULL,
    `create_date` datetime NOT NULL,
    `lastChangeDate` datetime NOT NULL,
    `content` longtext NOT NULL,
    PRIMARY KEY (`id`),
    FULLTEXT KEY `note_content` (`content`),
    FULLTEXT KEY `title` (`title`,`content`),
    FULLTEXT KEY `yarpp_content` (`content`),
    FULLTEXT KEY `yarpp_title` (`title`)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=391 ;
    so I can search my notes that I store in a database. I can’t figure out why I’m not getting results returned. I went in to the code and replace all the post with notes and modified all sql so it not using wp_posts. Any help would be help great

  23. Lam Nguyen 27. Nov, 2009 at 6:50 pm #

    I’m sorry about this stupid question, but have you changed the name of data columns?

  24. Richard 27. Nov, 2009 at 8:14 pm #

    Yeah from what I can tell I have mapped the $note['columnName'] on all of them

  25. Martin 07. Dec, 2009 at 4:09 pm #

    You could use escapeshellcmd().

  26. ghprod 17. Dec, 2009 at 11:15 am #

    really” awesome advanced tutorial for codeigniter!!

    you are so young but so smart!!

    cheers

    regards

    thanks

  27. Sram 24. Dec, 2009 at 7:49 am #

    Wow, mind blowing post!!!

    Thank you for sharing…

  28. Martini Ice 04. Jan, 2010 at 9:50 pm #

    Amazing Tutorial. Thank you!

  29. Jonathan 05. Jan, 2010 at 3:24 pm #

    Is it me or is it bugged in IE8?

    When I try to do a search it won’t slide (demo is broken too)

  30. Jonathan 05. Jan, 2010 at 4:33 pm #

    Fixed the IE8 bug!

    It has to do with trailing comma’s

    1. Open search.php (model)
    2. Find ‘foreach($posts as $post) {‘ (~line 55)
    3. Add above: ‘$i = 0;’
    4. Find ‘ $post_content=$this->search_model->cleanHTML($post['shortDescription']);’
    5. Add below: ‘if($i>0){echo ‘,’;}’
    6. Find ‘”url”:”‘.$post['guid'].’”‘
    7. Remove trailing ‘,’
    8. Find ‘}’;’ (below step 7)
    9. Add below: ‘$i = $i+1;’

    It should work now!

    • bili 27. Jan, 2010 at 8:24 am #

      can you just copy your complite code hire, i have problem whit this. thx

      • Lam Nguyen 27. Jan, 2010 at 2:33 pm #

        Take a look at comment section!

  31. MIckey 23. Jan, 2010 at 12:23 pm #

    Hello Lam

    I downloaded your tutorial and configured everything as per your tutorial.
    The page comes up fine but when i search a term nothing happens?
    Firebug says:Firebug’s log limit has been reached. 0 entries not shown. Preferences
    GET http://localhost/live_search/search?query=html&output=json&page=1&limit=5
    GET http://localhost/live_search/search?query=html&output=json&page=1&limit=5

    404 Not Found
    7ms
    Any suggestions.

  32. Swetz 03. Feb, 2010 at 12:37 am #

    Hey LAM,

    wonderful post! i downloaded your tut n configured everything with codeigniter.. but prob comes up with search results… nothing happens! but if i remove post_content column from your select query at both places then 1 record comes when i search for ‘code’. for other keywords nothing happens.. please help or do u have any suggestions..?

    thanks

  33. Swetz 03. Feb, 2010 at 12:39 am #

    @Mickey: hey Mickey did u find any solution to ur prob? i m also facing same issue

    thanks

    • Lam Nguyen 03. Feb, 2010 at 1:09 am #

      Maybe you guys are getting problem with the url_rewrite. Please check the config of the url_rewrite.

    • Mickey 07. Feb, 2010 at 8:49 am #

      Hello Swetz

      Haven’t solved the problem yet.

      Are you using WAMP server?

      I’m sure its something to do with the url_rewrite code like Lam suggested.

      • Swetz 08. Feb, 2010 at 6:22 am #

        yeah m using wamp server.. ya correct its somethng to do with url_rewrite. i tried a lot :( but no success. this is really excellent tut.. i just hope it starts working soon..

  34. Mickey 06. Feb, 2010 at 11:20 am #

    Hello Lam

    I checked my url_rewrite code.

    The following is my .htacces file. (Its in the root folder live_search)

    RewriteEngine On
    RewriteBase /

    #Removes access to the system folder by users.
    #Additionally this will allow you to create a System.php controller,
    #previously this would not have been possible.
    #’system’ can be replaced if you have renamed your system folder.
    RewriteCond %{REQUEST_URI} ^system.*
    RewriteRule ^(.*)$ http://localhost/live_search/search/$1 [L]

    #Checks to see if the user is attempting to access a valid file,
    #such as an image or css document, if this isn’t true it sends the
    #request to index.php
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ http://localhost/live_search/search/$1 [L]

    I’m using WAMP server. Am I missing any php extentions for things to work?

    My tutorial folder is called “live_search”
    My routes in config file is $route['default_controller'] = ” “;
    My controller name is search.php (just like yours)

    Your help is highly appreciated. I would like to make this tutorial work.

  35. Mickey 10. Feb, 2010 at 11:55 am #

    Has anyone been successful with this tutorial using a WAMP server?

    I’d would really like to know why it doesn’t work.

    Thanks

    • Swetz 17. Feb, 2010 at 6:42 am #

      nope.. i havent found anything.. :(
      trying hard to make it work..

    • Swetz 17. Feb, 2010 at 6:47 am #

      hey m very sorry for this dumb ques! but can we not execute this tutorial without .htaccess? will it work? i really dont understand this .htaccess concept in this tutorial..

  36. Mickey 22. Feb, 2010 at 10:20 am #

    Hello Lam

    Could you revisit your download file for your tutorial.

    I have tried different Php versions, JQuery versions, different server environments etc.
    .htaccess has no effect if removed.

    Maybe a Php extentions is not loaded or there is a FullText search problem with the database (mysql ver).
    I’m using Php 5.2.9 , MySql ver 5.1.32, Apache 2.2.11

    Thank You for your anticipated response.

    • Lam Nguyen 22. Feb, 2010 at 12:18 pm #

      Maybe you are getting problem with the Full text search. Have you tried to do with normal search query? Actually, I don’t support this tutorial anymore, but I will take a look at the code again, and update it as soon as possible.

      By the way, try to disable the rewrite url and try with the real url.

      Thanks!

  37. oko 02. Mar, 2010 at 7:43 am #

    you have problem with pagination try click result to keyword code a you see what happen when you be at last link

  38. hugoandyou 05. Mar, 2010 at 1:00 am #

    Thank you for sharing…

Trackbacks/Pingbacks

  1. Tweets that mention CodeIgniter and jQuery Real Live Search with Pagination | AEXT.NET -- Topsy.com - 13. Oct, 2009

    [...] This post was mentioned on Twitter by Lam Nguyen, Web Design News. Web Design News said: CodeIgniter and jQuery – Real Live Search with Pagination http://bit.ly/POh80 [...]

  2. CodeIgniter and jQuery – Real Live Search with Pagination | Web Design Updates - 14. Oct, 2009

    [...] CodeIgniter and jQuery – Real Live Search with Pagination [...]

  3. CodeIgniter and jQuery – Real Live Search with Pagination - 14. Oct, 2009

    [...] Visit Source. [...]

  4. links for 2009-10-14 .:: [aka щямукюшт] Ozver.in | Озверин - 14. Oct, 2009

    [...] I Had Known About jQuery(tags: jquery tips tutorial javascript webdesign development code webdev)CodeIgniter and jQuery Real Live Search with Pagination | AEXT.NET(tags: jquery codeigniter php mysql howto tutorials tutorial ajax)CSS Differences in Internet [...]

  5. CodeIgniter and jQuery – Real Live Search with Pagination | favSHARE.net - 15. Oct, 2009

    [...] Read the original article [...]

  6. 40+ CodeIgniter Framework Tutorials for Kick-Ass PHP Application | 2experts Design - Web Design and Graphic Design Blog - 15. Oct, 2009

    [...] 18. CodeIgniter and jQuery – Real Live Search with Pagination [...]

  7. 40+ CodeIgniter Framework Tutorials for Kick-Ass PHP Application | PHP Frameworks - 16. Oct, 2009

    [...] 18. CodeIgniter and jQuery – Real Live Search with Pagination [...]

  8. Aext.net: CodeIgniter and jQuery - Real Live Search with Pagination | Webs Developer - 20. Oct, 2009

    [...] the Aext.net website there’s been a recent tutorial looking at pagination in a CodeIgniter application using the jQuery Javascript library. In this [...]

  9. Aext.net: CodeIgniter and jQuery - Real Live Search with Pagination | Development Blog With Code Updates : Developercast.com - 20. Oct, 2009

    [...] the Aext.net website there’s been a recent tutorial looking at pagination in a CodeIgniter application using the jQuery Javascript library. In this [...]

  10. CodeIgniter and jQuery Real Live Search with Pagination | Design Newz - 22. Oct, 2009

    [...] CodeIgniter and jQuery Real Live Search with Pagination [...]

  11. 40+ CodeIgniter Framework Tutorials for Kick-Ass PHP Application | Programming Blog - 22. Oct, 2009

    [...] 18. CodeIgniter and jQuery – Real Live Search with Pagination [...]

  12. Aext.net: CodeIgniter and jQuery – Real Live Search with Pagination | pcsourcenetwork.com - 24. Oct, 2009

    [...] the Aext.net website there's been a recent tutorial looking at pagination in a CodeIgniter application using the jQuery Javascript library. In this [...]

  13. 100+ Mix of Great Community Links! | Master Design - 30. Oct, 2009

    [...] CodeIgniter and jQuery – Real Live Search with Pagination [...]

  14. 40+ CodeIgniter Framework Tutorials for Kick-Ass PHP Application | Son Of Byte - 02. Nov, 2009

    [...] 18. CodeIgniter and jQuery – Real Live Search with Pagination [...]

  15. links for 2009-11-08 « toonz - 08. Nov, 2009

    [...] CodeIgniter and jQuery Real Live Search with Pagination | AEXT.NET (tags: tutorial jquery php search) [...]

  16. 43 примера использования PHP фреймворка CodeIgniter | Vizor-IT blog - 28. Dec, 2009

    [...] CodeIgniter and jQuery – Real Live Search with Pagination [...]

  17. Getting Started with CodeIgniter and How to Create All Those Great Apps | DevSnippets - 23. Feb, 2010

    [...] 4.8 Real Live Search with Pagination [...]

  18. Getting Started with CodeIgniter and How to Create All Those Great Apps « Web Development News - 11. Mar, 2010

    [...] 4.8 Real Live Search with Pagination [...]

Leave a Reply

CommentLuv Enabled