In Joomla if you have more than 1 menu defined you may have discovered that the Main Menu item does not remain active whilst in the sub-menu. This is not ideal from a usability perspective, since in my sites I always want to make use of signposts to show a visitor whereabouts in the site they are.
So how do you go about achieving this. Well a simple way I use is to make use of JavaScript to walk the DOM tree to see if the Sub Menu is being displayed and one of it’s items is current, and then if this is the case set the associated item in the Main Menu active by adding a new CSS class definition to it that can then be styled using CSS in the normal way. Of course if the visitor has JS disabled it degrades gracefully.
So how do we got about adding the new CSS class to the page after the page has already been loaded?
Basically the first thing to do is ensure that the sub menu is contained within a element identified by an ID – typically I use a DIV – lets call this and “submenu”. This needs to be done in the index.php for the Joomla template being used.
So once the page is loaded we need to find out if any of the list items in the “submenu” div are set as “current” (as defined by the CSS class definition) and set the corresponding main menu item to be active as well by adding some new CSS class definition to it that we can then control via CSS. This is where knowledge of the DOM comes in.
In the “submenu” div, the LI’s will be a child of the child of the DIV (by nature of the LI is contained in the UL contained in the DIV we defined in index.php. The UL and LI’s are added by the Joomla menu module for us).
So first we need to get the DOM object for the “submenu” DIV, and check to see of the ID is present (since it may not be there on all pages depending on how you’ve set it up in Joomla):
var subMenu = document.getElementById("submenu");
if (!subMenu) { skip = true; }
This Object will contain as objects all its children and their properties.
We then need to step through each of its grandchildren to see if one of them is set “current”. One might not be of course.
Once we find an current LI we then need to search through all the LI’s in the document to find the associated item in the Main Menu. Fortunately In Joomla each menu LI is given a unique ID – shown in the Menu control Panel – (X) in the example below – so we can work out which LI we’re after. So we step through every LI in the document until the correct Item class is found and then add another class name to it, which we means we can then reference it via CSS. Since this LI won’t be active it will only have 1 class assigned to it – the ID of the menu item.
if (!skip) {
for (var i=0; i < subMenu.childNodes.length; i++) {
if (subMenu.childNodes[i].id == ("current")) {
// Set the associated main menu item active
var lists = document.getElementsByTagName("li");
for (var i=0; i < lists.length; i++) {
if (lists[i].className == ("itemX")) {
lists[i].className = "menuactive " + lists[i].className;
}
}
}
}
}
The only thing left to do is wrap this up within a function statement:
function menuStyle() {
....
}
and call it once the page is loaded by including the following in the
element in the HTML (PHP) file:
<body onload="menuStyle();">
The new JS function can be specified in the HEAD of the HTML document or an external JS file.
Hope this helps someone.