Universal Related Popup Menus / Related Menus
Related Menus
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
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
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
Created: Mar. 9, 1997
Revised: Oct. 18, 1999
URL: https://webreference.com/dev/menus/related.html