Using the select box as a menu (page 1)


The menu:
If we want the select box to function as a genuine menu, then a click on a given option (of the select box) must give us the same range of possibilities as does a click on the items of a normal menu. So a click should allow us to go to a new page, to open a popup window, to produce an alert etc.

We can achieve this with the help of a function having the following general form:

var which="";
function DoSomethingWithOptionvalue(which) {
var optionValue = document.getElementById(which).options[document.getElementById(which).selectedIndex].value;
var optionValueWithSplit = optionValue.substring(0,[optionValue.indexOf('|')]);
var url = optionValue.substring(optionValue.indexOf('|')+1, optionValue.length);
if (optionValue=="bla") {some function()}
if (optionValueWithSplit=="blo") {some function()}
}

The following lines are an arbitrary instantiation of the function:

var which="";
function DoSomethingWithOptionvalue(which) {
var optionValue = document.getElementById(which).options[document.getElementById(which).selectedIndex].value;
var optionValueWithSplit = optionValue.substring(0,[optionValue.indexOf('|')]);
var url = optionValue.substring(optionValue.indexOf('|')+1, optionValue.length);

//Some browsers (Chrome!) need this line, because they don't allow options with no value
if (optionValue=="none") {}

else if (optionValue=="alarm") {alert('This is an alert.')}
else if (optionValue=="red background") {document.body.style.background='red'}
else if (optionValueWithSplit=="popup") {window.open(url,'','toolbar=1, location=1, directories=1, status=1, menubar=1, scrollbars=1, resizable=1, width=600px, height=350px, top=50px, left=100px');}
else location.href=url
}

This function ensures that a click on an option having value="none" produces nothing, that a click on an option having value="alarm" produces an alert, that a click on an option having value="red background" changes the background-color to red while a click on an option having value="popup|http://www.google.com" (with a pipeline character = Split!) opens Google in a popup window. The last line of the function (else location.href=url) ensures that a click on an option having value="some_page.html" brings us to some_page.html (normal link). Of course, we could add as many else if's as we like (= as many (sub-)functions as we like).

Here'a the function that is actually used on this page. Move the mouse over 'Item 1' / 'Item 2' / 'Item 3' above and observe the results:

var which="";
function DoSomethingWithOptionvalue(which) {
var optionValue = document.getElementById(which).options[document.getElementById(which).selectedIndex].value;
var optionValueWithSplit = optionValue.substring(0,[optionValue.indexOf('|')]);
var url = optionValue.substring(optionValue.indexOf('|')+1, optionValue.length);
var info = "Om muziek te beluisteren, CTRL-knop ingedrukt houden bij klik op OK.";

if (optionValue=="none") {}
else if (optionValue=="alarm") {alert('This is an alert.')}
else if (optionValue=="red background") {document.body.style.background='red'}
else if (optionValue=="white background") {document.body.style.background='white'}
else if (optionValueWithSplit=="iframe") {frames['an_iframe'].location.replace(url)}
else if (optionValueWithSplit=="popup") {window.open(url,'','toolbar=1, location=1, directories=1, status=1, menubar=1, scrollbars=1, resizable=1, width=600px, height=350px, top=50px, left=100px');}
else if (optionValueWithSplit=="email") {location.href='mailto:'+url}
else if (optionValueWithSplit=="VerdiLisztBrahmsTjaik") {var message=info+"\n\nVerdi: Ouverture `La forza del destino`.\nLiszt: Eerste pianoconcert.\nBrahms: Hongaarse Dansen 1, 5, 6 en 7.\nTsjaikovsky: Capriccio Italien.\n\nDoor: Residentie Orkest olv Vassili Sinaiski; Love Derwinger,piano.";alert(message);zz=window.open(url,'','left=10000px,width=1px,height=1px');setTimeout('zz.close()',5000)}
else location.href=url
}

This function operates on the following select box(es):

<select size="0" name="select1" id="select1" onchange="DoSomethingWithOptionvalue('select1')" >

<option value="none" selected >Some text</option>

<optgroup label="Normal link" >
<option value="page1.html">Page 1</option>
<option value="page2.html">Page 2</option>
</optgroup>

<optgroup label="New window / popup" >
<option value="popup|http://www.google.com">Google in new window</option>
<option value="VerdiLisztBrahmsTjaik|http://cgi.omroep.nl/cgi-bin/streams?/avro/klassiek/zoc/zoc_940904_bb.wma">Music</option>
</optgroup>

<optgroup label="Iframe">
<option value="iframe|http://www.google.com" class="option">Google in iframe</option>
<option value="iframe|about:blank" class="option">Empty iframe</option>
</optgroup>

<optgroup label="Change background" >
<option value="red background">Make background ugly red</option>
<option value="white background">Make background white</option>
</optgroup>

<optgroup label="Alert" >
<option value="alarm">Produce an alert</option>
</optgroup>

<optgroup label="Email" >
<option value="email|bla@gmail.com">Send an email</option>
</optgroup>

</select>

Copy/paste the function and the select box and experiment with them. You'll learn fast enough how everything works.

Menu type / show/hide the menu:
It is preferable to use a select box menu having size="0" (or "1", or no size at all, which is the same as size="0"). Why zero-size? Because we want our menu to be able to appear outside of the control window over other windows and to stay within the visible part of the screen without having to do any specific scripting.

It is also a good idea to anchor a select box (used as a navigation tool) to another element, which shows/hides the box when the mouse moves over the anchor (show) or out of it (hide). This gives us some freedom in positioning the select box on the screen.

Showing a select box having 'display:none' is a simple matter. We could do, for instance:

function showBox(which)
{
document.getElementById(which).style.display='inline';
}

and then provide the anchor of a select box having id="some_selectbox" with onmouseover="showBox('some_selectbox')".

But hiding the select box in a proper way is another matter. The complexity of the matter has to do with the fact that different browsers require different ways to hide select boxes. For instance, if, in the select tag, we put onmouseout="this.style.display='none'", then, if we move the mouse out of the select tag, the entire select box hides in non-IE - except Opera - and in IE>6, but in IE6 and in Opera, only the first option (or the one having 'selected') goes away, etc.

Fortunately, these crossbrowser problems can be overcome (I added some lines ensuring that the select box 'maintains' its selected option):

Coding in the head:

//Div needed for showing and hiding select boxes. Background needed for IE6 (and possibly higher versions). We hide the background with opacity
document.write('<div id="hider" style="position:absolute; left:0; width:0%; height:0%; display:inline; z-index:2000; background:white; filter:alpha(opacity=0); opacity:.0" onmousemove="style.height=\'0px\'; style.width=\'0px\'; hideAll()"></div>')

var which="";

/* This hides the selected option in non-Opera when the select box folds out, ensuring that you don't see the selected option twice. You have to give the selected option of each menu: class="dynamicStyle". Doesn't work in IE, and must not apply to Opera, because it would mess up the select box. */
if(!window.opera){
document.write('<style type="text/css">.dynamicStyle{display:none}><\/style>')
}

/* Needed to keep 'selected' intact. */
function selected(){
for (i=0;i<document.getElementsByTagName('select').length; i++) {
document.getElementsByTagName('select').item(i).selectedIndex=0;
}
}
//The onload probably not needed; just a security measure
document.onload=selected;
document.onmouseover=selected;

//Focus needed for IE6
function focusIE6(){
if(/*@cc_on!@*/false){document.body.focus()}
}
document.onmouseover=focusIE6

function hide(tag,className) {
var els = document.getElementsByTagName(tag)
for (i=0;i<els.length; i++) {
if (els.item(i).className == className){
els.item(i).style.display="none";
}
}
}

//This function requires class="selectbox" for each select box
function hideAll()
{
hide('select','selectbox');
}

function showBox(which)
{
document.getElementById(which).selectedIndex=0;
document.getElementById(which).style.display='inline';
}

In the body:

//Anchor-button for first select box
<span onmouseout="hideAll()" >
<button onmouseover="showBox('select1')">Item 1</button>
</span>

<select size="0" name="select1" id="select1" class="selectbox" style="position:absolute;left:2%;margin-top:18px;display:none" onmouseout="document.getElementById('hider').style.height='95%'; document.getElementById('hider').style.width='100%'" onchange="DoSomethingWithOptionvalue('select1'); selectedIndex=0" onmouseover="showBox('select1')" >

<option value="none" selected class="dynamicStyle"> Everything about item 1</option>
...
other options
...
</select>

This works. Copy/paste and try for yourself.

Notes: