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;
}
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);
}
{
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.Titletextarea><br />
div>
<div class="edit-box">
<textarea name="edit-content" id="edit-content" class="edit-textarea" rows="1" maxlength="4000">@Model.Titletextarea><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
$(".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;
}
[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);
}
{
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.
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
Previous post: Async operations with jQuery Ajax and Asp.Net MVC
Extracted From -
http://www.stefanprodan.eu/2011/05/edit-data-in-dialog-form-with-jquery-and-asp-net-mvc/
No comments:
Post a Comment