Previously, I blogged about how to update the WebGrid in MVC 3 asynchronously. This was when MVC 3 beta came out. Later, I received a comment which confirmed that in fact my example no longer worked!!. Hopefully, I can redeem myself with this post.
I took a slightly different approach in this example, using a partial view and reloading the grid with .ajax.
First, the ViewModel which is simple enough:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace AsyncWebGrid.Models
{
public class ContactViewModel
{
public IEnumerable <Contact > Contacts { get ; set ; }
}
}
The Contact class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace AsyncWebGrid.Models
{
public class Contact
{
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>
/// The id.
/// </value>
public int Id { get ; set ; }
/// <summary>
/// Gets or sets the first name.
/// </summary>
/// <value>
/// The first name.
/// </value>
public string FirstName { get ; set ; }
/// <summary>
/// Gets or sets the last name.
/// </summary>
/// <value>
/// The last name.
/// </value>
public string LastName { get ; set ; }
/// <summary>
/// Gets or sets the age.
/// </summary>
/// <value>
/// The age.
/// </value>
public int Age { get ; set ; }
}
}
The Controller has a couple different methods. The important one is ReloadGrid. This returns the partial view which actually has the WebGrid in it. The ContactRepository is new'd up in the constructor for simplicity, obviously we would want to inject this normally.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Helpers;
using System.Web.Mvc;
using AsyncWebGrid.Models;
using AsyncWebGrid.Repositories;
namespace AsyncWebGrid.Controllers
{
public class HomeController : Controller
{
private readonly IContactRepository _contactRepository;
public HomeController()
{
_contactRepository = new ContactRepository ();
}
/// <summary>
/// Indexes this instance.
/// </summary>
/// <returns></returns>
public ActionResult Index()
{
var viewModel = new ContactViewModel
{
Contacts = this ._contactRepository.GetContacts(),
};
return View(viewModel);
}
/// <summary>
/// Deletes the person.
/// </summary>
/// <param name="id">The id.</param>
/// <returns></returns>
[HttpPost ]
public ActionResult DeletePerson(int id)
{
this ._contactRepository.DeleteContact(id);
return null ;
}
/// <summary>
/// Reloads the grid.
/// </summary>
/// <returns></returns>
public ActionResult ReloadGrid()
{
return PartialView("_Contacts" , this ._contactRepository.GetContacts());
}
}
}
Finally the Views. First Index.cshtml
@model AsyncWebGrid.Models.ContactViewModel
@{
ViewBag.Title = "Index" ;
}
<h2> Index</h2>
<div id="grid">
@ Html.Partial("_Contacts" , Model.Contacts)
</div>
The PartialView _Contacts.cshtml, which is where everything happens along with the javascript function for reloading the grid:
@model IEnumerable <AsyncWebGrid.Models.Contact >
@{
var grid = new WebGrid (source: Model,
defaultSort: "FirstName" ,
ajaxUpdateContainerId: "grid" ,
rowsPerPage: 15);
}
@ grid.GetHtml(
tableStyle: "grid" ,
headerStyle: "head" ,
alternatingRowStyle: "alt" ,
columns: grid.Columns(
grid.Column(format: (item) => Ajax.ActionLink("Delete" , "DeletePerson" ,
new { id = item.Id },
new AjaxOptions { HttpMethod = "POST" , OnSuccess= "reloadGrid" })),
grid.Column("Id" ),
grid.Column("FirstName" ),
grid.Column("LastName" ),
grid.Column("Age" )
)
)
JS:
function reloadGrid() {
$.ajax(
{ type: "GET" ,
url: '/Home/ReloadGrid/' ,
data: "{}" ,
cache: false ,
dataType: "html" ,
success: function (data)
{ $( ).html(data); }
})
}
In my first attempts to correct this post one issue I kept encountering was that jquery.load would only reload the grid the first time it was called. Each time after that nothing would happen. I did some searching and came across this blog which helped me out with an alternative.