Edit data in dialog form with JQuery and Asp.Net MVC

Web developers should always have in mind bandwidth optimization, when designing and developing applications. Even if, these days, most hosting services are offering unlimited bandwidth or you are deploying apps for intranet use only, the basic bandwidth optimization techniques like Efficiency, Compression and Omission should not be neglected. Every piece of data that you are sending or requesting from the server will slow down the application responsiveness and eventually dim the user experience.

Addressing Efficiency lets take a look at a simple comparison between a classic data edit flow and an Ajax driven one. In the classic model that MVC 3 scaffolding template creates, you have the Index page where a list of items are being displayed, in order to edit an item you’ll have to click on edit link, navigate to the dedicated Edit page, save the data and then return to index. Using Firebug I’ve trace the bandwidth usage and it goes like this:

Step Operation Bandwidth
1 Index page first load 140.7 KB
2 Click on edit link  
3 Edit page load 133.9 KB
4 Save data on the server 8 KB
5 Return to Index 140.7 KB
    423.3 K

 
The same operation performed over Ajax with a modal dialog pop-up instead of navigating to an Edit page:

Step Operation Bandwidth
1 Index page first load 140.7 KB
2 Click on edit link  
3 Edit dialog load 12.8 KB
4 Save data on the server 4 KB
5 Close dialog and update Index html 4.1 KB
    161.6 KB

 
These figures should change when applying Compression and Omission techniques, but the Ajax powered edit operation is more efficient nevertheless.

Lets see this implemented in my Post to Wall app:

In the controller expose a JsonResult action that will load the note from the database and returns it in a partial view:

TextNotesController.cs
[HttpGet]
public JsonResult EditNote(int id)
{
    string message = string.Empty;
    var note = new TxtNote();
    try
    {
        note = (from x in db.TxtNotes where x.Id == id select x).FirstOrDefault();
    }
    catch (Exception ex)
    {
        message = ex.Message;
    }

    return Json(new
    {
        Html = this.RenderPartialView("_NoteEdit", note),
        Message = message
    }, JsonRequestBehavior.AllowGet);
}

The _NoteEdit partial view makes the html for the dialog form except the buttons:

_NoteEdit.cshtml
@model MvcSp.Models.TxtNote
<div class="edit-box">
<textarea name="edit-content" id="edit-content" class="edit-textarea" rows="1" maxlength="4000" >@Model.Title</textarea><br />
</div>

All we need now is to write the JQuery code that will call EditNote over Ajax, get the html from the partial view and render it using the JQuery UI dialog modal form:

Index.cshtml
//edit note
$(".edit-note").live("click", function (e) {
    e.preventDefault();
    showLoader('Editing note');
    var noteId = $(this).attr("id").replace('edit-', '');
    var liId = '#bar-' + noteId;
    //load note from db and open in dialog
    $.ajax({
        type: "GET",
        url: "TextNotes/EditNote",
        data: { id: noteId },
        cache: false,
        dataType: "json",
        success: function (mynote) {
            $("#edit-popup").html(mynote.Html);
            $("#edit-popup").dialog({
                resizable: true,
                height: 210,
                width: 510,
                modal: true,
                buttons: {
                    Save: function () {
                        var boxval = $("#edit-content").val();
                        if (!boxval) {
                            showError("Can't save an empty note");
                            return;
                        }
                        $.ajax({
                            type: "POST",
                            url: "TextNotes/SaveNote",
                            data: { id: noteId, content: boxval },
                            cache: false,
                            dataType: "json",
                            success: function (data) {
                                if (data.Message) {
                                    showError(data.Message);
                                } else {
                                    $(liId).replaceWith(data.Html);
                                    $(liId).slideDown("slow");
                                    $("#flash").hide();
                                    $("#edit-popup").dialog("close");
                                }
                            }
                        }); //end save call
                    }, // end ok button
                    Cancel: function () {
                        $("#flash").hide();
                        $(this).dialog("close");
                    }
                },
                close: function () {
                    $("#flash").hide();
                } //end buttons
            }); //end modal edit
        }
    }); //end ajax call
}); //end edit

The dialog has two buttons, the Save button will call SaveNote on the server, if everything goes well, we’ll close the modal dialog and update the Index code by using JQuery .replaceWith(), the SaveNote method is another JsonResult action that returns just the html code that has changed:

TextNotesController.cs
[HttpPost]
[ValidateInput(false)]
public JsonResult SaveNote(int id, string content)
{
    string message = string.Empty;
    var note = new TxtNote();
    try
    {
        note = (from x in db.TxtNotes where x.Id == id select x).FirstOrDefault();
        note.Title = content;
        db.SaveChanges();
    }
    catch (Exception ex)
    {
        message = ex.Message;
    }

    return Json(new
    {
        Html = this.RenderPartialView("_NotesList", new List<TxtNote>() { note }),
        Message = message
    }, JsonRequestBehavior.AllowGet);
}

Before downloading the source code make sure you have VS.NET 2010 SP1, MVC 3 Tool Update and IIS 7.5 Express installed.

download source code files

Next post: Load on demand and Session Sync with JQuery and Asp.Net MVC
Previous post
: Async operations with jQuery Ajax and Asp.Net MVC

Tags: ,