Switch Menu In Javascript

Tuesday, December 19, 2006

I formerly choose Accordion Control in Microsoft Ajax Control toolkit in my application. I like menu with such switching  style. The control is well in it's appearance. For example, we can set frames per second of switching animation and fading transition effect.

However, I encountered the problem when I set  AsyncPostBackTrigger of updatepanel to the LinkButton inside the accordion. If do this, there will be a error at runtime said that  LinkButton1 is not exist. I found a lot of developer have the same confusion at the official forum of asp.net but I can't get answer of it. I think this is may be control name changed when it is in a panel.

I tried another way to solve this problem is to put accordion in a updatapanel. Unfortunately, It still din not work due to LinkButton can't raised event.

Because I can't get the solution of it. I decided to write a switch menu in such style although the self-made one will be simple without any animation or fading effect.

We know we can use CSS style.display attribute to display or hide the div, control and so on. So it's not difficult to make a simple switch menu in Javascript. At first we made menu in html

<ul id="nav-secondary">
<li id="Menu1"><a href="#" onclick="SwitchMenu('Menu1','nav-secondary')">Menu 1</a>
<ul style="display: none;">
<li><a href="#" id="A1">Sub Menu 1.1</a></li>
<li><a href="#" id="A6">Sub Menu 1.2</a></li>
<li id="Menu2"><a href="#" onclick="SwitchMenu('Menu2','nav-secondary')">Menu 2</a>
<ul style="display: none;">
<li><a href="#" id="A5">Sub Menu 2.1</a></li>
<li><a href="#" id="A7">Sub Menu 2.2</a></li>
<li id="Menu3"><a href="#" onclick="SwitchMenu('Menu3','nav-secondary')">Menu 3</a>
<ul style="display: none;">
<li><a href="#" id="A2">Sub Menu 3.1</a></li>
<li><a href="#" id="A3">Sub Menu 3.2</a></li>
<li><a href="#" id="A4">Sub Menu 3.3</a></li>

SwitchMenu is defined in the Javascript to display or hide the sub menu. note is added. the statement used to set CSS class is optional

var currentMenu;                             //Global variable: current menu
//Parameter obj is the menu you clicked, container is the container layer of menu
function SwitchMenu(obj,container){         
if (currentMenu!=null) {
            //Clear css style of current menu
        //Get the target menu you clicked     
var targetMenu = document.getElementById(obj);      
        //Get sub-menu of target menu        
var secondaryMenutargetMenu.getElementsByTagName("UL")[0];    
var secondaryMenus = document.getElementById(container).getElementsByTagName("UL")//get all submenus   
if (secondaryMenu==null) {                                  //No sub menu                                 
for (var i=0i<secondaryMenus.lengthi++){    
                 //Hide all sub menu                       
            //Set target menu css class
}else{                                                                               //Sub menu Exist
            //Click the  menu which sub-menu is hide
if(secondaryMenu.style.display == "none"){                             
for (var i=0i<secondaryMenus.lengthi++){                            
"none";       //Hide all sub menu                     
"block";              //Display sub-menu u clicked             
targetMenu.className="active";                            //Set target menu css class         
}else{                                                  //Click the  menu which sub-menu is displayed   
secondaryMenu.style.display "none";               //Hide it    
= document.getElementById(obj);     //Set current menu (global variable)

Ok, run it in your browser. it works fine, right?

Maybe additional css make appearance better

/* SECONDARY NAVIGATION - vertical navigation */
#nav-secondary, #nav-secondary ul {position:static}
#nav-secondary, #nav-secondary li {list-style: none;margin:0;padding:0;background:#fff}
#nav-secondary {padding-top:0;border-top: 1px solid #ccc;margin-top: 1px}
#nav-secondary a {line-height:1.8;padding: 5px 0 5px 23px;background: #fff url("images/sprites.gif") no-repeat 10px -695px;font: bold 86% arial;display:block}
#nav-secondary a, #nav-secondary a:link, #nav-secondary a:visited, #nav-secondary a:hover, #nav-secondary a:active {text-decoration:none;cursor:pointer} 
#nav-secondary a:link {color:#000} 
#nav-secondary a:visited {color:#000} 
#nav-secondary a:hover {color:#c00;background: #fee url("images/sprites.gif") no-repeat 10px -695px} 
#nav-secondary li.active a:link, #nav-secondary li.active a:visited, #nav-secondary li.active a:hover, #nav-secondary li.active a:active {color:#c00} 
#nav-secondary li {border-top: 1px solid #fff;border-bottom: 1px solid #ccc}

#nav-secondary ul {margin: 0 0 1em 23px;padding:0}
#nav-secondary li.active li a, #nav-secondary li.active li a:link, #nav-secondary li.active li a:visited {line-height:1.5;background: #fff url("images/sprites.gif") no-repeat 0 -798px;padding:0 0 0 12px;font-weight:normal;width:auto;color:#000;width:130px;display:block}
#nav-secondary li.active li a:hover, #nav-secondary li.active li a:active {color: #c00}
#nav-secondary li.active li {border: none;margin:0}
#nav-secondary li.active li.active a:link, 
#nav-secondary li.active li.active a:visited, 
#nav-secondary li.active li.active a:hover, 
#nav-secondary li.active li.active a:active {font-weight:bold}

These are the final snap in my FireFox2 and IE7