spacer

Webref WebRef   Sitemap · Experts · Tools · Services · Newsletters · About i.com

home / web / dev / menus / related

Related Menus

Developer News
Google Chrome Playing Catch-Up on Extensions
Open Solutions Alliance Gets New Leadership
Red Hat Spacewalk Expands Linux Management

Universal Related Popup Menus

JavaScript version 1.1, first introduced in Netscape 3.0, includes many new features that allows more dynamic Web pages. One in particular is the new Option command. This command allows the programmer to dynamically update the Option text in a select menu. This allows one menu to control the contents of another, thus the "related menu" was born (at WebReference.com). The "new Option" syntax is:

    new Option('option_text','value_text')

Where option_text is the text shown in the select menu's option and value_text is the text passed as that option's value. The above line would produce the following HTML:

    <OPTION VALUE="value_text">Option_text

Example Related Menus

2-level * 3-level * 4-level

We've encapsulated this command into a function called "O" (for brevity not clarity). O (for new Option function) is passed the option's descriptive text and url (value) and sets the current (k) element of array "a" to the new Option.

    function O(txt,url) {
    a[k]=new Option(txt,url); k++;
    }

The first "subject" menu calls the "relate" function, which zeros out the "a" array (a=new array(x)), fills it with new options, nulls out the second popup in reverse order and fills it with the elements of a.

    function relate(form,element,j) {
    if(v){ // if new Option command supported
     k=1;   // set option array number to 1
     if(j==0){ // if first (0th) option selected in subject menu
      a=new Array(8); // create new array exact length of menu
      O("3-D Animation","/3d/"); // fill array a with new option text/value pairs
      O("Design","/dlab/");
      O("DHTML","/dhtml/");
      O("E-Commerce","/ecommerce/mm/");
      O("Graphics","/graphics/");
      O("HTML","/html/");
      O("JavaScript","/js/");
    }
    ...
      aln2=a.length;  // save length of newly filled a array
      var formNum = getFormNum(formName); // get the form number from the form name (works in NS 2.02) 990102
      if (formNum>=0) { // check if a valid form number
    	formNum++; // reference next form, assume it follows in HTML
    	with (document.forms[formNum].elements[elementNum]) { // with saves a few bytes here
            	for (var i=<options.length-1;i>0;i--) options[i]=null;  
      		// null out current topic menu options array
      		// NOTE: bug fix here, IE 4 does not support nulling out nonexistent 
     		// options, so changed aln to options.length here (9-11-97). Now code 
      		// works in IE 4.
      		for (var i=1;i<aln2;i++) options[i-1]=a[i];  // fill up topic menu's options array
      		options[0].selected=true;  // default to 1st topic menu option, windows bug kludge
    	}
      }
      } else { // if new Option command not supported, act like live popup
      	jmp(formName,elementNum); // jump to this.form's element num's value, bug fix 990102 
      }
      }

Another quirk we found in JavaScript is that when you null out the popup menu before you redefine it with new options you have to do it in reverse order. Otherwise, you'll get menu overflow, where some menu options are tacked onto the beginning or end of the menu.

Bug Fix! - Internet Explorer 4 does not support nulling out nonexistent options, and the old code gives an error when the left menu is changed ("Option does not support this property or method.") The fix for this is to zero out (in reverse order) only the existing options. Changing "aln" to "options.length" solved the problem.

    for (var i=options.length-1;i>0;i--) options[i]=null;  
    // null out current topic menu options array
    // NOTE: bug fix here, IE 4 does not support nulling out nonexistent 
    // options, so changed aln to options.length here (9-11-97). Now code 
    // works in IE 4.

Note that the relate(Menus) code only runs for browsers that support the new Option command (currently Netscape 3+ and Internet Explorer 4), which supports JavaScript 1.1 and the new Option command. If the browser is does not support the new Option command the code defaults to the jmp(Page) function and acts like the right menu, a live popup.

    } else {
     	jmp(formName,elementNum); // if new Option command not supported, act like live popup
    }

Note also that you can pass the selectedIndex of the first (subject) form since it is a static menu, and the options don't change. This technique does not work on our second, dynamic menu.

    <SELECT NAME="m" onChange="relate(this.form,0,this.selectedIndex)">
    

Bug Fix: Netscape 2.02 gave an error when using the new object name passing method in the old jmp function. Specifically the following line gave an undefined:

    function jmp(formnum,menunum) {
    	with (document.forms[formnum].elements[menunum]) {
    	i=selectedIndex;location=options[i].value;
    	}
    }

Previously I hard coded the form and element number in the function calls. However, this causes a problem when the number and order of forms within the page are unknown (as with a form-enabled banner ad). To work around this problem, I combined the best of both worlds, I pass the form name using this.form:

    onChange="relate(this.form,0,this.selectedIndex)"
    onClick="jmp(this.form,0)"
    

and convert the form name to the matching form's number within the forms array using the new getFormNum function:

    function getFormNum (formName) {
    	var formNum =-1;
    	for (i=0;i<document.forms.length;i++){
    		tempForm = document.forms[i];
    		if (formName == tempForm) {
    			formNum = i;
    			correctForm = tempForm;
    			break;
    		}
    	}
    	return formNum;
    }
    
    function jmp(form, elt)
    // The first parameter is a reference to the form.
    {
    	if (form != null) {
    		with (form.elements[elt]) {
    			if (0 <= selectedIndex)
    				location = options[selectedIndex].value;
    		}
    	}
    }
    

This new method assumes that the second menu directly follows the first menu within the HTML (formNum = formNum + 1;) and that the number of the element with the menu in each form is the same.

Note that jmp does not call getFormNum anymore, as NS 2.02 had a bug within nested tables. getFormNum is still necessary however, when we use either relate function, to refer to the "next" form. Anybody think of a way to get rid of getFormNum?

Comments are welcome

internet.comearthweb.comDevx.commediabistro.comGraphics.com

Search:

Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

Jupitermedia Corporate Info

Legal Notices, Licensing, Reprints, Permissions, Privacy Policy.
Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers

webref The latest from WebReference.com Browse >
Popular JavaScript Framework Libraries: An Overview - Part 3 · Accessing Your MySQL Database from the Web with PHP · Working with the DOM Stylesheets Collection
Sitemap · Experts · Tools · Services · Email a Colleague · Contact FREE Newsletters 
 The latest from internet.com
MS Access and MySQL · Cisco AutoQoS: VoIP QoS for Mere Mortals · While VoIP Adoption Explodes in Enterprise, Carrier Spending Lags

 



Created: Mar. 9, 1997
Revised: Oct. 18, 1999

URL: http://webreference.com/dev/menus/related.html