Twitter












Updating Partial Views with Unobtrusive AJAX in MVC 3

This blog has been relocated to http://blachniet.com. See this post at it's new home: http://blachniet.com/2011/08/10/partial-views-with-unobtrusive-ajax/.



This is post is meant to be a more straightforward overview of my previous post. The previous post got a little long and turned into a walthrough. If you need a walkthrough of this, check out that post at http://geekswithblogs.net/blachniet/archive/2011/08/03/walkthrough-updating-partial-views-with-unobtrusive-ajax-in-mvc-3.aspx

So in my new exploration of web development, I found what I assume to be a fairly common need to have part of a view/page update without the entire page updating. In my particular case, I wanted to have a page that listed items but also provided a form that allowed you to add an item. When an item was added, the list of items would be updated without having to regenerate the entire page.

This was eventually accomplised through the unobtrusive AJAX provided through the MVC and jQuery frameworks. Below you can see the Razor page that was used to solve my problem. In this page, we include the jquery.unobtrusive-ajax.min.js and create a form using the AjaxHelper. The Ajax form indicates that it needs to call the action function Index_AddItem, and then update the productList when the form is submitted.  At the bottom, in the productList div, we render the partial view, ProductListControl with the list of products. (ProductIndexViewModel contains a Product and an IEnumerable<Product>. See Rachel Appel's post for more information on ViewModels in MVC here: http://rachelappel.com/use-viewmodels-to-manage-data-amp-organize-code-in-asp.net-mvc-applications)

@* Views\Product\Index.cshtml *@
@model BoringStore.ViewModels.ProductIndexViewModel
@{
    ViewBag.Title = "Index";
}
<h2>Index</h2>
 
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
@using (Ajax.BeginForm("Index_AddItem"new AjaxOptions { UpdateTargetId = "productList" }))
{ 
    <div>
        @Html.LabelFor(model => model.NewProduct.Name)
        @Html.EditorFor(model => model.NewProduct.Name)
    </div>
    <div>
        @Html.LabelFor(model => model.NewProduct.Price)
        @Html.EditorFor(model => model.NewProduct.Price)
    </div>
    <div>
        <input type="submit" value="Add Product" />
    </div>
}
 
<div id='productList'>
    @{ Html.RenderPartial("ProductListControl", Model.Products); }
</div>

The ProductListControl.cshtml is a very simple partial view that displays all the product names and prices in a table:

@* Views\Product\ProductListControl.cshtml *@
@model IEnumerable<BoringStore.Models.Product>
<table>
    <!-- Render the table headers. -->
    <tr>
        <th>Name</th>
        <th>Price</th>
    </tr>
    <!-- Render the name and price of each product. -->
    @foreach (var item in Model)
    { 
        <tr>
            <td>@Html.DisplayFor(model => item.Name)</td>
            <td>@Html.DisplayFor(model => item.Price)</td>
        </tr>
    }
</table>

The controller has a GET action for the Index and a POST action for adding the item. The Index_AddItem function is what the Ajax form calls when it is submitted. This function returns a partial view, allowing us to avoid regenerating the entire page.

// Controllers\ProductController.cs
namespace BoringStore.Controllers
{
    public class ProductController : Controller
    {
        public ActionResult Index()
        {
            BoringStoreContext db = new BoringStoreContext();
            ProductIndexViewModel viewModel = new ProductIndexViewModel
            {
                NewProduct = new Product(),
                Products = db.Products
            };
            return View(viewModel);
        }
 
        public ActionResult Index_AddItem(ProductIndexViewModel viewModel)
        {
            BoringStoreContext db = new BoringStoreContext();
            db.Products.Add(viewModel.NewProduct);
            db.SaveChanges();
 
            return PartialView("ProductListControl", db.Products);
        }
    }
}

 

Summary:

The unobtrusive Ajax provided by MVC and jQuery looks like it may be useful in many areas in my future web development. I hope this post helps get some people to this solution faster than I got to it.



Feedback

# re: Updating Partial Views with Unobtrusive AJAX in MVC 3

Windows Azure Platform is one of those cloud computing programs that Windows developed. These kind of programs has been thriving because companies need this kind of programs to run it. It (cloud computing programs) are essentials to these companies because of its complex functions. - Joe Zanotti
1/7/2012 12:05 AM | Joe Zanotti

# re: Updating Partial Views with Unobtrusive AJAX in MVC 3

is this code working in mvc 2 ? I implement this in my site but when i am going to add new item means call Index_AddItem(ProductIndexViewModel viewModel) function i found that voewModel.Products is null. I am using List<Product> as Products bcoz i am using this as local storage .. And in Partial view i use Html.RenderPartial("ProductListControl", Model); 4/5/2012 6:03 PM | Adit

# re: Updating Partial Views with Unobtrusive AJAX in MVC 3

I've never used MVC 2, so I'm not sure if this would work there. When you create the ProductIndexViewModel do you intialize Products to a new List<Product>?

ProductIndexViewModel viewModel = new ProductIndexViewModel
{
NewProduct = new Product(),
Products = new List<Product>()
}; 4/6/2012 12:13 AM | Brian Lachniet

# re: Updating Partial Views with Unobtrusive AJAX in MVC 3

This is a very good example.

Thank you 4/24/2012 5:32 PM | Abhishek

# re: Updating Partial Views with Unobtrusive AJAX in MVC 3

Did you have any problems with double postbacks?
When I try your example code in MVC 4 I get two inserts in the database. 5/14/2012 1:55 AM | Morgan Sundqvist

# re: Updating Partial Views with Unobtrusive AJAX in MVC 3

Just wanted to say thanks for the example and sharing! 5/20/2012 11:59 AM | Richard

# re: Updating Partial Views with Unobtrusive AJAX in MVC 3

hi, what about update and delete? 7/15/2012 10:59 PM | Amin

# re: Updating Partial Views with Unobtrusive AJAX in MVC 3

Any chance of seeing the model? 8/15/2012 5:27 PM | Stuart Dobson

# re: Updating Partial Views with Unobtrusive AJAX in MVC 3

Ahh I see it's in the other article. 8/20/2012 11:02 AM | Stuart Dobson

# re: Updating Partial Views with Unobtrusive AJAX in MVC 3

Original ASP.NET unobtrusive ajax library has many (few years well known :-( ) bugs.

I wrote a small library 'Better Unobtrusive Ajax (not only for ASP.NET MVC)'. It can be found on https://github.com/dhlavaty/winf.unobtrusiveAjax.js It supports latest jQuery, has clean code and documentation. It is 100% compatible with Microsoft's original. If someone is interested or want to contribute, I will appreciate it. 2/4/2013 11:34 AM | Dusan Hlavaty

# re: Updating Partial Views with Unobtrusive AJAX in MVC 3

@Dusan, thanks for the contribution. I will definitely check out the library. 2/4/2013 11:56 AM | Brian

# re: Updating Partial Views with Unobtrusive AJAX in MVC 3

@using (Ajax.BeginForm("SearchResult", "Employee", new AjaxOptions
{
UpdateTargetId = "targetContainer",
HttpMethod = "POST",
InsertionMode = InsertionMode.Replace,
LoadingElementId = "progress"
})) 6/11/2013 10:18 AM | Mohammad Shahnawaz

# re: Updating Partial Views with Unobtrusive AJAX in MVC 3

What does your model look like? 4/13/2014 5:58 PM | Scott

# kjljlklk

lkmlkmlkmlkmlmlmlkmlmlmlkmlkmklmlkmlkmlkmlkmlkmlkmklmlkmlkmlkmlmlkmlkmlmlmlkmlkmlkmlkmlkmlkmlkmlkmlkmlkmlkmlkmlkmklmklklmkmlkmklmlkmlkmlkmlkmlkmlkkmllkmlklkmlklkmllkmlkmlk lkm lmk lkm lkm kl klm klm klm klmklmklkmklmklkmkmlkmlkmlkmlkmlkmlkmlkmlmlkmkllklkmlkmlkmlmlmpoikpoipoipi 4/17/2014 7:22 AM | lkmlkm

# re: Updating Partial Views with Unobtrusive AJAX in MVC 3

thanks!
I have a problem, when submit data, partial display new data but it keep old data too 11/24/2014 11:50 AM | tmtlab