Customizing WebGrid with jQuery UI Themes

I recently began working with ASP.NET MVC 3, and I have been very impressed with the changes and updates that have been made. Follow the link to read about the many changes – I won’t rehash all those here. Instead, I want to discuss one of the new Web Helpers that have been added to MVC – specifically the WebGrid Web Helper.

I was excited when I first started reading about WebGrid. Up to this point, I had used jqGrid for grid layouts within my website. This solution works really well, and I want to stress that there is nothing wrong with the solution. There is a great deal of flexibility within this jQuery library which can be seen in the many demos of its functionality. One particular aspect that I liked about jqGrid is that it could use the jQuery UI themes generated by ThemeRoller for its display. This would keep the grid looking consistent with the rest of the website and was great to get with little or no real extra work.

As I was saying, when I first heard about WebGrid, I liked the idea of moving away from jqGrid and using a “pure” ASP.NET solution. WebGrid played very nicely with my models and I could literally setup a new grid in a manner of a couple minutes. This was a definite improvement over jqGrid (which required a little bit more work). However, I was held back because jqGrid looked beautiful with the jQuery UI themes. Quite frankly, WebGrid was pretty ugly out of the box. So, I decided to see if I could figure out how to make WebGrid also use the jQuery UI themes.

I first started by looking at jQuery UI’s Grid Static Test. My reasoning for this is that I wanted to see what classes jQuery’s grid component used to set its look and feel. Using Google Chrome’s Developer Tools, I quickly was able to pull out the various classes (which I’ll introduce in a moment). Let me pause here to introduce my WebGrid that I am using on the website I am creating. The following code is part of my Index.cshtml view. Note that I am using the new Razor view engine.

@model List
@{
    ViewBag.Title = "List of People";
}
@{
    var grid = new WebGrid(source: Model,
        defaultSort: "PersonID",
        rowsPerPage: 3);
}
<h2>List of People</h2>
<div class="webgrid-wrapper">
<div class="webgrid-title">List of People</div>
<div id="grid">@grid.GetHtml(
tableStyle: "webgrid",
headerStyle: "webgrid-header",
footerStyle: "webgrid-footer",
alternatingRowStyle: "webgrid-alternating-rows",
columns: grid.Columns(
grid.Column("PersonID", "ID"),
grid.Column("PersonName", "Person Name"),
grid.Column(format: (item) => Html.ActionLink("Edit", "Edit", new { id = item.PersonID })),
grid.Column(format: (item) => Html.ActionLink("Delete", "Delete", new { id = item.PersonID }))
)
)</div>
</div>

In this example, I am displaying a list of individuals, their ID, name, and whether they should be edited or deleted from the database. One thing you should note is the various style fields such as tableStyle, headerStyle, footerStyle, and alternatingRowStyle. Each one is followed by a class name that I gave to match the style. Being able to set individual styles on various elements within the WebGrid was very convenient as you’ll see in a moment.

You’ll also notice in the previous code snippet that I have surrounded my WebGrid with both a webgrid-wrapper and a webgrid-title. I had to do this because the Grid Static Test used a similar structure and I needed to do the same in order to get WebGrid to conform to the jQuery UI theme.

Let’s take a look at those styles in my CSS. (I included all the classes here so you could see what styles you had control over. I left a few empty for my particular case.)

.webgrid
{
    width: 100%;
    border: 0px;
    border-collapse: collapse;
}

.webgrid a
{
    text-decoration: none;
    color: #000;
}

.webgrid-wrapper
{
    width: 50%;
}

.webgrid-title
{
}

.webgrid-header
{
}

.webgrid-footer
{
    width: 500%;
}

The CSS is fairly straightforward. A couple things that I added to help with styling:

  • I collapsed the border and set it to 0. This keeps the individual cells from being too far apart. This is particularly helpful if your theme uses background colors in your cells. White grid lines don’t look very pretty.
  • I set the webgrid-wrapper class to 50%. This denotes the size of the grid on your page. Adjust as you feel necessary.
  • You’ll notice that webgrid-footer is 500%. This is a bit of a hack (and something I’m not happy about – I’m open to suggestions). This basically ensures that the bottom footer (which is used for pagination) stretches the length of the table. If this value is not set, the pager only stretches across one cell. You may need to adjust depending on the width of your table, etc.
  • As with the webgrid-footer width, you may also need to play around with font-size within webgrid. This will depend on your taste and preferences.

These two pieces of code prepare the WebGrid for its final transformation. Once this is setup, I use a bit of jQuery (whose library is nicely included with ASP.NET MVC) to bring it all together. Let’s take a look at the jQuery code.

//
// Style various parts to match the jQuery UI theme.
//
function jQueryUIStyling() {
    $('input:button, input:submit').button();

    // Style tables.
    $('.webgrid-wrapper').addClass('ui-grid ui-widget ui-widget-content ui-corner-all');
    $('.webgrid-title').addClass('ui-grid-header ui-widget-header ui-corner-top');
    jQueryTableStyling();
}

//
// Style tables using jQuery UI theme. This function is
// split out separately so that it can be part of the AJAX
// callback of the WebGrid WebHelper in ASP.NET MVC.
//
function jQueryTableStyling() {
    $('.webgrid').addClass('ui-grid-content ui-widget-content');
    $('.webgrid-header').addClass('ui-state-default');
    $('.webgrid-footer').addClass('ui-grid-footer ui-widget-header ui-corner-bottom ui-helper-clearfix');
}

This tableStyling() function (and you’ll see why I made this a function in a moment) is called by jQuery’s ready function upon page load. The basic purpose of this code is to set the varoius jQuery UI classes onto the WebGrid that are needed to complete the look and feel.

Now that this is all together, let’s look at the final product.

jqGrid Styled Table

At this point, you could stop and everything would work. However, I wanted to use AJAX to update the grid (for example, when paging). Fortunately this is very easy to do. Here is the updated code in my Index.cshtml file:

@model List
@{
    ViewBag.Title = "List of People";
}
@{
    var grid = new WebGrid(source: Model,
        ajaxUpdateContainerId: "grid",
        ajaxUpdateCallback: "jQueryTableStyling",
        defaultSort: "PersonID",
        rowsPerPage: 3);
}
<h2>List of People</h2>
<div class="webgrid-wrapper">
<div class="webgrid-title">List of People</div>
<div id="grid">@grid.GetHtml(
 tableStyle: "webgrid",
 headerStyle: "webgrid-header",
 footerStyle: "webgrid-footer",
 alternatingRowStyle: "webgrid-alternating-rows",
 columns: grid.Columns(
 grid.Column("PersonID", "ID"),
 grid.Column("PersonName", "Person Name"),
 grid.Column(format: (item) => Html.ActionLink("Edit", "Edit", new { id = item.PersonID })),
 grid.Column(format: (item) => Html.ActionLink("Delete", "Delete", new { id = item.PersonID }))
 )
 )</div>
</div>

You’ll notice the only change is the addition of two parameters to the WebGrid: ajaxUpdateContainerId and ajaxUpdateCallback. The first gets the ID of the HTML element in the WebGrid object in order to make partial-page updates. The second is the JavaScript function name that will be called after the previous property has been updated. You’ll notice that the callback function is tableStyling which is what needs to be called to style (or, in this case, re-style) the table. That’s really all there is to it! The WebGrid is now themed to look like the rest of your jQuery UI website.