Using the Infragistics jQuery Tree

Jordan Tsankov / Monday, November 28, 2011

Should you ever have the need to represent data with a “parent – children” relationship – we at Infragistics have just the right tool for you. The Infragistics jQuery Tree that comes with NetAdvantage for jQuery is a marvelous implementation of the tree-like structure we’re so used to. From text editors to operating systems to grocery lists, you have probably seen your fair share of expandable nodes and bulleted paragraphs, yet you most likely have not seen so much functionality at your fingertips.

tree_overview

The image to the left is an example of what a tree built using this control may look like. The expected node structure is there but you may also notice that there are also checkboxes next to each item. Yes, you can select a number of nodes instead of just one ! And the best part is that the IG Tree comes with a multitude of events which give you a pretty solid grip on the end result you’re after.

As usual for the NetAdvantage for jQuery components, this one can be used equally well in a pure HTML setup, a standard ASP.NET web application or a MVC project.

Now let’s get on with it !

 

 

 

Preparation

The first thing you need to do is, of course, supply yourself with the required JavaScript and CSS files. If you do not own a copy of NetAdvantage for jQuery already, you can get a trial version here. The picture below illustrates which files are required in order to make this control work.

needed_files

The files in the Scripts folder you get from the folder where you have your Infragistics products installed. Navigate to it, then go to jQuery/. The ig.ui.min.js file is in the js/combined/min folder and the other three scripts you can get off the demos/scripts folder ( provided you have the product samples installed, and I suggest that you do install them ).

All the styles needed can be found in the jQuery/themes folder. Just copy everything in there into your Styles folder inside your project. Bear in mind that this folder will probably be called “Content” if you’re working with a MVC project.

When the abovementioned files have been made available to your project, you are done with the initial preparation and are now ready to do some coding ! Just a quick reminder before that, though – if you’re working with a MVC project, you may add the IG ASP.NET MVC Helper to your project. You do that by adding a reference to the Infragistics.Web.Mvc DLL located in the jQuery/MVC folder – just choose the appropriate version and hit Okay.

Setting Up a Tree

Linking to the files you just added to your project is what you should do in the beginning – you do it like this:

ASP.NET Web Application

   1: <link href="Styles/min/ig/jquery.ui.custom.min.css" rel="stylesheet" type="text/css" />
   2: <link href="Styles/base/ig.ui.min.css" rel="stylesheet" type="text/css" />
   3:  
   4: <script src="Scripts/jquery-1.4.4.min.js" type="text/javascript"></script>
   5: <script src="Scripts/jquery-ui.min.js" type="text/javascript"></script>
   6: <script src="Scripts/ig.ui.min.js" type="text/javascript"></script>

Add the lines above into the head tag inside your Site.Master file.

In MVC, you add these lines to the head tag in the _Layout.cshtml file.

ASP.NET MVC

   1: <link href="@Url.Content("~/Content/min/ig/jquery.ui.custom.min.css")" rel="stylesheet" type="text/css" />
   2: <link href="@Url.Content("~/Content/base/ig.ui.min.css")" rel="stylesheet" type="text/css" />
   3:  
   4: <script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
   5: <script src="@Url.Content("~/Scripts/jquery-ui.min.js")" type="text/javascript"></script>
   6: <script src="@Url.Content("~/Scripts/ig.ui.min.js")" type="text/javascript"></script>

When the references have been added, you can create an igTree and fiddle with its options. Adding the component takes absolutely no effort – here’s how to do it through client-side JavaScript:

ASP.NET Web Application

   1: <div id="empty_div"></div>
   2:  
   3: <script type="text/javascript">
   4:        $(document).ready(function () {
   5:        var items = [
   6:             {
   7:                 "Parent": "Item 1 JSON",
   8:                 "Child": [
   9:                     { "Parent": "Sub 1 JSON 1" },
  10:                     { "Parent": "Sub 1 JSON 2" },
  11:                     { "Parent": "Sub 1 JSON 3" }
  12:                     ]
  13:             },
  14:             {
  15:                 "Parent": "Item 2 JSON",
  16:                 "Child": [
  17:                     { "Parent": "Sub 2 JSON 1" },
  18:                     { "Parent": "Sub 2 JSON 2" },
  19:                     { "Parent": "Sub 2 JSON 3" }
  20:                     ]
  21:             }];
  22:     empty_div.igTree({
  23:             dataSourceType: "json",
  24:             dataSource: items,
  25:             bindings: {
  26:                     textKey: "Parent",
  27:                     childDataProperty: "Child"
  28:             }});
  29: });
  30: </script>

What we’re doing here is first we define an empty element in our HTML mark-up which will serve as foundation for the igTree. Next, in JavaScript we have a JSON formatted array which holds our hierarchically-ordered data. Finally we go on to creating the grid itself. We specify the underlying data type of our data source, as well as link the dataSource property to our JSON variable. Finally we apply data bindings – by using them, we can explicitly map different properties of our data source to certain properties of the tree nodes. Following this link will give you more insight on the various binding options you can set.

Bear in mind that you can also directly bind the component to an existing <ul> list. You can see an example in the attached example solution.

Setting up an igTree widget in a MVC environment is no different than setting it up in JavaScript except the fact you have the added benefit of having IntelliSense available. The only different steps you need to take is to organize your data source accordingly. Here is a really basic example:

Child.cs

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Web;
   5:  
   6: namespace MVC3.Models
   7: {
   8:     public class Child
   9:     {
  10:         public string ChildName { get; set; }
  11:         private IEnumerable<Child> children;
  12:  
  13:         public IQueryable<Child> Children { get { return children.AsQueryable(); } }
  14:  
  15:         public Child(string name)
  16:         {
  17:             ChildName = name;
  18:             children = new List<Child>();
  19:         }
  20:  
  21:         public Child(string name, List<Child> children)
  22:         {
  23:             this.children = (children == null) ? new List<Child>() : children;
  24:             ChildName = name;
  25:         }
  26:     }
  27: }

Parent.cs

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Web;
   5: using System.Web.Mvc;
   6:  
   7: namespace MVC3.Models
   8: {
   9:     public class Parent
  10:     {
  11:         private string name;
  12:         private IEnumerable<Child> children;
  13:  
  14:         public string Name { get { return name; } set { name = value; } }
  15:         public IQueryable<Child> Children { get { return children.AsQueryable(); } }
  16:  
  17:         public Parent(string name, List<Child> children)
  18:         {
  19:             this.children = (children == null) ? new List<Child>() : children;
  20:             Name = name;
  21:         }
  22:         public Parent(string name)
  23:         {
  24:             Name = name;
  25:         }
  26:     }
  27: }

Create the files shown above in your Models folder. Parent represents a topmost node in the hierarchy, whereas Child represents just what the name suggests – a child node sitting on whichever level of the tree.

Next, we build a sample list which we’ll return with our view. We’ll do this in a controller so open up the Controllers folder in your solution and  create a new controller:

HomeController.cs

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Web;
   5: using System.Web.Mvc;
   6: using MVC3.Models;
   7:  
   8: namespace MVC3.Controllers
   9: {
  10:     public class HomeController : Controller
  11:     {
  12:         public ActionResult Index()
  13:         {
  14:             
  15:             return View(GetList());
  16:         }
  17:  
  18:         public IQueryable<Parent> GetList()
  19:         {
  20:             return new List<Parent>()
  21:             {
  22:                 new Parent("Item 1", 
  23:                     new List<Child> {
  24:                         new Child("Sub 1"),
  25:                         new Child("Sub 2"),
  26:                         new Child("Sub 3")
  27:                     }),
  28:                 new Parent("Item 2",
  29:                     new List<Child> {
  30:                         new Child("Sub 1", new List<Child> {
  31:                             new Child("Deeper down"),
  32:                             new Child("A sibling"),
  33:                             new Child("Another sibling")
  34:                         }),
  35:                         new Child("Sub 2"),
  36:                         new Child("Sub 3")
  37:                     })
  38:             }.AsQueryable();
  39:         }
  40:     }
  41: }

Once that is done, we go to the corresponding view and initialize the widget. With the ASP.NET MVC Helper, this is like a walk in the park:

Razor syntax

   1: @(Html.Infragistics().Tree().
   2:             Bindings(b1 => { b1.
   3:                 TextKey("Name").
   4:                 ChildDataProperty("Children").
   5:                 Bindings(b2 =>
   6:                 {
   7:                     b2.
   8:                         TextKey("ChildName").
   9:                         ChildDataProperty("Children").
  10:                         Bindings(b3 =>
  11:                         {
  12:                             b3.TextKey("ChildName");
  13:                         });
  14:                 });
  15:             }).
  16:         DataSource(Model).
  17:         DataBind().
  18:         Render()  
  19: )

A few points of interest to follow – firstly , you do not need a base html tag to build the igTree component on – the helper will do that automatically for you and name it’s ID attribute accordingly: the first tree you create will have an ID of “Tree1”, the second – “Tree2” and so on.

Second, do not forget to call .Render() when you’re done with the options.

Finally, and this is really important – you will need to apply a layer of bindings for each hierarchy level in your tree. You need to do this manually. In the code snippet above, you can see three layers of bindings applied.

So there you have it, this is a very simplistic setup of the igTree widget.

“I want more !”

Or the “Options” section. Here we’ll do a brief rundown on what makes this tree special. Configuring the options is extremely easy – we shall see how to make it so the tree comes with checkboxes and limit the amount of currently expanded nodes to one. To view all other available options, refer to the documentation.

For some additional samples related to options, click here and here.

ASP.NET Web Application

   1: $("#treeTarget").igTree({
   2:                     checkboxMode: "triState", 
   3:                     singleBranchExpand: true
   4:                 });

Razor Syntax

   1: @(Html.Infragistics().Tree().
   2:             CheckboxMode(CheckboxMode.TriState).
   3:             SingleBranchExpand(true).
   4:             Render()
   5: )

“I still want more !”

Here we’ll talk about events. You can click here and view some official samples related to manipulating the events of an igTree.

Here’s a basic example of alerting the text of the node that was just selected :

   1: $("#treeTarget").bind("igtreeselectionchanged", function(evt, ui) {
   2:                  alert(ui.newNodes[0].data.Text);
   3: });

Bear in mind that if you have applied bindings which change the textKey property, you will be wanting that same property name from the event. The same logic scales down to the valueKey property.

 

For instance, if you have done this:

   1: bindings: {
   2:           textKey: "Parent"
   3: }

Then you will need to access ui.newNode[0].data.Parent, like this:

   1: $("#treeTarget").bind("igtreeselectionchanged", function(evt, ui) {
   2:                  alert(ui.newNodes[0].data.Parent);
   3: });

A more thorough example of working with events can be seen in the attached sample solution.

Wrapping Up

This post was aimed at helping you with any igTree-related endeavors. If you managed to follow everything up to this point, you should have an idea of what you need to add to your project in order to make the widget work, as well as various tweaks that alter your users’ experience with this component.

 

If you do not have the NetAdvantage for jQuery product installed, get a trial  version from here.

IGTree.zip