CodeIgniter and Ajax using jQuery

Creating effective and usable Web 2.0 interfaces


CodeIgniter is a popular, lightweight, open source framework written in PHP and based on the Model-View-Controller (MVC) architectural pattern. jQuery is a fast, lightweight, open source JavaScript library designed to simplify manipulating HTML pages and Ajax interactions. When used together, they form a powerful foundation for rapidly developing usable Web sites and applications.

This article shows how to integrate these two systems into a single framework and how to use jQuery to improve the UI of an existing Web application. It assumes that you have both CodeIgniter version 1.7.2 or later and MySQL version 4.1 or later installed, and that you have a good working knowledge of both. In addition, you need the jQuery library version 1.4.2 or later.

Web 2.0: Ajax using jQuery

One of the most important aspects of Web 2.0 is that a user's experience is more like that of a desktop application than a Web site. Specifically, interaction with the Web page doesn't require "visual communication" with the Web server—for example, click Submit, wait for the Web server to process the submitted information, then the entire Web page refreshes with updated content. Instead, only the content that needs to change is updated, while the rest of the page remains in place.

This "submission-less" process works through the use of Ajax, which lets Web developers transmit information between a Web client (browser) and a Web server without requiring page refreshes. Better yet, this information transfer can be triggered without any direct user intervention.

When a Web page uses Ajax, it is asynchronously sending data to and receiving data from a Web server. This transmitted data is plain text and, therefore, can be in a number of different formats, such as XML, HTML, JSON, or just plain text.

The actual transmission of the data is executed using JavaScript and an API called XMLHttpRequest, and that's where jQuery enters the picture. The jQuery library has greatly simplified the process of using Ajax. And not only is using Ajax easier, but displaying the updated data is easier, too. (If you've ever tried traversing the HTML DOM with JavaScript, you'll really appreciate just how much easier it is!)

The existing CodeIgniter application

To demonstrate the power and simplicity of using jQuery with CodeIgniter, this article guides you through improving the UI of an existing Web application. This application was designed to help a teacher manage class activities and each parent's participation therein. The teacher first selects class activities from a list of board-approved options and schedules a date for each. Then, parents register on the site and enter the contact information for their child (or children). They can then view the list of class activities and select their level of participation (purchase supplies, help prepare, assist, or serve as an activity leader).

Note: This system could easily be applied to support a kids' sports team, YMCA group, and the like.

For this article, the application's database has been loaded with about 100 events, 5 parents, and 1 teacher. The parents' user names are parent1, parent2, . . . parent5. The teacher's user name is teacher, and all the passwords are ibm. You'll want to download the Web application and database and set them up on a Web server to follow along. The application requires that the CodeIgniter framework be at the root of the server.

Setting up jQuery

To start using jQuery, first download the library. Two files are offered for each version release: an uncompressed file and a "minified" file (this highly compressed version is faster to load but impossible to trace if you're so inclined). I recommend using the uncompressed version for development and the minified version for production.

Next, place the jQuery library file in the .assets/js folder at the root of your Web server. Then, create a new file in the same folder called global.js, as shown in Listing 1. This is where you'll place the JavaScript code for the entire application.

Listing 1. "Hello World" using jQuery
/* Global JavaScript File for working with jQuery library */

// execute when the HTML file's (document object model: DOM) has loaded
$(document).ready(function() {

  alert ('Hello World');

For this article—and most applications—much of the jQuery code will reside inside the $(document).ready() function. This function is automatically triggered only after the HTML file's DOM has finished loading.

For the application to load both of these files, edit the ./system/application/views/template.php file, as seen in Listing 2.

Listing 2. Loading jQuery and the global JavaScript file
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />

<link href="/assets/css/screen.css" rel="stylesheet" type="text/css" />

<!--  the following two lines load the jQuery library and JavaScript files -->
<script src="/assets/js/jquery-1.4.2.js" type="text/javascript"></script>
<script src="/assets/js/global.js" type="text/javascript"></script>

<title><?php echo $title;?></title>

Now, navigate to the index page of the Web site. When the page loads, a JavaScript alert will say "Hello World."

Using jQuery and Ajax with CodeIgniter

With the jQuery library and global.js file in place, you're ready to start improving the application's interface. If you haven't already, take a few minutes to log in as a parent and a teacher to become familiar with how activities work in the system.

Automatic username validation

The first place you'll improve the UI is on the Registration page. Currently, the validation for whether a username has been taken is done after the user submits the page. However, with Ajax, you can run the server-side validation and return the results without requiring any page submission.

To do so, bind code to the username field's onblur() event, which is triggered when the user's cursor leaves the field. Listing 3 shows the updated global.js file.

Listing 3. Checking whether a username is already registered
/* Global JavaScript File for working with jQuery library */

// execute when the HTML file's (document object model: DOM) has loaded
$(document).ready(function() {

  // use element id=username 
  // bind our function to the element's onblur event
  $('#username').blur(function() {

    // get the value from the username field                              
    var username = $('#username').val();
    // Ajax request sent to the CodeIgniter controller "ajax" method "username_taken"
    // post the username field's value
      { 'username':username },

      // when the Web server responds to the request
      function(result) {
        // clear any message that may have already been written
        // if the result is TRUE write a message to the page
        if (result) {
          $('#username').after('<div id="bad_username" style="color:red;">' +
            '<p>(That Username is already taken. Please choose another.)</p></div>');


This code creates a jQuery object using the DOM element with an ID of username. It then calls the jQuery blur() method, which binds a function to the onblur() event for the username field. This function posts the value in the username field, using Ajax, to the CodeIgniter controller named ajax and its method, username_taken. Next, it clears any existing error message and, based on the result of the Ajax post, displays or does not display an error message.

Next, in ./system/application/controllers, create a file called ajax.php, which is referred to by the jQuery Ajax .post() method. Listing 4 shows the source code for this controller. (Note that there is nothing special about naming the controller ajax. It could be called anything as long as the URL in the .post() method refers to the correct controller.)

Listing 4. The CodeIgniter controller that processes Ajax requests

class Ajax extends Controller {

  public function Ajax() {

  public function username_taken()
    $this->load->model('MUser', '', TRUE);
    $username = trim($_POST['username']);
    // if the username exists return a 1 indicating true
    if ($this->MUser->username_exists($username)) {
      echo '1';


/* End of file ajax.php */
/* Location: ./system/application/controllers/ajax.php */

Notice that the username_taken() method does not return a value. Rather, it echoes its response, and this is an important point. The jQuery Ajax request posts data to a Web page and uses the resulting page data; it's not programmatically touching the method itself.

Now, your first Ajax function is complete. Navigate to the Registration page and register with any user name that is already taken to see the appropriate error message.

Interestingly enough, there's an unintentional result of the jQuery code as written. The Ajax function is bound to fields with an ID of username, which includes the username field on the Login page. Listing 5 shows how to modify the jQuery object so that it only binds to the username field within the registration_form form.

Listing 5. Qualifying the correct username field
  // use element id=username within the element id=registration_form
  // bind our function to the element's onblur event
  $('#registration_form').find('#username').blur(function() {

Seamless status update and storage

The next UI improvement is on the Class Activity Listing page. For a parent to indicate his or her participation for a particular activity, the parent clicks the appropriate radio button, then clicks the save link to submit the page. To improve the UI, remove the requirement to click the save link and, therefore, the need to submit the page at all.

First, add the following code to the global.js file. It's split across Listing 6, Listing 7, and Listing 8 to more easily describe the process.

Listing 6. Using jQuery to get related element values
  // use input element name=participation_type_id and type=radio
  // bind our function to the element's onclick event
  $('input[name=participation_type_id]:radio').click(function() {
    var participation_type_id = this.value;

    // create global variables for use below
    var class_activity_id, user_id;
    // get the form's two hidden input elements 
    // each is a sibling of the parent of the clicked radio button
    // store their values in the global variables
    var hidden_elements = $(this).parent().siblings('input:hidden');
    $(hidden_elements).map(function() {
      if ( == 'class_activity_id') {
        class_activity_id = this.value;
      if ( == 'user_id') {
        user_id = this.value;

This function is bound to the onclick() event of any radio button named participation_type_id. It gets the value of the clicked radio button. Then, it uses a set of chained methods to return the hidden form elements. The map() method passes each element through its function, retrieving the class_activity_id and user_id values.

Having identified the values required to set a parent's participation, the code executes an Ajax request to save this information, as seen in Listing 7. The server's response to this request does not echo any data, so the jQuery response function is empty (and could actually have been removed).

Listing 7. Posting an Ajax request to CodeIgniter
    // Ajax request to CodeIgniter controller "ajax" method "update_user_participation"
    // post the user_id, class_activity_id and participation_type_id fields' values
      { 'user_id':user_id, 
        'participation_type_id':participation_type_id },
      // when the Web server responds to the request
      function(result) { }

Finally, the text next to the radio buttons is changed to the appropriate color using the jQuery next() method to target each string. This code is shown in Listing 8.

Listing 8. Dynamically changing the color of the radio button text
    // set the text next to the clicked radio button to red
    $(this).next().css("color", "red");

    // set the text next to the remaining radio buttons to black
    var other_r_buttons = $(this).siblings('input[name=participation_type_id]:radio');
    $(other_r_buttons).map(function() {
      $(this).next().css("color", "black");


Now that the jQuery code has been written, you need to create the update_user_participation() method in the ajax controller, as seen in Listing 9.

Listing 9. Processing user participation in CodeIgniter
  public function update_user_participation()
    $this->load->model('MActivity', '', TRUE);

This method uses the set_user_participation() method already found in the MActivity model, which takes variables posted by the Ajax request.

Finally, comment out the save link in ./system/application/controller/activity.php, as shown in Listing 10.

Listing 10. Removing the unnecessary save link
          '<span style="style="white-space: nowrap;">'.
          /* the save link is no longer needed
            '<a href="" onclick="document.forms[\'form_'.$activity->id.'\'].submit();
return false;">save</a>'. */

You can now change a parent's participation, and it will be automatically saved without a page refresh.

Autosuggest input field

One of the most effective and widespread uses of Ajax is the autosuggest or autocompletion functionality. Log in as a teacher, and click Manage Class Activities. To add an activity, users must scroll down the long list of possible activities. To improve the UI, add an input field bound to an autosuggest function at the top of the ./system/application/views/activity_master_listing.php file, as seen in Listing 11. Doing so allows the teacher to more easily select from all the unscheduled activities.

Listing 11. Adding an autosuggest input field
<div id="select_anchor">
  <a href="" onclick="$('#select_anchor').hide(100); 
    return false;">
    Select an unscheduled Activity to add >></a>
  <br /><br />
<div id="select_activity" class="requested_activity" style="display:none;">
    <caption>&nbsp;Select an unscheduled Activity</caption>
    <tr class="odd_row_add">
        Begin by typing a few letters of an activity name<br />
        then select from the resulting list<br />
        <br />
        <input type="text" value="" id="class_activity" 
          onkeyup="autosuggest(this.value);" class="autosuggest_input" />
        <div class="autosuggest" id="autosuggest_list"></div>

Take note of the two jQuery objects and methods bound to the JavaScript onclick() event. Remember that jQuery is simply a JavaScript library and can seamlessly interact with JavaScript throughout an application, not just within the $(document).ready() function.

Next, outside the $(document).ready() function in the global.js file, implement the following JavaScript function. It is bound to the onkeyup() event of the class_activity input field. The source code is shown in Listing 12.

Listing 12. Implementing autosuggest with jQuery
// triggered by input field onkeyup
function autosuggest(str){
  // if there's no text to search, hide the list div
  if (str.length == 0) {
  } else {
    // first show the loading animation
    // Ajax request to CodeIgniter controller "ajax" method "autosuggest"
    // post the str parameter value
      { 'str':str },
      function(result) {
        // if there is a result, fill the list div, fade it in 
        // then remove the loading animation
        if(result) {

Notice that although this function is not within the $(document).ready() function, it still uses jQuery objects and methods. Its jQuery .post() method is calling the Ajax controller's autosuggest() method, which echoes an unordered list of autosuggest results. Listing 13 shows this code.

Listing 13. Retrieving and echoing autosuggest results
  public function autosuggest()
    // escapes single and double quotes
    $str = addslashes($_POST['str']);
    $this->load->model('MActivity', '', TRUE);
    $unscheduled_activities_qry = $this->MActivity->find_unscheduled_activities($str);
    // echo a list where each li has a set_activity function bound to its onclick() event
    echo '<ul>';
    foreach ($unscheduled_activities_qry->result() as $activity) {
      echo '<li onclick="set_activity(\''.addslashes($activity->name).'\'';
      echo ', '.$activity->id.');">'.$activity->name.'</li>'; 
    echo '</ul>';

Next, add the find_unscheduled_activities() method to return the autosuggest results from the database. Listing 14 contains the code from ./system/application/models/mactivity.php.

Listing 14. Querying the database for unscheduled activities
  // Finds all unscheduled activities that match the passed string
  function find_unscheduled_activities($str)
    $this->db->select('id, name
        FROM master_activity 
        WHERE name LIKE \''.$str.'%\'
          AND id NOT IN 
            (SELECT master_activity_id FROM class_activity)
          ORDER BY name', FALSE);
    return $this->db->get();

You'll also want to style the autosuggest <div> and list so that the UI is clearer and the list elements are clickable. The styles added to ./assets/css/screen.css are shown in Listing 15.

Listing 15. Making the autosuggest list clear and clickable
/* Autosuggest */

.autosuggest {
  border:1px solid #000000;

.autosuggest ul li {

.autosuggest ul li:hover {


.autosuggest_input {

.table_header_add {

.odd_row_add {

You're about halfway done. You can type characters into the field to retrieve a set of matching activities. Now, implement the code to select, display, and save an activity for the class. Begin by adding two functions to the global.js file to set the activity name field and display a row with the activity's information. Listing 16 shows the source code for both.

Listing 16. Getting and displaying the selected activity
// triggered by an onclick from any of the li's in the autosuggest list
// set the class_acitity field, wait and fade the autosuggest list
// then display the activity details
function set_activity(activity_name, master_activity_id) {
  setTimeout("$('#autosuggest_list').fadeOut(500);", 250);

// called by set_activity()
// get the HTML to display and display it
function display_activity_details(master_activity_id) {
  // Ajax request to CodeIgniter controller "ajax" method "get_activity_html"
  // post the master_class_activity parameter values
    { 'master_activity_id':master_activity_id },
    // when the Web server responds to the request
    // replace the innerHTML of the select_activity element
    function(result) { 

This code also uses Ajax to get the table row that displays the selected activity. Its HTML is generated by the code in Listing 17.

Listing 17. Echoing the HTML table displaying an activity
  public function get_activity_html()
    $this->load->model('MActivity', '', TRUE);

    $requested_activity_id = $_POST['master_activity_id'];
    $requested_activity_qry = 

    // code leveraged from /controllers/activity.php manage_class_listing() method
    // generate HTML table from query results
    $tmpl = array (
      'table_open' => '<table>',
      'heading_row_start' => '<tr class="table_header_add">',
      'row_start' => '<tr class="odd_row_add">' 
    $this->table->set_caption('&nbsp;Add this Activity'); 

    $this->table->set_heading('<span class="date_column">Date</span>',
                  '<span class="activity_name_column">Activity Name</span>',
                  '<span class="address_column">Address</span>',
                  'City', 'Details');
    $table_row = array();

    foreach ($requested_activity_qry->result() as $activity)
      $m_id = $activity->master_activity_id;

      $table_row = NULL;

      $table_row[] = ''.
        '<form action="" name="form_'.$m_id.'" method="post">'.
        '<input type="hidden" name="master_activity_id" value="'.$m_id.'"/> '.
        '<input type="text" name="activity_date" size="12" /> '.
        '<input type="hidden" name="action" value="save" /> '.
        '<span class="help-text">format: MM-DD-YYYY</span><br/>'.
        '<a href="" onclick="document.forms[\'form_'.$m_id.'\'].submit();'.
        'return false;">save</a>';

      $table_row[] = '<input type="text" value="'.$activity->name.
        '" id="class_activity" onkeyup="autosuggest(this.value);"'.
        'class="autosuggest_input" />'.
        '<div class="autosuggest" id="autosuggest_list"></div>';
      $table_row[] = htmlspecialchars($activity->address);
      $table_row[] = htmlspecialchars($activity->city);
      $table_row[] = htmlspecialchars($activity->details);

    $requested_activities_table = $this->table->generate();

    echo $requested_activities_table;


This code was leveraged from the activity controller with only a few modifications, including echoing the final table, not returning it. It requires the SQL query shown in Listing 18 from ./system/application/models/mactivity.php.

Listing 18. Returning the requested master activity
  // Returns a single master activity record
  public function get_requested_master_activity($id)
    $this->db->select('id as master_activity_id, name, address, city, details');
    $this->db->where('id', $id);
    return $this->db->get('master_activity');

Finally, although you can already add a new activity, you want to remove the unscheduled activities and re-sort the list in ascending order. The updated SQL code from the MActivity model is shown in Listing 19.

Listing 19. Only returning unscheduled activities
  // Retrieve all master activity records
  function list_class_activities($activity_id)
    // get all records
    if (!$activity_id) {
      $this->db->select(' as master_activity_id,, 
                ma.details, as class_activity_id,
            FROM master_activity ma
            /*LEFT*/ JOIN class_activity ca ON ca.master_activity_id =
            ORDER BY /*DESC*/,', FALSE);
      return $this->db->get();
    // get all records except the one being requested
    } else {
      $this->db->select(' as master_activity_id,, 
                ma.details, as class_activity_id,
            FROM (SELECT * FROM master_activity 
              WHERE != '.$activity_id.') ma
            /*LEFT*/ JOIN class_activity ca ON ca.master_activity_id =
            ORDER BY /*DESC*/,', FALSE);
      return $this->db->get();

Visual calendar for date selection

The final UI improvement you'll make is to replace the text input fields for entering dates with a visual calendar. To do so, use the jQuery UI Datepicker, which is a popular plug-in from the jQuery UI library (an open source extension of the jQuery library). Update the ./system/application/views/template.php file as shown in Listing 20.

Listing 20. Including the jQuery UI Datepicker
<!-- including the jQuery UI Datepicker and styles -->
<script src=""
<link href="/assets/css/jquery-ui-1.7.2.custom.css" rel="stylesheet" type="text/css" />
<style type="text/css">
  /* jQuery UI sizing override */
  .ui-widget {font-size:1em;}

Notice that instead of having downloaded the library, the <script> tag references, which is a free repository for many libraries, such as the jQuery UI. The CSS file and images were configured to contain only the necessary styles ( Finally, the jQuery UI library is built assuming a body font size of 62.5%, so you override its default to size it appropriately.

The Datepicker works by being bound to a CSS class or ID within your HTML. For the edit activity function, assign a class called date-picker to the date input field in ./system/application/controllers/activity.php around line 210. The code is shown in Listing 21.

Listing 21. Assigning the date-picker class for edits
          // add the date-picker class to the date input field
          '<input type="text" name="activity_date" size="12" value="'.
            date('m/d/Y', strtotime($activity->date)).'" class="date-picker" /> '.
          '<input type="hidden" name="action" value="update" /> '.
          '<span class="help-text">format: MM/DD/YYYY</span><br/>'.

For the add activity function, assign the same class to the date input field in ./system/application/controllers/ajax.php around line 83, as seen in Listing 22.

Listing 22. Assigning the date-picker class for adds
        // add the date-picker class to the date input field
        '<input type="text" name="activity_date" size="12" class="date-picker" /> '.
        '<input type="hidden" name="action" value="save" /> '.
        '<span class="help-text">format: MM/DD/YYYY</span><br/>'.

Finally, bind the Datepicker so that it shows up when editing or adding a class activity. The code to place inside the $(document).ready() function in the global.js file is shown in Listing 23.

Listing 23. Binding Datepicker to a class
  // bind the Datepicker to the date-picker class

Now try to edit a class activity. When you place your cursor in the date input field, a calendar appears, allowing you to select a date for the activity. However, notice that this doesn't work when trying to add an activity. That's because the add activity HTML is written after the document has already been loaded (using Ajax), so the Datepicker is not bound to its date input field. To fix this, you bind the Datepicker to the date input field after the Ajax function writes the HTML. This change to the display_activity_details() function in the global.js file is shown in Listing 24.

Listing 24. Binding Datepicker to the add date field
    function(result) { 

      // because the add datepicker is not loaded with the DOM
      // manually add it after the date input field is written

Now, you can add a class activity using the Datepicker calendar.


Kudos on a job well done! You have learned to combine DOM manipulation through jQuery objects and achieve seamless communication through Ajax to significantly improve the UI of this application. And in many cases, the code to do so was quite small. Now, you might enjoy the challenge of further enhancing the application by having the class activity edit happen inline using Ajax or implementing any other UI ideas that you may have had while reading this article.

Related topics


Sign in or register to add and subscribe to comments.

Zone=Web development
ArticleTitle=CodeIgniter and Ajax using jQuery