It may come as a surprise, but there are no "combo boxes" in HTML forms.

A "combo box" is of course a combination dropdown list/edit control; i.e., a control where the user can either enter freeform text or select from a set of choices available in a dropdown list. Dropdown list boxes are present in HTML, but combo boxes aren't.

Recently, I was working on a Web-based application that required combo boxes in forms. I looked around on the Web for a workaround but I found no satisfactory solution. Instead, I developed my own:

This is a test. Enter something here or select from the list:

This implementation consists of two parts: a JavaScript portion with a couple of functions, and the HTML form.

The HTML form contains an ordinary edit control, a button, and a "hidden" list control of the desired size:

<p>This is a test. Enter something here or select from the list:
<input id="combotext" style="width: 200px; height: 23px;" type="text" size="20"
/><input style="height: 22px; width: 22px; font-family: helvetica; font-size: 10pt;"
onclick="JavaScript:menuActivate('combotext', 'combodiv', 'combosel')"
type="button" value="&9660;" />
<span style="position: absolute; display: none; top: 0px; left: 0px; z-index: 10000; width: 220px;"
id="combodiv" onmouseover="javascript:oOverMenu='combodiv';"
onmouseout="javascript:oOverMenu=false;"><select id="combosel"
style="width: 220px; border-style: none;"
onclick="JavaScript:textSet('combotext',this.value);"
onkeypress="JavaScript:comboKey('combotext', this);" size="10">
<option value="ARGENTINA">ARGENTINA</option>
...
<option value="VIETNAM">VIETNAM</option> </select></span></p>
</form>

The JavaScript code provides functions that make the dropdown list visible, and copy the content from the dropdown list to the edit control when the user makes a selection:

<script lang="JavaScript">
<!--
var fActiveMenu = false;
var oOverMenu = false;

function mouseSelect(e)
{
	if (fActiveMenu)
	{
		if (oOverMenu == false)
		{
			document.getElementById(fActiveMenu).style.display = "none";
			fActiveMenu = false;
		}
	}
}

function menuActivate(idEdit, idMenu, idSel)
{
	if (fActiveMenu) return mouseSelect(0);

	oMenu = document.getElementById(idMenu);
	oEdit = document.getElementById(idEdit);
	nTop = oEdit.offsetTop + oEdit.offsetHeight;
	nLeft = oEdit.offsetLeft;
	while (oEdit.offsetParent != document.body &&
oEdit.offsetParent.getStyle('position') != "relative") { oEdit = oEdit.offsetParent; nTop += oEdit.offsetTop; nLeft += oEdit.offsetLeft; } oMenu.style.left = nLeft + "px";
oMenu.style.top = nTop + "px";
oMenu.style.display = ""; fActiveMenu = idMenu; document.getElementById(idSel).focus(); return false; } function textSet(idEdit, text) { document.getElementById(idEdit).value = text; oOverMenu = false; mouseSelect(0); document.getElementById(idEdit).focus(); } function comboKey(idEdit, idSel) { if (window.event.keyCode == 13 || window.event.keyCode == 32) textSet(idEdit,idSel.value); else if (window.event.keyCode == 27) { mouseSelect(0); document.getElementById(idEdit).focus(); } } document.onmousedown = mouseSelect; //--></script>

The function menuActivate makes the previously invisible div tag visible, and positions it right underneath the edit control. This function is activated whenever the user clicks the button. It also sets the focus to the list control within the div tag. If the user makes a selection, the function textSet is invoked, which copies the selection to the edit control. Afterwards, or if the user clicks an area outside the dropdown list, the function mouseSelect is called, and it removes the menu from the screen.

If the code is displayed by a browser that has no JavaScript support, only the edit control is shown, the dropdown never appears. However, the form will remain usable.

The comboKey function is a helper function that assists with keyboard navigation.

This solution has been tested on Windows using Internet Explorer 6.0, Mozilla FireFox 1, and Opera 7. It has also been tested using Mozilla, Netscape and Konqueror on Linux. By and large it works on all these systems, but cosmetic problems remain, especially in Konqueror, but also on the other platforms: Most notably, the down-arrow character used for the button label is not available in all character sets, keyboard navigation only works under Internet Explorer, and the border of the dropdown list may not always appear as desired. Also, the accessibility of the solution is limited; you cannot use the down-arrow on the keyboard, for instance, to invoke the dropdown list and make a selection.

Update (October 12, 2005): I was just told by Zhang Weiwu from China that the solution also works on Windows 98 using Internet Explorer 5.5.

Update (January 26, 2011): I thank James Bench for contributing a fix that made this solution compatible with Google Chrome and Apple Safari.

Update (November 25, 2011): In the process of moving this page to Joomla!, I discovered some HTML idiosyncrasies that I corrected. Most notably, the code now works correctly even when it is placed inside an element that has the position:relative style set.