Saturday, June 11, 2011

MVC3: Basic JQGrid Example

JQGrid seems to be one of the most fully featured grids in JQuery land.  Further to this, it seems like MS is putting some money into the development of features for this particular grid.  The following is a basic example of how to get JQGrid running with MVC3.

The scenario is as follows.  Lets say you have a small amount of data (say less than 500 rows) and you would like to display this to your user.  The easiest way to do this is to load all the data client side and then let jqgrid take care of the rest.  The client-side sorting and filtering will be really quick as it will not require another server call.  This will also reduce load on your server.

JQuery requires that the response format be very specific.  From the examples, it looks something like this.

total: 1,
page: 1,
records: 20,
rows: [ {id:1 cell:[data1 data2]} ... ]

You can customize the names of the fields with the jsonreader property, but the concept is still the same.

With the row number being pretty low and no need for server side interaction (read save/update) we can load all the data directly into the grid via the model.  Here is some sample code to do that.

public class HomeController : Controller
    {
        public ActionResult Index()
        {
            var model = new IndexModel();
            model.Data = new JavaScriptSerializer().Serialize(CreateGridData(100,100));
            return View(model);
        }

        private dynamic CreateGridData(int count, int rows)
        {
            var totalPages = Math.Ceiling((double)count / rows);
            return new
            {
                total = Convert.ToInt32(totalPages),
                page = 1,
                records = count,
                rows = CreateGridItems(count)
            };
        }


        private dynamic CreateGridItems(int count)
        {
            var gridItems = Enumerable.Range(0, count).Select(x => new GridItem() { Name = "Name" + x, Number = "Number" + x }).ToArray();
            var results = new List<object>();
            foreach (var gridItem in gridItems)
            {
                results.Add(new
                {
                    id = gridItem.Name,
                    cell = new []{gridItem.Name,gridItem.Number}
                });
            }
            return results;
        }

    }


The model is quite simple:

public class IndexModel
    {
        public dynamic Data { get; set; }
    }

And the JS code (just a very basic grid, you will probably want more options than this)

$(document).ready(function () {
        $("#simpleGrid").jqGrid({
            datastr: '@Html.Raw(@Model.Data)',
            datatype: 'jsonstring',
            colNames: ['Name', 'Number'],
            colModel: [
                { name: 'id' },
                { name: 'Number' }
            ],
            rowNum:100,
            height: '100%'
        });

    });

The JavaScript serializer converts our object into proper JSON.  MVC3 has some built in XSS projection, and by default, will escape out the data.  You can get around this by using the @Html.Raw feature.  See MVC3 Xss. You now have a jqgrid with all the data loaded.  You can add paging/sorting/filtering that will all work client-side.