Auto Highlighting from an SSI Navigation Menu
Recently on http://www.mafiawarstips.com I was in the process of converting the side navigation menu on the Strategy Guide sections to a Server Side IncludeW file. Before making the switch to an SSI, the guide was copy and pasted between each page to provide the following:

The biggest challenge to getting the navigation menu to behave as an SSI was the highlighting that is given to the link for the anchor of the page the guide is currently displayed on. In the previous version, every link was given a specific class and then another class was created for theming the inactive links. Finally, there was a specific id given to theme the link for the page that is currently being displayed. That ID could just as easily have been a class as well.
There isn’t a way to pass variables or parameters over to an SSI file that will work on both Apache and IIS. The specific effect we are looking for isn’t required for the page to function so a Javascript solution seemed like the best option. After browsing around I found the following idea:
/* Class appender function, straight out of Jeremy's book */
function appendClass(element,value) {
if (!element.className) {
element.className = value;
} else {
newClassName = element.className;
newClassName+= " ";
newClassName+= value;
element.className = newClassName;
}
}
// Function to add class="current" to the appropriate LI
function addYouAreHere() {
var listElement = document.getElementById("navigation");
if (listElement != null) {
if (!listElement.className) {
listElement.className = "noCurrentSelected";
} else {
var selected = listElement.className.split(" ");
var selected = selected[0] - 1;
var selectedLI = listElement.getElementsByTagName("li")[selected];
appendClass(selectedLI,"current");
}
}
}
This solution felt very heavy weight though. In the comments was another interesting idea:
var x = document.getElementsByTagName('a');
for (var i=0; i < x.length; i++)
{ if (x[i].href == location.href) x[i].className += 'onstate'; }
The general idea of cycling through the available anchors to find the appropriate one for the page we are on was a good one. Unfortunately, we don’t want to change all the links on a page and none of the articles mentioned at all how or when to get it to execute.
What I needed was a script to add to the INC file for the nav menu that would only look at the relevant anchors within the guide, execute when the list is first loaded, and not require any special code on the pages that include it. What I ended up with was the following:
<!-- Start: Guide Menu -->
<div class="guideMenu" id="guideMenu">
<div id="guideTitle">Strategy Guide</div>
<p><a class="guideItem" href="">Getting Started</a></p>
<p><a class="guideItem" href="">The Basics</a></p>
<p><a class="guideItem" href="">Rollin' a Bankroll</a></p>
<p><a class="guideItem" href="">Usin' Skill Points</a></p>
<p><a class="guideItem guideItemLocked">Doin' the Job</a></p>
<p><a class="guideItem guideItemLocked">Property Moguls</a></p>
<p><a class="guideItem guideItemLocked">Fightin' and Robbin'</a></p>
<p><a class="guideItem guideItemLocked">Game Design Suggestions</a></p>
</div>
<!-- Entry Highlighting Script -->
<script type="text/javascript">
<!--
var menuDiv = document.getElementById('guideMenu');
var anchors = menuDiv.getElementsByTagName('a');
for (var i = 0; i < anchors.length; i++)
{
if (anchors[i].href == location.href)
anchors[i].id = 'guideSelection';
}
-->
</script>
<!-- End: Guide Menu -->
Very simply, the original DIV for the menu was maintained, a specific ID was added so the script would target just the menu and not other links on the page. From there, just add a script block after the menu (otherwise the getElement calls will not work in all browsers) and leave the script outside of any function definition so it gets executed as the page gets parsed.
The script itself grabs the menu DIV so it can operate on only its child members and then collects all the anchors. It cycles through the anchors until it finds the one that matches the page it is currently on and adds our special selection ID. The solution would also work with classes by appending a new class name to the existing list on the element.
The final file is then able to be included in any of our guide pages and nothing special needs to exist on the page at all for the highlighting to be accurate. Hopefully this will help others working outside of PHP and ASP to have a simple way to break their navigational elements out from the individual pages and in to INC files where it is much more simple to keep them updated.




Leave a Reply