Using Submenus

As of version 2.0, the UW Flyout Menus support submenus. The simplest way to define submenus is to use the makeLayer function, but you can also use predefined menus.

Simple Submenus

This example shows that you can define more than one level of submenu. You do need to be sure to:

  1. Have a good indication that there are submenu items. In this example, the normal arrow is always displayed, and filled in when the submenu is active. Having this arrow is a good visual cue, and filling the arrow shows which items triggered the menus.
  2. Don't make the timeout values smaller than the defaults. If, for example, you shorten the time a menu stays displayed after the mouse leaves, it is more difficult to accurately get the mouse in the menu before it goes away. If you make the amount of time before a menu shows up too short, a completely different menu may show up if the user's mouse passes over another link on the way to the menu.
  3. Either set menu widths or force no line breaks. This is because submenus default to being no wider than their parent menus. If your first menu has short items but your second menu has longer ones, your menu will be harder to read unless you declare a comfortable width or make sure the text does not wrap.

A simplified example can be viewed which only has what's necessary to implement this menu.

HTML

The HTML to use submenus is the same as with the other examples which use makeLayer:

<a href="#" onmouseover="mIn ('menu1')" onmouseout="mOut ('menu1')">Using
    submenus <img id="menu1" src="/home/graphics/arrow0.gif"
    width="9" height="13" alt=""/></a>

Older versions of Flyout Menus did not need an argument to the mOut function, but it's necessary when you use submenus. This is so the script can tell which menu should be closed.

CSS

The CSS which is used is also the same as with other examples, but this time we also explicitly set the menus to not wrap lines:

.barlink a, .navlink a {
    text-decoration: none;
}
.barlink a img, .navlink a img {
    border: 0;
}
.barlink a {
    color: #fff;
}
#l_menu1.flyout td {
    white-space: nowrap;
}

For this particular example, the last rule is very specific because there is more than one example on this page. Normally you do not need to do this, and the simplified example uses a more general rule.

Javascript

While the HTML and CSS are similar to the examples without nested menus, the Javascript does look quite different. We define the submenus when we call makeLayer:

var newDefs = new Object;
newDefs.overimg = '/home/graphics/arrow1.gif';
flyDefs (newDefs);
makeLayer (
    "menu1",
    "First title=#",
    "Item 1=#",
    "Item 2=#>menu2a",
	 "Item 2 submenu=#",
	 "Subitem 1=#",
	 "Subitem 2=#",
	 "Subitem 3=#>menu2a3",
	      "Subitem 3 submenu=#",
	      "Sub Subitem 1=#",
	      "Sub Subitem 2=#",
	      "<menu2a3",
	 "Subitem 4=#",
	 "<menu2a",
    "Item 3=#",
    "Item 4=#>menu4a",
	 "Item 4 submenu=#",
	 "Subitem 1=#",
	 "subitem 2=#",
	 "<menu4a"
);

At first glance you can see that the nested menus are defined where they will actually show up. The menu item named Item 2 has >menu2a after it, which indicates that this item should have a submenu which is named menu2a. The next string after that is the title of the submenu; if you do not wish to have a title, you still need an empty string, just like with normal menus.

After the submenu's title, you enter items just like with non-nested menus. After the last item for Item 2 submenu you see a string which has <menu2a, which indicates the end of menu2a.

The submenu for Item 4 is defined in the same manner as the one for Item 2. You'll also see that Item 2 submenu itself has a submenu attached to its third item, which is defined just like the other submenus.

You must be very careful how you define the submenus, since the menu start and stop strings must both exist and match exactly. If they are incorrectly defined, makeLayer will not be able to figure out where the submenus start and end.

Arrow Images

You may have noticed that the submenus use the same arrow image as the parent menu, even though one was not defined (even with the flyDefs function). This is because if the outimg default is not changed, the flyout script will use the arrow image used to trigger the main menu, and will also copy any CSS classes defined. It will not, however, copy the width or height; since the image will already be loaded, the browser will already be able to figure out the size. If you wish to have the arrow image to be different than its native size, you need to set the size using CSS (which is why the CSS classes are copied).

If you change the outimg default, that image will override the main menu's arrow image. If your image object is not actually an image, then the outimg default will be used, or the normal UW Home Page arrow if that is not set.

Submenus with Predefined Menus

You can also use predefined menus with submenus:

While the HTML and CSS seem more complex than the previous example, these menus also work when Javascript or CSS are disabled.

A simplified version of this example is available.

HTML

The HTML for this example is a series of nested unordered lists.

<ul class="submenus2">
    <li><a href="#" onmouseover="mIn ('pmenu1')"
	    onmouseout="mOut ('pmenu1')">Submenu Example
	    <img id="pmenu1" src="/home/graphics/arrow0.gif"
	    width="9" height="13" alt=""/></a>
	<ul id="l_pmenu1" class="flyout">
	    <li class="title2"><a href="#">Submenu Example</a></li>
	    <li><a href="#">Item 1</a></li>
	    <li><a href="#" onmouseover="mIn ('pmenu2a')"
		    onmouseout="mOut ('pmenu2a')">Item 2
		    <img id="pmenu2a" src="/home/graphics/arrow0.gif"
		    width="9" height="13" alt=""/></a>
		<ul id="l_pmenu2a" class="flyout">
		    <li class="title2"><a href="#">Item 2</a></li>
		    <li><a href="#">Subitem 1</a></li>
		    <li><a href="#">Subitem 2</a></li>
		</ul>
	    </li>
	    <li><a href="#">Item 3</a></li>
	</ul>
    </li>
</ul>

The arrow images and identifiers are all explicitly entered into the HTML. As with other predefined menu examples, you could add the arrows either with Javascript or CSS, and the identifiers could also be added with Javascript.

CSS

As with the previous example, some of the CSS is specific to this page since there is more than one example. The simplified example also has simplified CSS, which is why that CSS doesn't exactly match what's used here.

.submenus2 a, #l_pmenu1.flyout a {
    text-decoration: none;
}
.submenus2 img, #l_pmenu1.flyout img {
    border: 0;
}
ul.submenus2 {
    list-style-type: none;
}
ul#l_pmenu1.flyout li.title2 {
    color: white;
    background: blue;
    text-align: center;
}
ul#l_pmenu1.flyout li.title2 a {
    color: white;
}
ul#l_pmenu1.flyout, ul#l_pmenu1.flyout ul {
    width: 10em;
    background: white;
    margin-left: 0;
    margin-top: 0;
    border: 2px blue solid;
    padding-left: 0;
    list-style-type: none;
}
ul.submenus2 ul#l_pmenu1.flyout, ul.submenus2 ul#l_pmenu1.flyout ul {
    border: none;
    padding-left: 1em;
}
ul.submenus2 ul.flyout li.title2, ul.submenus2 ul.flyout img {
    display: none;
}

The last two rules are what make the menus work without Javascript by removing the border, and hiding the menu titles and submenu arrows. The arrow for the menu itself cannot be hidden with CSS, however, unless you use Javascript to either enable the arrow or set some other state.

The menus have a fixed with of 10em. If this were not done, the submenus would have an unpredictable appearance; the width may be too narrow, or the menu's border would surround a narrow menu, but the text would overflow outside the border.