jqGrid and ASP.NET MVC - TreeGrid

This is probably the last post about jqGrid. TreeGrid is quite cool and very easy to use feature. It supports both the Nested Set model and the Adjacency model. I'm going to show only the Adjacency model, but all the differences lies in data handling.
We will start with jqGrid initlization function:
<script type="text/javascript">
  $(document).ready(function() {
    $('#jqgTreeGrid').jqGrid({
      //enable TreeGrid
      treeGrid: true,
      //set TreeGrid model
      treeGridModel: 'adjacency',
      //set expand column
      ExpandColumn: 'Name',
      //url from wich data should be requested
      url: '/Home/FilesAdjacencyTreeGridData/',
      //type of data
      datatype: 'json',
      //url access method type
      mtype: 'POST',
      //columns names
      colNames: ['Path', 'Name', 'CreationTime', 'LastAccessTime', 'LastWriteTime'],
      //columns model
      colModel: [
                  { name: 'Path', index: 'Path', width: 1, hidden: true, key: true },
                  { name: 'Name', index: 'Name', align: 'left' },
                  { name: 'CreationTime', index: 'CreationTime', align: 'left' },
                  { name: 'LastAccessTime', index: 'LastAccessTime', align: 'left' },
                  { name: 'LastWriteTime', index: 'LastWriteTime', align: 'left' }
                ],
      //pager for grid
      pager: $('#jqgpTreeGrid'),
      //grid width
      width: 'auto',
      //grid height
      height: 'auto'
    });
  });
</script>

As you can see, the grid is configured to perform POST request. If the request is for child node, it will have three additional parameters: nodeid - the id of the currently expanded node, parentid - the parent id of the currently expanded node, n_level - the level value of the currently expanded node. We also need to add corresponding fields to every cell array in rows array. Here is a simple example:
/// <summary>
///
Provides json data for TreeGrid in adjacency mode
/// </summary>
/// <param name="postData">
POST parameters collection</param>
/// <returns></returns>

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult FilesAdjacencyTreeGridData(FormCollection postData)
{
  DirectoryInfo root = null;
  //Checking if we are expanding existing node
  if (postData.AllKeys.Contains("nodeid"))
    root = new DirectoryInfo(postData["nodeid"]);
  else
    root = new DirectoryInfo(@"D:\Books\");
  //Getting childrens
  var children = from child in root.GetFileSystemInfos()
                 orderby child is DirectoryInfo descending
                 select child;

  //Preparing result
  var filesData = new
  {
    page = 1,
    total = 1,
    records = children.Count(),
    rows = (from child in children
            select new
            {
              //table of cells values
              cell = new object[] {
                                    child.FullName,
                                    child.Name,
                                    child.CreationTime.ToString(),
                                    child.LastAccessTime.ToString(),
                                    child.LastWriteTime.ToString(),
                                    //Level - based on '\' count
                                    ((from backslash in child.FullName
                                    where backslash == '\\'
                                    select backslash).Count() - 2),
                                    //Parent id
                                    root.FullName == @"D:\Books\" ? null : root.FullName,
                                    //Is not expandable
                                    child is FileInfo,
                                    //Is expanded
                                    false
                                  }
            }
           ).ToArray()
  };

  //Returning json data
  return Json(filesData);
}

Screenshot of our sample at work (you can download source code here):

15 comments:

Anonymous said...

Hi, as you can see this is my first post here.
Hope to get some assistance from you if I will have some quesitons.
Thanks and good luck everyone! ;)

Anonymous said...

[... ] is one another interesting source of information on this subject[...]

Anonymous said...

This is fantastic! Can you show the json file? Thanks

Tomasz Pęczek said...

Entire sample can be downloaded from my codeplex repository (link in top menu) :)

Anonymous said...

Unbelievable, that' s exactly what I was seeking for! You just saved me alot of work

Anonymous said...

I typically do not submit in Blogs but your blog forced me to, awesome function.. gorgeous

Anonymous said...

Wow,so niceeee!! Thanks for sharing!

Anonymous said...

When I try to expand a node, jquery says 'invalid expression' and quotes the filesystem path corresponding to the node I clicked on. The quoted path does not include a trailing backslash... any idea what the problem might be?

Anonymous said...

you have cell = new string[] { ... }

But in the ..., they are not all strings, so the code doesn't work. What's up with that? I see that in your linked project code, new string[] is replaced with new object[]... could this have something to do with the errors I'm getting (see preceding post)?

Tomasz Pęczek said...

The correct version is new object[]. It's highly probable that I have fixed the bug in repository but forget to fix it here, my apologies. Please check my SVN repository at CodePlex for most recent version - https://tpeczek.svn.codeplex.com/svn/trunk/MVC/jqGridExample/

Bobby said...

I have a question regarding jqtreegrid. Can we use the sample shown here in mvc 1.0 and can we implement paging ???

Please let me know.

Thanks,
Rajesh

Tomasz Pęczek said...

There is no problem with using jqGrid TreeGrid in ASP.NET MVC 1.0. About the second part of your question - there is no 'out of the box' mechanism for paging in TreeGrid, but you can always try to create your own.

Tuomo Viljanmaa said...

Hi,

Tried this with jqGrid 4.1.2/jquery 1.5.2 and this example does not work anymore. Problem is that when the Path as a key column has spaces, it won't work anymore. I am sure there is a workaround.

Tomasz Pęczek said...

Hi,

Yes it doesn't work anymore (well it's 2009 code). I have "up to date" samples available here: http://tpeczek.codeplex.com/releases/view/61796.

Regards,
Tomasz Peczek

Anonymous said...

Thank you! Extremely helpful post, saved me a night of struggle!