Setting up Node Template in the jQuery igTree

Jordan Tsankov / Friday, December 2, 2011

Introduction

If you have always wondered how to make every igTree widget have an unique feel to it, then let me introduce you to templating in jQuery. Templating is a client-side way of interweaving  data with markup. What this means is, in essence, you produce a string which contains valid HTML markup ( or even expressions or function calls ! ) and embed  data fields in places where you want them to appear. Next up is a visual example to easily get the idea across:

   1: var simple_template_layout = "<label>${Name}: ${Value}</label>";

As you see in the snippet above, our template is technically HTML code with some non-HTML syntax  thrown in for good measure – the ${Name} and ${Value} bits. Those parts, when rendered by the template engine, will be replaced by the corresponding fields of the data object we used to render the template with. If this data object looked something like this:

   1: var data = { Name: "Age", Value: 33 };

then the code produced after the template has been processed should resemble something of these likes:

   1: <label>Age: 33</label>

I hope you obtained enough initial understanding on the subject, because we’ll now be applying it to the NetAdvantage for jQuery igTree component. If you’d like to read up more, visit the jQuery template API. Or maybe you’d like to see all the code at one place – in which case I suggest that you download this example solution.

Let’s get on with it !

What to do?

For starters, you need to get ahold of either jquery.tmpl.js or jquery.tmpl.min.js. Both files can be found on this GitHub page. With that out of the way, just drop the downloaded file in your Scripts/ folder of your project and add the appropriate link to the script on the page you intend to use it on.

Now you’re ready to use the node templating feature. But how , you may be wondering? You may have seen a property within the "bindings” option that’s called “nodeContentTemplate”. That property accepts a string which, the craftier ones amongst you may have already figured, is the same string as seen in the very first code snippet in this blog post. Yes, this is where you specify your template ! The data fields that get rendered into the template variables – ${Name} and ${Value} in our example, are taken right out of the current layer of bindings for the igTree. Let me show you what that means:

   1: var items = [
   2:             { Person: "Bob", Info: [
   3:                 { Name: "Favorite Color", Value: "Red" },
   4:                 { Name: "Age", Value: 19 },
   5:                 { Name: "Favorite Sport", Value: "Football" }
   6:             ]
   7: }];
   8:  
   9: var simple_template_layout = "<label id='${Name.replace(\" \", \"_\")}'>${Name}: ${Value}</label>";
  10:  
  11: simple_template.igTree({
  12:                 dataSourceType: "json",
  13:                 dataSource: items,
  14:                 singleBranchExpand: true,
  15:                 hotTracking: false,
  16:                 bindings: {
  17:                     textKey: "Person",
  18:                     valueKey: "Person",
  19:                     childDataProperty: "Info",
  20:                     bindings: {
  21:                         textKey: "Name",
  22:                         valueKey: "Value",
  23:                         nodeContentTemplate: simple_template_layout
  24:                     }
  25:                 }
  26:             });

Breaking down the code, step by step.

In lines 1 through 7, we define our data source, which is basically a JSON object.

Next up, in line 9, we have the jQuery template string.  You can see that I’ve set the <label> id to the value of the Name property of the JSON object ( which in this case is the Info object and I’ll explain why in a bit ), but with all spaces replaced with underscores.Within the <label> tag there are simply the Name and Value property displayed.

The next block of code is our igTree initialization. It’s a pretty straightforward setup, so just focus your attention to lines 21-23. These lines are within the second layer of bindings, which are applied to every “Info” child within our data source object. In this layer of binding, the current data object is the Info object, which does in fact contain properties called Name and Value – this means they can successfully be rendered by the template engine. Then on line 23 we specify a template string that will be used to render the node’s content, and how handy – we already have a template string prepared !

What to expect?

If you’re wondering what node templating helps you achieve, the following image is an example of the snippet above, as seen in action.

As you can see, this type of tree does a very good job of visually informing you what the actual value of a node is. Even though it may seem irrelevant, it will shift the attention from anticipating what your selection was and where to see it, to the process of making a selection. Also, this is just a very basic example of how to use node templating – directly displaying certain data properties. It’s not the only way to apply this option, though!

Here’s a snapshot of the same tree without a template, so you can compare:

Notice how on this tree, there is no visual identification of what you’re selecting – you know it will be either someone’s favorite sport , color or his age…but you’re left wondering what that is until you actually make a selection.

 

How to improve?

Still working within the context of a simple example of igTree node templating, let’s see how we can improve on the idea above. With visualization in mind, we may be hoping for something like this:

In terms of data conveying, this template style is even better than the one where values were represented as mere words. It is much more inviting to the typical user because we are more attracted to images. You know the saying – “A picture is worth a thousand words” !

Okay, so what did we do in order to get the nodes to this state? Let’s examine the following code snippet:

   1: adv_template.igTree({
   2:                 dataSourceType: "json",
   3:                 dataSource: items,
   4:                 singleBranchExpand: true,
   5:                 hotTracking: false,
   6:                 bindings: {
   7:                     textKey: "Person",
   8:                     childDataProperty: "Info",
   9:                     bindings: {
  10:                         textKey: "Name",
  11:                         valueKey: "Value",
  12:                         nodeContentTemplate:
  13:                         "{{if Name == 'Favorite Color'}}<label>${Name}</label>: <div class='favcolor' style='background-color: ${Value.replace(\" \", \"\")};'></div>" +
  14:                         "{{else Name == 'Age'}} ${Name}: ${Value}" +
  15:                         "{{else Name == 'Favorite Sport'}}<label>${Name}</label>: <img class='favsport' src='Content/icons/${Value}.png' alt='${Value}'></img>" +
  16:                         "{{/if}}"
  17:                     }
  18:                 }
  19:             });

This time in our template string, we’ve made use of the flow control statements supported by the templating engine. Based on the text of the Name property, we use the Value property in a different way. Line 13 takes the favorite color of the person node and renders a <div> element that uses that color for its background. Line 15 tries to find an image with the same name as the person’s favorite sport and then display that image. Aside of the code snippet above, we’d also need to make use of the following CSS rules:

   1: .favcolor, .favsport
   2: {
   3:     display: inline-block;
   4:     width: 20px;
   5:     height: 20px;
   6:     position: relative;
   7:     top: 4px;
   8:     left: 5px;
   9: }

Additionally, there’s one more alteration to the igTree that can further be done – you can see it in my sample solution.

Conclusion

This blog was aimed at telling you about the custom formatting you can apply to the nodes of an igTree widget , by setting up a node content template. A few examples were shown that outline some of the practical applications of a template.

Further reading on the topic of jQuery templating can be done here.

You can get my sample project from this link.

jQueryTreeNodeTemplate.zip