I had a page where I wanted to create a collapsible navigation menu and wanted to learn about the dijit tree widget. I’m pretty happy with the result. Note that I removed the branches and icons associated with the tree to give it a cleaner look. Is this a misuse of the tree widget? Probably, but it does result in a pretty slick menu that is easily maintainable since the hierarchy is stored in a json data file.
The one problem I haven’t been able to overcome is the accessibility issue with the tree. Users that depend on Jaws have problem navigating the menu. To fix this I need to be able to control the tab index for the tree nodes while building the tree as well as tying the enter key with Dojo.connect to methods for collapsing a particular menu (today the arrow keys have to be used).
Find the code for the collapsible menu below. Enjoy!
- note this isn't a complete html file, only the code for adding the tree/menu. Don't for the include the dojo.require("dijit.Tree");
<div class="top-level">
<div dojoType="dojo.data.ItemFileReadStore" jsId="taskStore"
url="data/tasks.json"></div>
<!-- Dojo code for creating the Navigation tree. The values
found in the tree will be located in the data/task.jsjon. The
ForestStoreModel basically sets up the tree, and the dijit.Tree displays
it and associates it with the reidirect to the correct page -->
<div dojoType="dijit.tree.ForestStoreModel" jsId="taskModel"
store="taskStore" query="{type:'task'}"
rootId="taskRoot" rootLabel="task" childrenAttrs="children"></div>
<div dojoType="dijit.Tree" id="navigationTree" class="w3tree"
model="taskModel" openOnClick="true" showRoot="false">
<script type="dojo/method" event="onClick" args="item">
// if the type is subTask we want to redirect the page to the associated link
if(taskStore.getValue(item, "type") == "subTask")
{
window.location = taskStore.getValue(item, "link");
} else if ((taskStore.getValue(item,"type") == "task") && (taskStore.getValue(item,"link") != undefined))
{
console.debug("Found a link in a task"+taskStore.getValue(item,"link"));
window.location = taskStore.getValue(item, "link");
} else if (taskStore.getValue(item, "newWindow") != undefined)
{
console.debug("found a new Window value: "+taskStore.getValue(item, "newWindow"));
window.open(taskStore.getValue(item, "newWindow"));
}
</script>
</div>
</div>
</div>
tasks.json - data file for supplying your two tier menu
{ identifier: 'name',
label: 'name',
items: [
{ name:'MyHomePage', type:'task', link:'myHomePage.php' },
{ name:'IDs', type:'task',
children:
[
{_reference:'Show IDs'},
{_reference:'Create New ID'},
{_reference:'Delete IDs'},
{_reference:'Rename IDs'}
]
},
{ name:'Create New ID', type:'subTask', link:'createNewID.php'},
{ name:'Show IDs', type:'subTask', link:'showCurrentIDs.php'},
{ name:'Rename IDs', type:'subTask', link:'renameIDs.php'},
{ name:'Delete IDs', type:'subTask', link:'deleteIDs.php'}
{ name:'Passwords', type:'task',
children:
[
{_reference:'Change/Reset Passwords'}
]
},
{ name:'Change/Reset Passwords', type:'subTask', link:'changePasswords.php'}
]}
w3tree.css - the css file to include inorder to create the nice block menu
{
margin-left: 0px;
display: block;
}
/* The top level nodes shoudl have the darker blue background */
.w3tree .dijitTreeIsRoot
{
background: #99CCFF none repeat scroll 0% 0% !important;
}
/*
* This should match the top all dijit Tree Labels
* The > indicates a child selector. This will only match the top level
* dijtTreeLabels
*/
.w3tree > .dijitTreeIsRoot > .dijitTreeContainer > .dijitTreeIsRoot
> DIV > .dijitTreeContent >.dijitTreeLabel
{
padding-left:12px;
}
/* This should only match children Tree Labels */
.w3tree > .dijitTreeIsRoot > .dijitTreeContainer > .dijitTreeIsRoot
> .dijitTreeContainer > .dijitTreeNode > DIV > .dijitTreeContent > .dijitTreeLabel
{
padding-left:24px;
}
/* light blue for the child nodes*/
.w3tree .dijitTreeNode
{
background:#CCE5FF none repeat scroll 0% 0%;
margin-left: 0px;
}
/* This is included so that the background will be the correct color for the child nodes */
.w3tree .dijitTreeContainer
{
background:#CCE5FF none repeat scroll 0% 0%;
}
.w3tree .dijitTreeContent
{
border-top:1px solid #FFFFFF;
padding-bottom:5px;
padding-left:0px;
padding-top:5px;
min-height:5px;
min-width:5px;
margin: 0px;
}
/* for w3 we just want to clear out all of the tree branches
* so remove all icons
*/
.w3tree .dijitLeaf, .w3tree .dijitFolderClosed, .w3tree .dijitFolderOpened,
.w3tree .dijitTreeExpandoOpened, .w3tree .dijitTreeExpandoClosed,
.w3tree .dijitTreeExpandoLeaf
{
background: none;
display: none;
}
.w3tree .dijitTreeIcon, .w3tree .dijitTreeExpando
{
height: 0px;
width: 0px;
display: none;
}
.w3tree .topLevel
{
background: #99CCFF none repeat scroll 0% 0%;
padding-left: 12px;
}
.w3tree .secondLevel
{
background:#CCE5FF none repeat scroll 0% 0%;
padding-left: 24px;
}
.w3tree .thirdLevel
{
background:#CCE5FF none repeat scroll 0% 0%;
padding-left: 36px;
}
.w3tree .dijitTreeLabelFocused
{
background:#EEEEEE none repeat scroll 0% 0%;
color:#000000;
text-decoration:underline;
}
.w3tree .dijitTreeNodeEmphasized {
background:#EEEEEE none repeat scroll 0% 0%;
color:#000000;
text-decoration:underline;
}
