Edit in place / inline editing with jQuery, jTemplates and ASP.NET

Download source

In this post I talked about how to use the jTemplates plugin for jQuery. Using my final example in the post I thought it would be cool to try and add some ‘edit in place’ functionality to the table.

For this to work I’ve created a Data Access Layer using Linq to XML. My web service then uses this DAL to save and retrieve my data.

First of all there a few changes to make to my jTemplate in the foreach loop:

{#foreach $T as Customer}
    <tr id="{ $T.Customer.ID }" bgcolor="{#cycle values=['#AFCFFF','#C0FFBF']}">
        <td id="Forename">
            { $T.Customer.Forename }
        </td>
        <td id="Surname">
            { $T.Customer.Surname }
        </td>
        <td id="DOB">
            { $T.Customer.DOB }
        </td>
        <td id="Location">
            { $T.Customer.Location }
        </td>
    </tr>
{#/for} 

For each TR tag I am setting the id attribute to the Customer ID, I can then use this later when updating to make sure I update the correct customer record. Also for each TD tag I’m setting the id attribute to the name of the field to make sure I update the correct field.

As my template renders a simple HTML table I need to create a handler for either click or double click on each TD tag to allow them to be edited, I’m attaching it to double click.  This function sits within a Init function which is called after the jTemplate is loaded, otherwise the event handler won’t be hooked up.

$("td").dblclick(function() {
    if (!$(this).hasClass("edit")) {
        var value = jQuery.trim($(this).html());
        $(this).html("<input id=\"txtEdit\" type=\"text\" class=\"textbox\" value=\"" + value + "\" onblur=\"SaveValue(this, '" + value + "')\" onfocus=\"PutCursorAtEnd(this)\" />");
        $(this).addClass("edit");
        $("#txtEdit").focus();
    }
});

In this function I first check if the TD tag contains the ‘edit’ class (I add this later to know the TD is in ‘edit mode’). Next I get the value from the cell, then replace the HTML of the cell with an textbox containing the value that was in the cell.  I also assign handlers to the onblur and onfocus events of the textbox which I’ll explain in a moment.  Next I add the ‘edit’ class to the TD tag, which as mentioned it checked at the start of the function. Without this clicking on the cell a second time would replace the HTML again.  Lastly I focus on the textbox.

On the onfocus event I’m using a function called PutCursorAtEnd which uses the PutCursorAtEnd jQuery plugin to simply place the cursor at the end of the text. My function looks like this:

function PutCursorAtEnd(obj) {
    if (obj.value == obj.defaultValue) {
        $(obj).putCursorAtEnd(obj.length);
    }
}

The onblur event calls a method called SaveValue passing itself (the textbox) and the old value:


function SaveValue(obj, oldValue) {
    var value = $(obj).val();
    $(obj).parent().removeClass("edit");
    if (value != oldValue) {
        var property = $(obj).parent().attr("id");
        var id = $(obj).parent().parent().attr("id");

        $(obj).parent().html("<img id='imgSaving" + id + "' src='ajax-loader.gif' alt='Saving...' />");

        $.ajax({
            type: "POST",
            url: "MyService.asmx/SaveCustomer",
            data: "{ customerID: " + id + ", args:{'" + property + "':'" + value + "'}}",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: SaveCustomer_Success,
            error: Error
        });
    }
    else {
        $(obj).parent().html(oldValue);
    }
}

In this function I first get the new value from the textbox then remove the ‘edit’ class so it’s no longer in edit mode.  I then check if the value has changed, if not then the HTML of the TD is replaced with the old value using the Parent method on the textbox.  If the value has changed then it needs to be updated; first I get the property name from the jTemplate which I put in the TD’s id attribute, then I get the Customer ID which is in the id attribute of the TR tag. Next I replace the contents of the cell with an animated loading image which will be displayed when updating (you can see I’m using the Customer ID to form the id attribute  here so that if multiple fields are updated I can keep track of each loading image, I also use this later to find the correct cell after updating). Finally I call the SaveCustomer method on my web service to perform the update.

The SaveCustomer method looks like this:

 

public object SaveCustomer(int customerID, Dictionary<string, object> args)
{
    DAL.SaveCustomer(customerID, args.First().Key, args.First().Value.ToString());

    return new
    {
        ID = customerID,
        NewValue = args.First().Value.ToString()
    };
}

Here I am passing back the Customer ID and the new value. In the success callback for my ajax call I then use the ID to find the correct loading image, and replace it’s parent cell’s content with the new updated value:

function SaveCustomer_Success(data, status) {
    $("#imgSaving" + data.d.ID).parent().html(data.d.NewValue);
}

Now the ‘edit in place’ functionlity should be working and look something like this after double clicking a cell:

editinplace1

Just to make things a little prettier I’ve added the following CSS:

 

.hover
{
    background-color: #F8FFDB;
}

#txtEdit
{
  border: none;
  background-color: transparent;
  width: 100%;
}

Then the following jQuery into the Init function:

 

$("td").mouseover(function() {
    $(this).addClass("hover");
});

$("td").mouseout(function() {
    $(this).removeClass("hover");
});

Now it appears as if you are editing the information directly in the cell and you get a nice hover effect:

editinplace2

Download source

Posted on by Joe in Ajax, ASP.NET, JavaScript, jQuery

One Response to Edit in place / inline editing with jQuery, jTemplates and ASP.NET

  1. hungry for jquery

    Hi, this is a nice article, but i need to edit the whole row at a time not single cell. I was trying to get this functionality for long time, any idea pointing me to the right direction is much appreciated. thanks in advance, once again nice article and keep posting

Add a Comment