CRUD using jQuery and Codeigniter – III

Learning Objectives

In Part 3 you will learn:

  1. How to filter form values to prevent XSS attack.
  2. What jQuery serialize method do and how to use it.
  3. How to send Ajax call to perform UPDATE operation using POST method.
  4. How to use jQuery advance selectors to update table rows.

Previous Parts

Get Source Files

Modify Model

First step is to add getById and update methods in mUsers model. Both of these methods are shown below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public function getById( $id ) {
    $id = intval( $id );
 
    $query = $this->db->where( 'id', $id )->limit( 1 )->get( 'users' );
 
    if( $query->num_rows() > 0 ) {
        return $query->row();
    } else {
        return array();
    }
}
 
public function update() {
    $data = array(
        'name' => $this->input->post( 'name', true ),
        'email' => $this->input->post( 'email', true )
    );
 
    $this->db->update( 'users', $data, array( 'id' => $this->input->post( 'id', true ) ) );
}

getById method accepts $id as parameter and returns a single record based on the passed id. Note that I used chaining of active record methods on line 3. This is possible if you are using PHP5. In PHP4 you will get error if you try to run this code. The code on line 3 will generate the following SQL.

SELECT * FROM users WHERE id = $id LIMIT 1

In update method, I used post method of input class to get the post variables. In every call to post, true is passed as a second parameter. This is done because I want post method to perform xss filtering before returning the value.

On line 19, the first parameter to active record’s update method is table name. Second parameter is the array $data containing new values which we want to update. Third parameter is also an array containing the id of record which we want to update.

Modify Controller

Now add two methods in Home controller with same names as in mUsers model (getById and update).

1
2
3
4
5
6
7
8
9
10
11
12
public function getById( $id ) {
    if( isset( $id ) )
        echo json_encode( $this->mUsers->getById( $id ) );
}
 
public function update() {
    if( !empty( $_POST ) ) {
            $this->mUsers->update();
 
            echo 'Record updated successfully!';
    }
}

First method simply calls getById method of mUsers model and the record which it returns is encoded in json format using json_encode.

Second method is also simple. If the $_POST is not empty, then it calls update method of mUsers method and echo a success message.

Modify View

The first thing which you need to add is the update form.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!-- update form in dialog box -->
<div id="updateDialog" title="Update">
    <div>
        <form action="" method="post">
            <p>
               <label for="name">Name:</label>
               <input type="text" id="name" name="name" />
            </p>
 
            <p>
               <label for="email">Email:</label>
               <input type="text" id="email" name="email" />
            </p>
 
            <input type="hidden" id="userId" name="id" />
        </form>
    </div>
</div>

Note that I enclosed the form in a div having id updateDialog. This is done because this form will appear in dialog box widget. Also the hidden field having id “userId” is will be used to store the userId of current record being edited.

Second change in the view is in template used to display records in a table rows

1
2
3
4
5
6
7
8
<script type="text/template" id="readTemplate">
    <tr id="${id}">
        <td>${id}</td>
        <td>${name}</td>
        <td>${email}</td>
        <td><a class="updateBtn" href="${updateLink}">Update</a> | <a class="deleteBtn" href="${deleteLink}">Delete</a></td>
    </tr>
</script>

The change is on line 2. I added id attribute in tr element.

Modify CSS

1
2
3
4
5
6
7
8
9
#delConfDialog, #msgDialog, #updateDialog {
    font-size: 1em;
}
 
#updateDialog label {
    display: inline-block;
    text-align: right;
    width: 90px;
}

In the first selector, only #updateDialog is added. The second selector with properties is totally new.

Modify Javascript

Steps Involved in Update Process

Before showing you the code, let’s take a look at the steps involved for updating a record.

  1. User clicks on Update link
  2. An Ajax request is sent to Home controller method getById to get the record which user wants to update
  3. On success, the values of the fetched record will be populated in the update form.
  4. jQuery UI’s Dialog widget appears containing update form.
  5. If user modifies content in form and click Update button, then the dialog containing update form will be closed and an Ajax call is sent to update method of Home controller. This Ajax call is sent via POST method and data in the form is also sent.
  6. update method of Home controller updates the record with the help of mUsers model and the message returned from it’s “Record updated successfully!”
  7. On success jQuery simply displays a msgDialog containing this message.
  8. Finally the new values are also updated in table row containing that record.

Add Variables

I hope you got the picture of update process in your mind. Now let’s modify the all.js file. First add two new variables updateHref and updateId at the top of js file.

1
2
3
4
5
6
var readUrl   = 'index.php/home/read',
    updateUrl = 'index.php/home/update',
    delUrl    = 'index.php/home/delete',
    delHref,
    updateHref,
    updateId;

Update Link Click Event

Now add a delegate method for update links in each table row.

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
$( '#records' ).delegate( 'a.updateBtn', 'click', function() {
    updateHref = $( this ).attr( 'href' );
    updateId = $( this ).parents( 'tr' ).attr( "id" );
 
    $( '#ajaxLoadAni' ).fadeIn( 'slow' );
 
    $.ajax({
        url: 'index.php/home/getById/' + updateId,
        dataType: 'json',
 
        success: function( response ) {
            $( '#name' ).val( response.name );
            $( '#email' ).val( response.email );
 
            $( '#ajaxLoadAni' ).fadeOut( 'slow' );
 
            //--- assign id to hidden field ---
            $( '#userId' ).val( updateId );
 
            $( '#updateDialog' ).dialog( 'open' );
        }
    });
 
    return false;
}); //end update delegate

On line 1 is the delegate method of jQuery which I already explained in Part 2.

On line 2, the value of href on which the user clicked is assigned to updateHref.

On line 3, the parents hierarchy of anchor tag on which user clicked is searched via parents() method for tr and then its id attribute is assigned to updateId

On line 7, ajax() method is called. This Ajax call will fetch the record which user wants to update and populate the text input fields of update form.

On line 8, url is defined where this Ajax call is sent. Note that we make use of updateId variable which we got from the parent tr.

On line 9, dataType is defined which tells in what format response must be parsed.

On line 11, success method is defined which receives response from the server as a parameter. Then this method assign values from response to input fields.

On line 12 and 13, name and email are assigned to input fields so that user can modify current values of fetched from server.

On line 18, the user id stored in variable updateId is assigned to hidden field having id userId. This is done because we need know which record we want to update when user clicks on the update submit button in the update form.

On line 20, updateDialog is opened containing update form.

Update Form

The updateDialog after completing js code will look like this:

Update Dialog containing Update Form

I showed this image so that you clearly understand what following code is doing.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$( '#updateDialog' ).dialog({
    autoOpen: false,
    buttons: {
        'Update': function() {
            $( '#ajaxLoadAni' ).fadeIn( 'slow' );
            $( this ).dialog( 'close' );
        },
 
        'Cancel': function() {
            $( this ).dialog( 'close' );
        }
    },
    width: '350px'
}); //end update dialog

Above code is for updateDialog which I opened in line 20 of previous code snippet. We are simply selecting updateDialog by id and calling jQueryUI’s dialog() method on it.

On line 2, I set autoOpen to false. This means that dialog will not open itself. It will open only when we call $( ‘#updateDialog’ ).dialog( ‘open’ ).

On line 3, buttons object id defined. It tells the dialog method that how many buttons will be displayed and what functionality will it perform.

On line 4, Update button’s function is defined. Note that this is not complete function. It will also contain an Ajax call for UPDATE operation.

On line 5, loading animation is displayed and on line 6, dialog box is closed.

On line 9, Cancel function is defined. It only contains a single statement which closes the dialog box.

The Update Ajax Call

The update Ajax call will go in Update function right below line 6 in above code snippet. After inserting the ajax call, Update function will 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
'Update': function() {
    $( '#ajaxLoadAni' ).fadeIn( 'slow' );
    $( this ).dialog( 'close' );
 
    $.ajax({
        url: updateHref,
        type: 'POST',
        data: $( '#updateDialog form' ).serialize(),
 
        success: function( response ) {
 
            $( '#msgDialog > p' ).html( response );
            $( '#msgDialog' ).dialog( 'option', 'title', 'Success' ).dialog( 'open' );
 
            $( '#ajaxLoadAni' ).fadeOut( 'slow' );
 
            //--- update row in table with new values ---
            var name = $( 'tr#' + updateId + ' td' )[ 1 ];
            var email = $( 'tr#' + updateId + ' td' )[ 2 ];
 
            $( name ).html( $( '#name' ).val() );
            $( email ).html( $( '#email' ).val() );
 
            //--- clear form ---
            $( '#updateDialog form input' ).val( '' );
 
        } //end success
 
    }); //end ajax()
},

The Ajax call starts from line 5. First property is url (line 6) which tells where this Ajax call will be sent.

On line 7, type in which this Ajax will go is defined. By default ajax() method uses GET. But here we need POST because we want to send form values via POST method.

On line 8, form inside updateDialog is selected and then jQuery built in method serialize() is called. This method takes all the values of form fields and return a string in this format: “name=Naveed&email=naveed@test.com&userId=2″. Note that it’s an & separated name value pairs just like query string.

On line 10, success method is defined which receives the response from server as a parameter.

On line 12, innerHTML of p element inside msgDialog is assigned response from server.

On line 13, msgDialog’s title is set to Success and then it’s opened showing the success message.

Update process is completed but the new values are not shown in table row containing the updated record. So on line 18 and 19, td containing name and td containing email is selected and assigned to variables. To select name, first tr having an id whose record is updated is selected. Then inside that tr, all td elements are selected. Suppose record having id 2 is updated. So all td elements inside tr#2 are selected. Here jQuery selector $( ‘tr#2 td’ ) returns an array of td elements inside tr#2. Note that index 0 contains id, index 1 contains name, and td at index 3 contains email. So for name td at index 1 is assigned to name variable. Similarly td at index 2 is assigned to email.

Now on line 21, td containing name is assigned updated name value via html() jQuery method. Similarly on line 22, the same thing is done for td containing email. Now the table row also contain those values which user entered in update form.

On line 25, all the input fields in update form are cleared out.

Review

In this part you learned how to perform Ajax based UPDATE operation using. You also learned about serialize method and how to send ajax call using POST method. Finally you learned how to update table rows using some jQuery advance selectors. In the next part you will learn how to perform CREATE operation.


comments powered by Disqus