Frontendplace Blog

Sharing Frontend developing ideas

combobox

Ever wanted to add a combobox (selectbox and inputbox) in your HTML form.

combo2 combo3

Here you can find the code for the Combobox

This is the markup

You can also place the inline javascript as an obtrusive way in an included
javascript file and then show or create the input tag only when javascript
is enabled

<form id=”form1″ action=”#”>

<div id=”combo1″>

<input name=”textInput” type=”text” class=”combotext” id=”textInput”

onmouseup=”combotext_onkeyup(event, this)”
onkeydown=”combotext_onkeydown(event, this)”
onkeyup=”combotext_onkeyup(event, this)”
onfocus=”combotext_onkeyup(event, this)”
autocomplete=”off”

>
<

select name=”selectInput” size=”1″ id=”selectInput” class=”comboselect”

onblur=”hideCombo(this)”
onchange=”comboselect_onchange(event,this)”
onkeyup=”comboselect_onkeyup(event, this)”
onmouseup=”comboselect_onmouseup(event,this);”

>
<option>Alabama</option>
<option>Alaska</option>
<option>Arizona</option>
<option>Arkansas</option>
<option>California</option>
<option>Colorado</option>

</div>

</form>

This is the stylesheet

  • <style type=”text/css”>
    body {

    • margin:0;
      padding:0;
      background-color: #CCC;
      }
  • *html body {
    • display:block;
      width:100%;
      height:100%;
      }
  • .textelement{
    • border:1px solid #CCC;
      width:106px;
      height:1.2em;
      }
  • .combotext{
    • border:1px solid #CCC;
      padding:0px 3px;
      width:100px;
      height:1.2em;
      }
  • .comboselect{
    • border:1px solid #CCC;
      background:#DDD;
      display:none;
      position:absolute;
      top:1.2em;
      padding-right:10px;
      margin-top:2px;
      left:0px;
      width:108px;/* width of text plus padding and border */
      }
  • #combo1{
    • position:relative;
      }
  • </style>

Finally the javascript

/* handle changes of textbox */
function combotext_onkeyup(evt, oText, oSelect) {
    var e = evt ? evt : window.event;
    if (!e) return;// don't know what caused the event
	if(!oSelect) oSelect = oText.form[getFormIndex(oText)+1];
// selectbox should be the form element next to the textbox
    var keyCode = (!e.keyCode) ? -1 : e.keyCode;  
//when no key code is passed then -1;
    var nextOptionText;
    var iMaxNumToShow = 8;
    if (keyCode == 40 || keyCode == 38) {  				
// check input chars up down
        oSelect.style.display = "block";
        oSelect.focus();
        comboselect_onchange(e,oSelect, oText);
    } 
	if (keyCode == 9) {return true;} 
	else { 								
		var arSource = arCombo[oSelect.id].optionValues;
		var iarLength = arSource.length; 		
// Remember the selectbox list length for loop speedup
		var toFind = oText.value;				
// text to find in optiontext
		var sOptionText = "";					
// init values
		var iNumShown = 0;
		oSelect.options.length = 0;
		for (i = 0; i < iarLength; i++) {		
// loop over the intial values and find the string
			sOptionText = arSource[i];
			var searchPattern = "^" + toFind;
			var re = new RegExp(searchPattern, "gi"); 
// Create a regular expression
			if (re.test(sOptionText) || toFind == "") { 
// if found add this value to the selectbox
				oSelect[iNumShown] = new Option(sOptionText, "");
				iNumShown++;
			}
		}
		showCombo(oSelect);
//oSelect.style.display = "block";display selectbox
		oSelect.size = (oSelect.length <= iMaxNumToShow) ?oSelect.length :iMaxNumToShow; 
// shrink size to minimal
		
		stopPropagate(e);
		
		if (oSelect.length == 1 ) {				
// When options list whittled to one, select that entry and don't return the last key
			oSelect.options[0].selectedIndex = 0;
			oSelect.options[0].selected = true;
			oText.value = oSelect.options[0].text;
			return false;
		}
    }
}
// selectbox eventhandlers
function comboselect_onchange(evt,oSelect, oText) {
	if(oSelect.type!="select-one") return;
	if(!oText) oText = oSelect.form[getFormIndex(oSelect)-1];
// textfield should be the form element previous to the selectbox
    if (oSelect.selectedIndex != -1) oText.value=oSelect.options[oSelect.selectedIndex].text;
// if change caused by mouseevent then close selectbox  bu how do i detect that??
	if (window.mouseevent) hideCombo(oSelect);
	window.mouseevent = false;
}

// detect return on selectbox
function comboselect_onkeyup(evt, oSelect, oText) {
	var e = evt ? evt : window.event;
	if (!e) return;// don't know what caused the event
	var keyCode = e.keyCode;
	if(!oText) oText = oSelect.form[getFormIndex(oSelect)-1];
// textfield should be the form element previous to the selectbox
    if (keyCode == 13 ) {
        comboselect_onchange(e,oSelect, oText);
        hideAllComboBoxes();
        oText.focus();
    }
} 

function getKey(evt){
	var e = evt ? evt : window.event;
	if (!e || typeof e.keyCode == "undefined") return -1;
// don't know what caused the event
	else return e.keyCode;
}

function comboselect_onmouseup(evt){
// don't detect the onmouseup on the document because 
// the onmouseup also fires in firefox on the scrollbar
	stopPropagate(evt);
	window.mouseevent = true;
}

function combotext_onkeydown(evt,oText){
	var e = evt ? evt : window.event;
	if (!e) return;// don't know what caused the event
	// Set references to the form elements on enter or tab
	if( e.keyCode && (e.keyCode == 13 || e.keyCode == 9)){
		// prevent for submitting form when enter/return is used
		stopPropagate(e)
		// is there a new element to get focus?
		setFocusToNextElement(oText,e.keyCode);
		// hide the selectbox
		hideAllComboBoxes();
	}
}
// stop propagate events up down
function stopPropagate(evt){
	var e = evt ? evt : window.event;
	if (!e) return;// don't know what caused the event
	e.cancelBubble = true;
	if (e.returnValue) e.returnValue = false;
	if (e.stopPropagation) e.stopPropagation();
}

// set the right next element when return or tab key is used
function setFocusToNextElement(oCurEl,iKeycode){
	// get currentElement
	var oFocusEl = oCurEl;
	var index = getFormIndex(oCurEl);
	 // if tab choose one element before tabbed element
	if( oCurEl.form[index+2].style.display!="none" ) {
		if(iKeycode ==9) {
			if(!window.event)oFocusEl = oCurEl.form[index+1]; 
// when not in IE tabbed not last one but one before 
// that and then tabbed to next one
		}
	else 
		oFocusEl = oCurEl.form[index+2];
	} 
	// don't refocus
	if (oFocusEl!=oCurEl) oFocusEl.focus();
}


function getFormIndex(oCurEl){
	var oCurIndex = 0;
	var len = oCurEl.form.length;
	var i;
	for (i=0;i= 0; i = i - 1){
        item = listEvents[i];
        if(item[0].removeEventListener){
          item[0].removeEventListener(item[1], item[2], item[3]);
        };
        if(item[1].substring(0, 2) != "on"){
          item[1] = "on" + item[1];
        };
        if(item[0].detachEvent){
          item[0].detachEvent(item[1], item[2]);
        };
        item[0][item[1]] = null;
      };
    }
  };
}();

/* function Created by Dustin Diaz http://www.dustindiaz.com/ */
function addEvent(obj, type, fn) {
  if (obj.addEventListener) {
    obj.addEventListener(type, fn, false);
    EventCache.add(obj, type, fn);
  }
  else if (obj.attachEvent) {
    obj["e"+type+fn] = fn;
    obj[type+fn] = function() {obj["e"+type+fn](window.event);}
    obj.attachEvent("on"+type, obj[type+fn]);
    EventCache.add(obj, type, fn);
  }
  else {
    obj["on"+type] = obj["e"+type+fn];
  }
}

function init(){
	storeComboSelect();
	window.mouseevent = false; 
// differentiate between mouse or key event as boolfor change selectbox
}
addEvent(window,"load",init);
addEvent(document,"mouseup",hideAllComboBoxes);
addEvent(window,'unload',EventCache.flush);
 

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>