An early look at jQuery UI Grid in ASP.NET MVC - Data Model

More than a week ago The jQuery UI Team has announced that they are building a grid widget. Don't get me wrong, I'm a huge fan of jqGrid but when jQuery UI will have its own widget I will strongly consider switching. That's why I decided to test the widget through some basic samples while it's being developed.
I have downloaded current widget sources from jQuery UI grid branch at GitHub. The widget development takes place in three subfolders: grid-datamodel, grid-markup and grid-type - in this post I will look only into the first one.
Lets start by referencing some CSS and JavaScript:
<link href="@Url.Content("~/Content/site.css")" rel="stylesheet" type="text/css" />
<link href="@Url.Content("~/Content/themes/base/jquery-ui.css")" rel="stylesheet" type="text/css" />
<link href="@Url.Content("~/Content/grid-datamodel.css")" rel="stylesheet" type="text/css" />
...
<script src="@Url.Content("~/Scripts/jquery-1.4.4.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.tmpl.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/ui/jquery.ui.core.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/ui/jquery.ui.widget.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/datamodel/dataitem.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/datamodel/datasource.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/datamodel/extractor-datasource.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/datamodel/datastore.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/datamodel/grid.js")" type="text/javascript"></script>
Now we will add a table, which will be extended by the widget:
<table id="products">
<thead>
<tr>
<th data-field="ProductID">Product Id</th>
<th data-field="ProductName">Product Name</th>
<th data-field="Supplier">Supplier</th>
<th data-field="Category">Category</th>
<th data-field="QuantityPerUnit">Quantity Per Unit</th>
<th data-field="UnitPrice">Unit Price</th>
<th data-field="UnitsInStock">Units In Stock</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
Moving on to JavaScript we should define datasource for the widget. The widget can work with local datasource, but I will go for a remote one, because this is much more fun ;).
//extend dataitem with our new type
$.ui.dataitem.extend('product', {});

//create datasource for our new type
$.ui.datasource({
type: 'product',
source: function (request, response) {
$.getJSON('@Url.Action("Products", "Home")', request, response);
}
});
At the moment datasource accepts data as an array of objects, so this simple action will be enough for sending data to the client:
public JsonResult Products()
{
object[] products = (from product in _productsRepository.GetProducts()
select new
{
ProductID = product.ProductID,
ProductName = product.ProductName,
Supplier = product.Supplier.CompanyName,
Category = product.Category.CategoryName,
QuantityPerUnit = product.QuantityPerUnit,
UnitPrice = product.UnitPrice,
UnitsInStock = product.UnitsInStock
}).ToArray();

return Json(products, JsonRequestBehavior.AllowGet);
}
All what is left for use is to apply the widget on our table. While doing this, we must tell the widget how to map objects fields into cells. There are two ways of doing it. We can pass an array of fields names for columns like this:
$('#products').grid({
type: 'product',
columns: [ 'ProductID', 'ProductName', 'Supplier', 'Category', 'QuantityPerUnit', 'UnitPrice', 'UnitsInStock' ]
});
Or tell the widget to use a row template:
$('#products').grid({
type: 'product',
rowTemplate: $('#products-row-tmpl').html()
});
In second case, we have to create a row template with jQuery Templates plugin:
<script type="text/x-jquery-tmpl" id="products-row-tmpl">
<tr>
<td>${ProductID}</td>
<td>${ProductName}</td>
<td>${Supplier}</td>
<td>${Category}</td>
<td>${QuantityPerUnit}</td>
<td>${UnitPrice}</td>
<td>${UnitsInStock}</td>
</tr>
</script>
And this is all. The widget will pull the data from the server and render a nice grid for us:
You can download source code of this sample from my svn repository at CodePlex. I will continue to play around with this widget as the beginning is very promising.

14 comments:

Anonymous said...

Pretty sweet. Great summary.

It's crazy how easy development is becoming.

Bob Hansen said...

Nice to see that JQuery UI is putting a grid together. I will probably switch as well. It looks very simple to implement. It will be nice to have everything I use under one package.

Ian Robinson said...

This looks great, especially the integration with jQuery templates.

Having recently used Allan Jardine's DataTables plugin (http://www.datatables.net/), it will be interesting to see how the jQuery grid compares.

Anonymous said...

IMHO, If this does not come with edit/update functionality then it is a waste of time.

Tomasz Pęczek said...

Update/edit is a planned feature (and lot of others). I'm going to test them as soon as they appear.

Ramazan Mert Dönmez said...

greatttt

KrystelleDannaHoyt said...

Does googlebot index json generated tables?

Tomasz Pęczek said...

From my experience it looks like it doesn't (like most of javascript changes you do on your page). What I usually do is providing special version of page depending on User Agent.

whittet said...

JavaScript is not run by search engines (yet).

whittet said...

Please put out a live demo on jsfiddle.net that does not include unrelated server side dependencies, i.e. ASP.NET MVC 3. Thank you, Shane Whittet - ASP.NET MVC 3, Razor, jQuery

Tomasz Pęczek said...

This post is an early look on how to use it with ASP.NET MVC 3. Pure HTML + JavaScript samples are available directly in jQuery UI GitHub repository

Anonymous said...

I really like your post. Will continue reading your blog. :)

darkroastjava said...

Very nice, thank you! It looks like you can also use this with a table that has been prefilled on the server-side. This would answer KrystelleDannaHoyt's issue.

keratokonusz said...

cool, I'll use it (hopefully) on my site's admin page too.