DHTML Lab: Hierarchical Menus, I; Child Menu Creation | WebReference

DHTML Lab: Hierarchical Menus, I; Child Menu Creation


Logo

DHTML Hierarchical Menus, Part I
second and third level menu creation

Webreference

Contents

Open the menus above to remind yourself that this is a technique worth learning.

As you may recall, in our controlling makeTop() function, called when the page loads, we have this statement:

   if (topItem.hasMore) makeSecond();

Refresher: When we return from creating an item, we have set its hasMore property. If the item opens a child menu, then we have to create that menu by calling makeSecond().

The makeSecond() function is basically an adaptation of the makeTop() function, with only a few statements that differ. These statements are outlined in red below:

function makeSecond() {
   secondCount = topCount + "_" + topItemCount;
   
   secondArray = eval("arMenu" + secondCount);
   secondName = "elChild" + secondCount
   
   secondMenu = makeElement(secondName);
   secondMenu.setup = menuSetup;
   secondItemCount = 0;
   for (j=0; j<secondArray.length; j+=3) {
      secondItemCount++;
      secondItemName =  (keep with next)
        "item" + secondCount + "_" + secondItemCount;
      secondItem = makeElement(secondItemName,secondMenu)      
      
      if (secondItemCount > 1)
         secondItem.prevItem = (keep with next)
eval("item" + secondCount  + "_" +(secondItemCount-1));
      secondItem.setup = itemSetup;
      secondItem.setup(j,secondArray);
      
      if (secondItem.hasMore) makeThird();
   }
   secondMenu.setup(true,secondItem,topMenu,topItem);
}

Look over makeSecond(). Notice that it mostly repeats the statements in makeTop(). The logic is the same:

  • an identifier is created for the menu
  • a setup function is defined as the menu's setup method (menuSetup(), same as top level)
  • the contained items are created and set up, using itemSetup(), again like the top level
  • if any items have a child menu, another function, makeThird() is called.

Even in the similar statements, we have provided distinct identifiers to prevent any confusion with the identifiers in makeTop(). Remember that makeSecond() will run its course, possibly many times, before makeTop() terminates. When in makeSecond(), we are still in makeTop(). However, we do not need to remember any of these identifiers. In fact, we do not need to remember the menu names, the item names or any of the suffixes. We will never use them again! We only have to make sure that they are distinct from top level or third level identifiers. That is all. As you will see from the next page forward, our method assignment and relative referencing will make the menu identification instinctive, without reference to the element's name.

Second Level Differences

No arguments are passed to makeSecond(). Since we are still in makeTop(), all the makeTop() variables are available to us.

A variable, secondCount, is created that stores the identifier used for this menu. This identifier is created by combining the topCount (the present top level menu number) with an underscore and then the topItemCount (the present top level item number).

   secondCount = topCount + "_" + topItemCount;

So, if we are on the second item of the first menu, secondCount will be 1_2.

We now identify the array to be used for the child menu items by appending this identifier to arMenu:

   secondArray = eval("arMenu" + secondCount);

If secondCount is 1_2, then the array that should be used is arMenu1_2. Refer back to our array definitions to see how this fits in. Clearly, you can see the importance of strict adherence to the array naming scheme we devised.

We give the menu a string name to use when creating the positioned element. In this case, elChild is the prefix. Remember this is to differentiate the menus. We will never have cause to know what any child menu is named later.

   secondName = "elChild" + secondCount;

A new menu element is created, and a setup method is defined, just like the top level menus. We enter into a for loop for creating the menu items, using j as the incrementing pointer (i is still being used by makeTop() which has not yet terminated):

   secondMenu = makeElement(secondName);
   secondMenu.setup = menuSetup;
   secondItemCount = 0;
   for (j=0; j<secondArray.length; j+=3) {
      secondItemCount++;
      secondItemName =  (keep with next)
         "item" + secondCount + "_" + secondItemCount;
      secondItem = makeElement(secondItemName,secondMenu)      
      
      if (secondItemCount > 1)
         secondItem.prevItem = (keep with next)
eval("item" + secondCount  + "_" +(secondItemCount-1));
      secondItem.setup = itemSetup;
      secondItem.setup(j,secondArray);
      if (secondItem.hasMore) makeThird();
   }
   secondMenu.setup(true,secondItem,topMenu,topItem);
}

If an item has a child menu of its own, makeThird() is called. Finally the menu's setup method is invoked. Unlike the top level menus, four arguments are passed to menuSetup(). The use of these arguments was discussed in the menu setup page.

The Third Level

Another function, makeThird() handles the creation of third level menus and menu items. It is identical to makeSecond() in its logic, with one exception: It is assumed that no item can have a child menu. You can expand our technique to include another level by simply creating a fourth level function identical to makeSecond() and makeThird(), and have makeThird() check an item's hasMore property before calling the new function.

function makeThird(){
   thirdCounter = secondCount + "_" + secondItemCount;
   
   thirdArray = eval("arMenu" + thirdCounter);
   thirdName = "elGrandChild" + thirdCounter;
   thirdMenu = makeElement(thirdName)
   
   thirdMenu.setup = menuSetup;
   thirdItemCount=0;
   for (k=0; k<thirdArray.length; k+=3) {
      thirdItemCount++;
      thirdItemName =  (keep with next)
         "item" + thirdCounter + "_" + thirdItemCount;
      thirdItem = makeElement(thirdItemName,thirdMenu);
      if (thirdItemCount > 1)
         thirdItem.prevItem =  (keep with next)
eval("item" + thirdCounter + "_" + (thirdItemCount-1));
      thirdItem.setup = itemSetup;
      thirdItem.setup(k,thirdArray);
   }
   thirdMenu.setup(true,thirdItem,secondMenu,secondItem);
}

Finally, we have examined the functions that create our menus. Now, things get easy and fun. First, how do we get the menus to appear on our page?


Produced by Peter Belesis and

All Rights Reserved. Legal Notices.
Created: Feb. 19, 1998
Revised: Feb. 19, 1998

URL: http://www.webreference.com/dhtml/column14/menuChild.html