CodeIgniter and jQuery – Real Live Search with Pagination
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
- PHP Framework: CodeIgniter
- Javascript Framework: jQuery 1.3.2
- Debug tool: Firebug
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.
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_modelthat 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"> </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"> </div>                   </div>                   <div class="clearfix"id="subnavclear"> </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:

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"> </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"> </div>         </dt>         <?php else: ?>         <dt>             <span class="results_meta">There were no results</span>             <div class="clearfix"> </div>         </dt>         <dt>         <div class="clearfix"> </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"> </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"> </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!
Pingback: Tweets that mention CodeIgniter and jQuery Real Live Search with Pagination | AEXT.NET -- Topsy.com
Pingback: CodeIgniter and jQuery – Real Live Search with Pagination | Web Design Updates
is awesome
Pingback: CodeIgniter and jQuery – Real Live Search with Pagination
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!
This is so cool! As a side effect it shows how to “integrate” codeigniter with wordpress.
Cool!
Nice article! 😉
Thanks for your interesting! 😀
Pingback: links for 2009-10-14 .:: [aka щÑмукюшт] Ozver.in | Озверин
Why do you insert chunks of HTML into the model? Isn’t that something awful and to-be-avoided at all cost?
@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 😀
Pingback: CodeIgniter and jQuery – Real Live Search with Pagination | favSHARE.net
Pingback: 40+ CodeIgniter Framework Tutorials for Kick-Ass PHP Application | 2experts Design - Web Design and Graphic Design Blog
Nice article, but you should watch out for some characters : in the demo, try to type or ‘, then press Enter, you may be surprised
Pingback: 40+ CodeIgniter Framework Tutorials for Kick-Ass PHP Application | PHP Frameworks
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…..
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.
@Killian: yes, I was really surprised 😀
@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! 😀
Hello from Russia!
Can I quote a post in your blog with the link to you?
@Polprav Of course, you can!
Pingback: Aext.net: CodeIgniter and jQuery - Real Live Search with Pagination | Webs Developer
Pingback: Aext.net: CodeIgniter and jQuery - Real Live Search with Pagination | Development Blog With Code Updates : Developercast.com
Pingback: CodeIgniter and jQuery Real Live Search with Pagination | Design Newz
Pingback: 40+ CodeIgniter Framework Tutorials for Kick-Ass PHP Application | Programming Blog
Pingback: Aext.net: CodeIgniter and jQuery – Real Live Search with Pagination | pcsourcenetwork.com
I can not setting.
Fatal error: Class ‘Controller’ not found in D:AppServwwwwwwLiveSearchsystemapplicationcontrollerssearch.php on line 3
$config[‘base_url’] = “http://localhost/www/LiveSearch/”;
what’s wrong?
Needs to be CI_Controller
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.
$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.
Pingback: 100+ Mix of Great Community Links! | Master Design
Pingback: 40+ CodeIgniter Framework Tutorials for Kick-Ass PHP Application | Son Of Byte
Pingback: links for 2009-11-08 « toonz
This is what I have searched for long!
Thank you for your work.
Please continue to make good tools for codeigniter users.
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!
SOLVED:
http://codeigniter.com/forums/viewthread/132757/
Glad to hear that, Mark!
Anyone having problems with IE7 or IE8 ?
Great work there. Awesome code, powerfull search script.
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
I’m sorry about this stupid question, but have you changed the name of data columns?
Yeah from what I can tell I have mapped the $note[‘columnName’] on all of them
You could use escapeshellcmd().
really” awesome advanced tutorial for codeigniter!!
you are so young but so smart!!
cheers
regards
thanks
Wow, mind blowing post!!!
Thank you for sharing…
Pingback: 43 примера иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ PHP фреймворка CodeIgniter | Vizor-IT blog
Amazing Tutorial. Thank you!
Is it me or is it bugged in IE8?
When I try to do a search it won’t slide (demo is broken too)
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!
can you just copy your complite code hire, i have problem whit this. thx
Take a look at comment section!
Hello Jonathan
I tried your code for the IE8 fix but it had no effect.
Was there anything else that i missed?
Thanks
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.
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
@Mickey: hey Mickey did u find any solution to ur prob? i m also facing same issue
thanks
Maybe you guys are getting problem with the url_rewrite. Please check the config of the url_rewrite.
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.
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..
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.
Has anyone been successful with this tutorial using a WAMP server?
I’d would really like to know why it doesn’t work.
Thanks
nope.. i havent found anything..
trying hard to make it work..
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..
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.
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!
Hello Lam
I got your tutorial working!
Just one more problem to fix. I’m sure its simple.
When i type a search word it all works fine. If I press the enter key I get an error
Parse error: parse error in C:wampwwwlive_searchsystemapplicationviewssearch_result.php on line 52
Can I disable this error?
Pingback: Getting Started with CodeIgniter and How to Create All Those Great Apps | DevSnippets
you have problem with pagination try click result to keyword code a you see what happen when you be at last link
Thank you for sharing…
Pingback: Getting Started with CodeIgniter and How to Create All Those Great Apps « Web Development News
I have a private question for you.
Are you VietNamese? And where do you live?
dude you left pass in database.php file
Oh I did move to another hosting provider! So I think it’s fine 😀 To someone cannot see the demo works: the database server is not configured correct after I changed hosting, but the source works. Thanks!
Fantastic!!
This is what I have searched for long!
Thank you for your work.
interesting stuff
.-= Adrian Botea´s last blog ..edigram catering =-.
not everyone is comfortable with frameworks . if you are looking for a non objection orienred style ,you can find a fancy live search tutorial here :
http://youhack.me/2010/04/28/creating-a-fancy-search-feature-with-php-mysql-and-jquery/
i hope this save someone ‘s time !
Pingback: Getting Started with CodeIgniter and How to Create All Those Great Apps | PHP Lovers
Pingback: 40+ CodeIgniter Framework Tutorials for Kick-Ass PHP Application
Pingback: 40+ CodeIgniter Framework Tutorials for Kick-Ass PHP Application | Hassan C
getting an error:
Object not found!
i used search term = example
url is returning
http://localhost/ci_search/search?query=example
could you helpout
thanks
I get the same error, did you find a solution?
Thank you for your work. and good luck
Hello Lam,
Thanks for your article,is very helpfull for learning Code ignitor, because the official documentation is poor of this light framework.
Please fix the demo online.
I’am unable to run the demo, i pasted the files, changed configuration file database.php and config.php and when i call to the controller search, example:
http://localhost/search
My CPU goes to 100% and never displays something, probable there is a loop.Anyways the tutorial is interesting.
Regards
what’s Happening i am new to this, I stumbled upon this I’ve found It positively helpful and it has aided me out loads. I hope to contribute & help other users like its helped me. Great job.
Hey,
Sorry to bother you, but the following images are missing from your download package and unfortunately, the script demo is also down, so I can’t retrieve them from there, here’s what’s missing.
1. livesearch_bg.png
2. livesearch_bg2.png
3. livesearch_bg3.png
If you could either email those to me, or re-up the file, it would be greatly appreciated!
Nice article about using codeigniter with ajax. But your demo is not working.
Hi, Is a nice demo, I download it and configure it, but seems like its not working, when I try to search there is a Json error.
Did anybody got a solution for this?
Thanks
Are you pretty sure there is data flow between the model and the view? ._.
A Database Error Occurred
Error Number: 1064
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘key ) AGAINST (‘dasar’)’ at line 1
SELECT * FROM pdf_upload WHERE MATCH ( key ) AGAINST (‘dasar’)
Filename: C:xampphtdocsp-cisystemdatabaseDB_driver.php
Line Number: 330
my query is
$sql = “SELECT * FROM pdf_upload WHERE MATCH ( key ) AGAINST (?) LIMIT ?,?”;
anyone can tell me why?
I use CI 2.1.0 and xampp 1.7.4
Pingback: 40+ CodeIgniter Framework Tutorials for Kick-Ass PHP Application | Best Open Source Resources for Web Developers | Designers