Monday, April 11, 2011

CRUD using jQuery and Codeigniter – I


You may get confuse while downloading jQueryUI. If you are new to jQueryUI, then simply download it with everything selected as shown below:
jQueryUI Download Page
You can select any theme from the right of the download page but I selected smoothness theme.

Placing Files in Codeigniter

Extract codeigniter zip file and rename it to “crud”. Now place it in “www” directory and move the “application” folder out of “system” folder. Although it’s not necessary but it separates core and user created files. Then create “js” directory within “crud” and copy jquery library there.
Now create css folder within crud folder. Then extract jQueryUI file and copy smoothness folder (jquery-ui-1.8.2.custom/css/smoothness) and paste it in crud/css folder. Similarly copy jquery-ui-1.8.2.custom/js/jquery-ui-1.8.2.custom.min.js file in crud/js folder.
The complete tree of files is shown below:
Directory Structure

Configuring Codeigniter

First make following changes in the crud/application/config/config.php file:
  1. On line number 14, change the value of $config['base_url'] to “http://localhost/crud”. This value may differ if you are using Mac.
Now open crud/application/config/routes.php and make following changes:
  1. On line number 43, change value of $route['default_controller'] to “home”. ‘default_controller’ specifies which controller to run when no controller name is specified in the URL. This is very similar to index.htm which runs by default.
Open crud/application/config/autoload.php and make these changes:
  1. On line number 42, make sure you loaded database library like this: $autoload['libraries'] = array( ‘database’ );
  2. On line number 54, set $autoload['helper'] to array( ‘url’, ‘form’ ). Here you specify those helpers which must be loaded on startup before running any controller.
Finally let’s configure crud/application/config/database.php. In this file you specify database details which you want to use in you application. Change following lines of code:
  1. On line 41, $db['default']['username'] = “root”.
  2. On line 42, $db['default']['password'] = “”. This must not be empty in case of Mac and Linux.
  3. On line 43, $db['default']['database'] = “crud”. This is actually the name of database you will use with you application.

Create Database

Now create a database “crud”.
CREATE DATABASE `crud` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
Create a table “users” having following structure:
CREATE TABLE `crud`.`users` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR( 100 ) NOT NULL ,
`email` VARCHAR( 200 ) NOT NULL
) ENGINE = MYISAM;
Enter some dummy data in users table:
INSERT INTO `crud`.`users`
( `id`, `name`, `email` )
VALUES ( NULL , 'Fawad Hassan', 'fawad@test.com' ),
( NULL , 'Bill Gates', 'bill@test.com' ),
( NULL , 'Steve Jobs', 'steve@test.com' ),
( NULL , 'Naveed Ahmad', 'naveed@test.com' ),
( NULL , 'Mr Zee', 'zee@test.com' );

Read Operation

Creating Model

Our first step is to create a model class which will contain all the data access logic. To do so we need to first write a model called mUsers. Create a file musers.php in crud/application/models folder and write following code in it:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class mUsers extends Model {
 
    public function getAll() {
 
        //get all records from users table
        $query = $this->db->get( 'users' );
 
        if( $query->num_rows() > 0 ) {
            return $query->result();
        } else {
            return array();
        }
 
    } //end getAll
 
} //end class
In the above model we only have one method called getAll(). This method uses Codeginiter’s Active Record method “get”. “get” method fetches all the records from “users” table in the database. Then there’s an if condition which checks that there are more than 0 record in the returned result array. If yes then it returns the resultant array of objects using:
$query->result();
In the else case, we are returning an empty array.
Note that this method returns an array of objects. To return array of arrays, you need to use result_array() method. Take a look at Codeigniter’s user guide for more detail on result and result_array.

Creating Controller

Now create home.php file in crud/application/controllers folder and write following code in it:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Home extends Controller {
 
 public function __construct() {
  parent::__construct();
  $this->load->model( 'mUsers' );
 }
 
 
 public function index()
 {
  $this->load->view( 'home' );
 }
 
 
 
 public function read() {
  echo json_encode( $this->mUsers->getAll() );
 }
 
} //end class
In constructor of Home class, we are calling parent constructor and loading mUsers model which we created previously.
In Codeigniter’s controller, index method runs by default even if method name is not provided in the URI. In our index method we are only loading the home view which we haven’t created yet.
Finally there’s a read method which calls the getAll method of mUsers and passes the result in json_encode function. This is a PHP5 function and it converts the PHP arrays and objects into json format and returns it as a string. Then I simply echo the returned json string because I will use the read method for ajax operation.

Creating View

Create a new file “home.php” in crud/application/views and write following code in it:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<html>
 
<head>
    <title>CRUD Operations using jQuery and Codeigniter</title>
 
    <base href="<?php echo base_url(); ?>" />
 
    <link type="text/css" rel="stylesheet" href="css/styles.css" />
</head>
 
<body>
    <table id="records"></table>
 
    <script type="text/javascript" src="js/jquery-1.4.2.min.js"></script>
    <script type="text/javascript" src="js/jquery-templ.js"></script>
 
    <script type="text/template" id="readTemplate">
        <tr>
            <td>${id}</td>
            <td>${name}</td>
            <td>${email}</td>
        </tr>
    </script>
 
    <script type="text/javascript" src="js/all.js"></script>
 
</body>
</html>
On line 5, I write base tag and specify its href value equal to base_url(). Now every relative link we give in our view will be relative to the returned value from base_url(). This returned value is the same as we give in config.php. In our case base_url is http://localhost/crud.
On line 12, I wrote a blank table having id “records”. This table will contain all the records returned from server via Ajax call.
On line 14, I included jQuery core file and on line 15, I included Microsoft’s jQuery template plugin. On line 17 to 23, I defined a template which I will use to display records returned from server. Note that in this template each row will contain 3 columns having id, name, and email. Note the syntax of template variables used here. ${id} is where the id of each record goes. Similarly name, and email will be replaced in place of ${name} and ${email}. Finally the type of template is text/template and id is readTemplate.
In the end we included all.js file which we haven’t created yet. Now create this file in crud/js folder.

Performing Read Ajax Call

Now open all.js and write following code in it:
1
2
3
4
5
6
7
8
9
$( function() {
    $.ajax({
        url: 'index.php/home/read',
        dataType: 'json',
        success: function( response ) {
            $( '#readTemplate' ).render( response ).appendTo( "#records" );
        }
    });
});
Each line of above code is explained below:
  1. First line checks “Is DOM loaded completely?”. If yes then execute the code inside its body. This is similar to window.onload event.
  2. Then an Ajax call is performed with $.ajax() method and an object (object injavascript is denoted by curly braces {} ) with some properties is sent as anargument.
  3. The first property of passed object is url. It specifies where Ajax request must be sent? In our case we are sending it to read method of home controller.
  4. Here we specify that the response from server is in json format. Remember that response from server comes in string format. So we need to parse it. This property tells jQuery to parse string in specified format.
  5. Final property or data member is success. Here we specified an anonymous function (function not having any name) which will receive the response from server in the argument “response”. Response can be in plain text, html, json, or xml. But in our case it’s in json format.
  6. In this line we select the template (which we wrote in script tag with type=”text/template”) having an id “readTemplate” and then render method is called. “render” method is part of template plugin which iterates over the response returned from server and insert each value in place of template variables like ${id}, ${name}, and ${email}. Then we append the returned value of render to #records table.
  7. Closing brace of success
  8. Closing brace of object passed to $.ajax method and closing parenthesis of $.ajax method.
  9. Finally closing brace of DOM ready function and closing parenthesis which encloses that function.
Viola! Ajax based reading part is almost done. Now try running it and you will see the table filled with the records coming from server. I know its looking dull so let’s integrate jQueryUI tabs to make it look better :)

Integrating jQueryUI Tabs

To integrate jQueryUI, you first need to link jQueryUI’s all-in-one CSS “css/smoothness/jquery-ui-1.8.2.custom.css” which I placed in css folder in installation step. Link this file before style.css
<link type="text/css" rel="stylesheet" href="css/smoothness/jquery-ui-1.8.2.custom.css" />
<link type="text/css" rel="stylesheet" href="css/styles.css" />
Then add a script tag whose src is “js/jquery-ui-1.8.2.min.js”. Note that this jQueryUI’s all-in-one script file which contains all the required core files plus code for widgets, interactions, and effects. All of these individual files are also present in jQueryUI downloaded zip file (you can find them in jquery-ui-1.8.2/development-bundle/ui). But for production always use the combined version which is present in jquery-ui-1.8.2/js/jquery-ui-1.8.2.custom.min.js. Now your script tags must look like this:
<script type="text/javascript" src="js/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.8.2.min.js"></script>
<script type="text/javascript" src="js/jquery-templ.js"></script>
Now change the body contents as shown below:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div id="tabs">
 
    <ul>
        <li><a href="#read">Read</a></li>
        <li><a href="#create">Create</a></li>
    </ul>
 
    <div id="read">
        <table id="records"></table>
    </div>
 
    <div id="create">Create form goes here...</div>
 
</div> <!-- end tabs -->
We wrapped everything within a div having an id of tabs. Then we created ul which contains the header links of tabs. Then we created two div elements. One for Read link, other one for Create link. Remember that href of links in ul must match the id of div to which it points to. For example href of Read link is #read and the div which it will open have an id of read.
Now you home view must look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<html>
<head>
    <title>CRUD Operations using jQuery and Codeigniter</title>
 
    <base href="<?php echo base_url(); ?>" />
 
    <link type="text/css" rel="stylesheet" href="css/smoothness/jquery-ui-1.8.2.custom.css" />
    <link type="text/css" rel="stylesheet" href="css/styles.css" />
</head>
 
<body>
 
<div id="tabs">
 
    <ul>
        <li><a href="#read">Read</a></li>
        <li><a href="#create">Create</a></li>
    </ul>
 
    <div id="read">
        <table id="records"></table>
    </div>
 
    <div id="create">Create form goes here...</div>
 
</div> <!-- end tabs -->
 
<script type="text/javascript" src="js/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.8.2.min.js"></script>
<script type="text/javascript" src="js/jquery-templ.js"></script>
 
<script type="text/template" id="readTemplate">
    <tr>
        <td>${id}</td>
        <td>${name}</td>
        <td>${email}</td>
    </tr>
 
</script>
 
<script type="text/javascript" src="js/all.js"></script>
 
</body>
</html>
You may have noticed how easy it’s to create structure for jQueryUI tabs. Finally all you have to do is call tabs() function of jQueryUI. I called it in all.js as shown below:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$( function() {
    $( '#tabs' ).tabs({
        fx: { height: 'toggle', opacity: 'toggle' }
    });
 
    $.ajax({
        url: 'index.php/home/read',
        dataType: 'json',
        success: function( response ) {
            $( '#readTemplate' ).render( response ).appendTo( "#records" );
        }
    });
 
});
On line 2, #tabs div is selected and then tabs() function is called on it. Also we passed a javacript object having some animation settings. fx property specifies what animation effects must be used when different tabs are clicked. I only toggled height and opacity css property. You can pass additional properties to tabs widget function. Check more options here.
All the functionality is done. Just add the following styles in css/styles.css file for visual appearance.
body {
    font-family: Arial, Helvetica, sans-serif;
}
 
#tabs {
    font-size: .9em;
    margin: 0 auto;
    width: 800px;
}
 
.ui-widget-content {
    font-size: .8em;
}
 
#records {
    font-size: 1em;
    width: 100%;
}
 
#records tr:nth-child(2n) {
    background: #EAEAEA;
}
 
#records tr:hover {
    background: #CCCCCC;
}
 
#records td {
    padding: 6px;
    margin: 8px;
}
Note that I used some of the CSS3 selectors so they will not work in older browsers. Now final output must look like this:
Final Output
In this part we learned how to perform read operation using Ajax call and displaying the response in a table. We also learned how to use jQueryUI tabs widget. In Part-II of this tutorial you will learn how to perform write, update, and delete Ajax calls. Also how to validate form data with jQuery.

1 comment: