15th Apr 2008

CSS jQuery Tree Menu

The other day I decided it was time to redesign (or rather clean up) my portfolio site. In its old incarnation, I used a tree menu component that I had found online for my samples page. Since I was in the redesigning mood, I thought I would try building my own tree menu from scratch.

I had been using jQuery for some time at work and decided I would use that in combination with CSS and the good old unordered list.

The tree menu loads files identified in the id attribute into a content div via ajax. It allows nesting of sub menus, toggling and closes all other menus on the same nesting level so that only one menu is open a time.

Here is the code:

The CSS File:

/* CSS Document */
#sideMenu h3{
margin-top:2px;
}

/*Position the menu absolutely so that it can appear above other content and does not impact the alignment of the content div. Optional*/
#sideMenu{
position:absolute;
top:0px;
left:0px;
font-weight:bold;
padding-left:5px;
}

/*Since we are not using actual links, mimic link behavior using the cursor style*/
#sideMenu li{
cursor:pointer;
list-style-image:url(../images/petal_li.png)
}

/*Make any node that actually displays content (has an id attribute) a different color*/
#sideMenu ul li[id]{
color:#00FF00;
}

/*General list styling, do with as you like*/

#sideMenu ul{
list-style-position:outside;
margin:15px;
padding:5px;
}

/*Set nested ULs (i.e. submenus) to display none so that they are closed on page load. To display the menu in an expanded state on page load, remove the display property*/

#sideMenu ul ul {
display:none;
margin:5px;
padding:2px 10px;
}

/*This is the div that content is loaded into. Style as you like*/

#sampleDisplay{
padding-top:5px;
width:100%;
}

The JavaScript File:

// JavaScript Document

/*Top level menus are identified by nesting the title in a DIV tag rather than assigning the event to the LI itself. This is because when the event was tied to the LI, clicking on any of the sub menus contained in the LI would trigger the event for the LI meaning that all you got was a menu that opened and closed rather than being able to trigger the loading function in the LIs children. */

$(“#sideMenu li div”).click(categoryClick)

/* Only elements that define a page path for content need to trigger the load function. Hence use the CSS attribute selector to find nodes that define an ID attribute and bind the load function to them. This has implications in that you cannot assign IDs to elements in the menu that you do not want to trigger the load event, but this could be easily modified if need be and I have found this implementation to be quite flexible in terms of styling and functionality*/

$(“#sideMenu li[id]”).click(loadSample)

/*When a top level category is clicked, show sub menus and hide all other menus on the same nesting level. /*
function categoryClick(){
$(this).siblings().toggle();
$(this).parent().siblings().children(‘ul’).hide();
}
/*Load a page into the specfied element (in this case a div with the ID sampleDisplay) as identified by the id attribute of the element that triggered the function*/

function loadSample(){
// alert(“Loading sample ” + this.id);
$(“#sampleDisplay”).load(this.id)
}

The HTML File:

<link href=”css/samples.css” rel=”stylesheet” type=”text/css” />
<div id=”sideMenu”>
<h3>Projects</h3>
<ul>
<li><div>Flash 8</div>
<ul>
<li><div>Media</div>
<ul>
<li id=”haverick_player.html”>Tabbed Video Player</li>
</ul>
</li>
<li><div>Components</div>
<ul>
<li id=”rte.html”>Rich Text Editor</li>
</ul>
</li>
<li><div>Widgets</div>
<ul>
<li id=”wwyd_widget.htm”>Advice Widget</li>
<li id=”burn_widget.htm”>Drawing Widget</li>
</ul>
</li>
</ul>
</li>
<li><div>Flash 9</div>
<ul>
<li id=”ad_rotator.html”>Ad Rotator</li>
</ul>
</li>
<li><div>Flex</div>
<ul>
<li id=”flex_video_player.htm”>Video Player</li>
<li id=”flickr.html”>Flickr Search</li>
</ul>
</li>
</ul>
</div>
<div id=”sampleDisplay”><div align=”center” style=”height:20px; margin:10%”>You can view samples of my work by clicking on the menus to the left. </div></div>
<script type=”text/javascript” src=”scripts/samples.js”></script>

And that’s pretty much it. I just put up the site redesign today so far this menu has been doing everything I expect of it. You can check out out on my portfolio site (see Blog Roll) under the samples section.

One Response to “CSS jQuery Tree Menu”

  1. indialike.com Says:

    This is really very good… Thanks