Thursday, January 21, 2010

GridView in ASP.NET MVC

One of the controls that it seems like everyone in the ASP.NET community is most concerned about losing when switching to ASP.NET MVC is the ubiquitous GridView control to render grid based data. Fear not ASP.NET community there is a GREAT alternative that, in my opinion, has a lot more to offer than the GridView in terms of user experience.

First off, if you are looking for an excellent jQuery book I HIGHLY recommend jQuery in Action

I have seen a few different solutions to display grid data in ASP.NET MVC. There is of course a for loop in the View that will render a table (or CSS based layout that mimics a table.) Telerik is putting together a commercially available GridView for MVC, which looks pretty nice but also has a licensing cost associated with it (if you are using it in a commercial application). http://demos.telerik.com/aspnet-mvc Both solutions work, but I don't like the downsides of either, which is where jqGrid comes in. jqGrid is an awesome, free, open source jQuery based grid control.

jqGrid

Application site: http://www.trirand.com/blog/
Demos: http://trirand.com/blog/jqgrid/jqgrid.html
jqGrid is a very fully featured grid that supports loading data client side via AJAX (JSON) calls, paging, sorting, row editing, etc., etc. etc. I believe it can do everything the Telerik control can do and comes with a fully free license for any application.

ASP.NET MVC jqGrid Demo Application

Since I have already used jqGrid in several applications and got everything working pretty smoothly I figured that it would be helpful to make a full demo application available to the community so it can be downloaded and then the pattern easily adapted into ASP.NET MVC applications.
image

JSON data source

I setup the grid to use a controller method that will return a JSON result formatted so that the jqGrid can use it. In the example the call to get the JSON data can be manipulated on the fly and the contents of the grid changed via an AJAX call by filtering the sales data by Date Range.

public ActionResult JsonSalesCollection(DateTime startDate, DateTime endDate,
string sidx, string sord, int page, int rows)
{
SalesLogic logicLayer = new SalesLogic();
List<Sale> context;
// If we aren't filtering by date, return this month's contributions
if (startDate == DateTime.MinValue || endDate == DateTime.MinValue)
context = logicLayer.GetSales();
else // Filter by specified date range
context = logicLayer.GetSalesByDateRange(startDate, endDate);
// Calculate page index, total pages, etc. for jqGrid to us for paging
int pageIndex = Convert.ToInt32(page) - 1;
int pageSize = rows;
int totalRecords = context.Count();
int totalPages = (int)Math.Ceiling((float)totalRecords / (float)pageSize);
// Order the results based on the order passed into the method
string orderBy = string.Format("{0} {1}", sidx, sord);
var sales = context.AsQueryable()
.OrderBy(orderBy) // Uses System.Linq.Dynamic library for sorting
.Skip(pageIndex * pageSize)
.Take(pageSize);
// Format the data for the jqGrid
var jsonData = new
{
total = totalPages,
page = page,
records = totalRecords,
rows = (
from s in sales
select new
{
i = s.Id,
cell = new string[] {
s.Id.ToString(),
s.Quantity.ToString(),
s.Product,
s.Customer,
s.Date.ToShortDateString(), 
s.Amount.ToString("c")
}
}).ToArray()
};
// Return the result in json
return Json(jsonData);
}


Javascript setup



The call to configure the jqGrid when the document ready event is fired is pretty straight forward.


jQuery("#list").jqGrid({
url: gridDataUrl + '?startDate=' + startDate.toJSONString() + '&endDate=' + endDate.toJSONString(),
datatype: "json",
mtype: 'GET',
colNames: ['Sale Id', 'Quantity', 'Product', 'Customer', 'Date', 'Amount'],
colModel: [
{ name: 'Id', index: 'Id', width: 50, align: 'left' },
{ name: 'Quantity', index: 'Quantity', width: 100, align: 'left' },
{ name: 'Product', index: 'Product', width: 100, align: 'left' },
{ name: 'Customer', index: 'Customer', width: 100, align: 'left' },
{ name: 'Date', index: 'Date', width: 100, align: 'left' },
{ name: 'Amount', index: 'Amount', width: 100, align: 'right'}],
rowNum: 20,
rowList: [10, 20, 30],
imgpath: gridimgpath,
height: 'auto',
width: '700',
pager: jQuery('#pager'),
sortname: 'Id',
viewrecords: true,
sortorder: "desc",
caption: "Sales"
});


Download



Here is the full application for you to download and play with.



I hope this is helpful in your MVC applications.


Aaron


http://www.churchofficeonline.com

4 comments:

Akhilesh Yadav said...

nce one please provide in vb.net

Anonymous said...

Nice. But in 'JsonSalesCollection' I have to change Json(jsonData) to Json(jsonData, @"application/json");

Anonymous said...

and mtype: 'POST'.

Anonymous said...

Very nice, Thx...