DotNetCurry Logo

Auto Collapsible Nested TreeView using jQuery

Posted by: Suprotim Agarwal , on 10/9/2015, in Category jQuery and ASP.NET
Views: 18233
Abstract: Build a Nested TreeView in jQuery Tree which can be nested to any level

A Tree is a nested list, which can be nested to any level. In this example, we will use jQuery to create a nested tree with the following features:

  • Auto collapse the tree with animation when it is loaded
  • Expand and collapse nodes with animation when they are clicked
  • Prevent Hyperlinks inside the list from expanding/collapsing nodes

 

Create a new file called ‘AutoCollapseTreeView.html’. Here’s a subset of the markup we will use. You can view the entire markup in the source code that accompanies this article (given at the end):

<ul id="Decor">
    <li class="level1">Home Decor
        <ul>
            <li class="level2">Bedroom
                <ul>
                    <li><a href="http://www.yourwebsiteurl.com">Bed Linen</a></li>
                    <li><a href="#">Curtains</a></li>
                </ul>
            </li>
            <li class="level2">Dining
                <ul>
                    <li><a href="#">Table Linens</a></li>
                    <li><a href="#">Dinner Ware</a></li>
                </ul>
            </li>        
     ...

The Tree we will be building will look like the one shown here:

basictree

This tree has no styling whatsoever, so bear with me for now as we you can find some styling applied in the source code, along with some other effects.

Let’s jump to the code directly:

$(function () {
    $('#Decor ul').hide(600);

    $('#Decor li').on('click', function (e) {
        e.stopPropagation();
        $(this).children('ul').slideToggle();
    });
});

The first line of code is as follows:

$('#Decor ul').hide(600);

The code hides all the nested ul’s of the tree with id=Decor, so that the tree appears in a collapsed state when it is loaded. I have specified the duration of the animation as 600 milliseconds. You can always go ahead and remove the duration. By default the value is 400ms.

Let’s jump to the next portion of the code:

$('#Decor li').on('click', function (e) {
    e.stopPropagation(); // prevent links from toggling the nodes
    $(this).children('ul').slideToggle();
});

Here we attach a click event on every li item of the list. Observe that I have used e.stopPropagation(). This is especially done to stop the event from propagating from the anchor element, within the li. So if the user clicks on a link inside the tree, the nodes won’t toggle and that’s what we want. To understand this better, try commenting out the e.stopPropagation() code, click the link and you will observe that the nodes collapse when the hyperlink is clicked. This is not the desired behavior and that’s why we have stopped the event from propagating.

 

If you already know the number of levels of the tree in advance (as in our case) you can gain a small performance by doing $('#Decor').on('click', '.level1, .level2, .level3', function (e) {..}. This code uses event delegation by attaching the click event to only the parent li’s but then that will require some additional changes in the code, so let’s avoid being over ambitious here as the benefit is barely negligible here.

The next task is to display only those elements that are directly below the li that was clicked. Remember that a tree can be nested to any level. So you need to specifically open only the direct child elements inside the li, rather than all li elements that can be nested inside a level.

$(this).children('ul').slideToggle();

Observe how I have used children(), which looks only at the direct children elements rather than all descendants. slideToggle toggles (displays/hides) the matched elements with a sliding motion.

Why did I use .children() and not .find() here?

Instead of using $(this).children('ul').slideToggle() you could have also written $(this).find('> ul').slideToggle(400);

..and the code would work just fine. However there’s an important distinction in the two approaches here. find() gets the descendants of each element in the current set of matched elements whereas children() gets the children of each element in the set of matched elements.

The structure of the tree is as follows:

s5-tree-structure

Let’s say you are on level1. Here ul’s are children of li. However ul, li (level2, level3 etc), anchors are all descendants of li (level1). If we use find(), it searches all nested levels to find a match; whereas when we use children(), it only searches the immediate level to find a match. Since we require only descendants to open when a level is clicked, we should use children() for better performance. Although the performance difference is not much, in jQuery, there are ‘n’ number of ways to do something. As a developer, we should be aware of when to use what.

Lastly, to open all hyperlinks inside the list, in a new window/tab, just use this piece of code

$('#Decor a').not('[href="#"]').attr('target', '_blank');

The not() method removes all anchor elements from the set of matched hyperlinks so that they do not open in a new window/tab when clicked on. If you do not have any anchors, safely remove the not('[href="#"]') from the above code.

Live Demo: http://www.jquerycookbook.com/demos/S5-MenusTreeViews/47-AutoCollapseTreeView.html

Further Reading: http://api.jquery.com/slideToggle/  & http://api.jquery.com/find/ & http://api.jquery.com/children/

It would be nice if our TreeView had some expand/collapse icons and an automated way to display them. Stay tuned for my next article!

Download the entire source code of this article (Github)

Was this article worth reading? Share it with fellow developers too. Thanks!
Share on Google+
Further Reading - Articles You May Like!
Author
Suprotim Agarwal, MCSD, MCAD, MCDBA, MCSE, is the founder of DotNetCurry, DNC Magazine for Developers, SQLServerCurry and DevCurry. He has also authored a couple of books 51 Recipes using jQuery with ASP.NET Controls and a new one recently at The Absolutely Awesome jQuery CookBook.

Suprotim has received the prestigious Microsoft MVP award for nine times in a row now. In a professional capacity, he is the CEO of A2Z Knowledge Visuals Pvt Ltd, a digital group that represents premium web sites and digital publications comprising of Professional web, windows, mobile and cloud developers, technical managers, and architects.

Get in touch with him on Twitter @suprotimagarwal, LinkedIn or befriend him on Facebook



Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!