Retrieve Views and Submit Forms with Ajax, JQuery and MVC
November 19, 2009
In my previous post I was using Ajax to retrieve Json data and update the DOM using JavaScript. While this is pretty useful you will often find your application quickly becomes JavaScript-heavy and difficult to maintain. I’m going to illustrate using JQuery and the MVC Ajax libraries to simplify this process.
Retrieving a view using Ajax
The first thing I’m going to do is to change the view I did in my last post. Instead of retrieving Json and manually updating the DOM using JavaScript I’m going to use partial views. This way the difficult work gets done on the server and is less error-prone and easier to maintain.
The first step is to split my view into a number of partial views and introduce placeholders for the details and comments that I load once a widget is selected.
<h2>Select a Widget</h2>
<div id="widgetsDiv">
<% Html.RenderPartial("Widgets", Model); %>
</div>
<br />
<h2>Details</h2>
<div id="widgetDetailsDiv"></div>
<h2>Comments</h2>
<div id="widgetCommentsDiv"></div>
I now want to be able to update the list of widgets via Ajax. Because I put the list into a partial view I simply need to add another action on my controller for retrieving this partial view.
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult GetWidgets()
{
return PartialView("Widgets", widgetService.GetWidgets());
}
The last step is to call this action with JQuery and update the DOM.
jQuery.get(rootPath + "Example/GetWidgets", function(response) {
$("#widgetsDiv").html(response);
});
I can load the details and comments in a similar fashion.
jQuery.get(rootPath + "Example/WidgetDetails?widgetId=" + selectedWidgetId, function(response) {
$("#widgetDetailsDiv").html(response);
});
jQuery.get(rootPath + "Example/WidgetComments?widgetId=" + selectedWidgetId, function(response) {
$("#widgetCommentsDiv").html(response);
});
Which is really very simple. Now let’s allow the user to add widgets.
Form submission using Ajax
To allow adding widgets I created a simple form to handle the data entry. The only tricky bit is that I want to submit this form using Ajax. I’m going to use the built-in MVC Ajax libraries to submit the form.
<% using (Ajax.BeginForm("Add", "Example", new AjaxOptions { HttpMethod = FormMethod.Post.ToString(), OnComplete = "widgetAdded" } )) { %>
<label>Name:</label>
<input type="text" id="Name" name="Name" />
<label>Attribute:</label>
<input type="text" id="Attribute" name="Attribute" />
<input type="text" id="Value" name="Value" />
<label>Comment:</label>
<input type="text" id="Comment" name="Comment" />
<input type="submit" value="Add" />
<% } %>
It’s possible to do this with JQuery but I find it much easier with the MVC Ajax libraries. Now we simply need to refresh the list of widgets in the OnComplete method (using the routing I showed earlier) and we’re done.
I have attached the code here. Happy coding.
I would still prefer the pure jquery way of ajax-posting a form using form.serialize() and $.post(). Because:
1. You can then separate the view logic in a separate .js file and use the html for presentation only.
2. More control over the submission. eg. you can hook to the submit event of the form via jquery, more easily select the target action programatically (on the client side)
I guess it is really a matter of preference.
In regards to #1 I tend to agree with you, however I still prefer this approach because I don't need to write any of my own JavaScript. Less code = easier to maintain. But again, both approaches are useful. I just don't know how easy it would be to make the site work if the client doesn't have JavaScript enabled in the browser – perhaps a discussion for a future post.
In terms of #2 – the MVC Ajax libraries do allow you to hook to 4 different events – OnBegin, OnComplete, OnSuccess and OnFailure. But again, I think this is more a case of personal preference.