Revision 34 (by dpavlin, 2004/09/26 22:10:44) hide dropdown first, and then empty it (prevents flicker in Internet
Explorer)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Combobox example</TITLE>

<style type="text/css">
#textfilterholder {
	border:1px black solid;
	padding:0px;
	width:200px;
}
#filterholder {
	position:relative;
}

#textfilter {
	width:175px;
	font-size:12px;
	border: 0px black solid;
	height:20px;
}
#sel {
	width:200px;
	font-size:12px;
}
#dropdown {
	z-index:100;
	border: 0px black solid;
	width:200px;
	position:absolute;
	top:20px;
	left:0px;
}
#status {
z-index:10;
}
#down {
	margin: 2px;
	background: #c0c0c0;
	border: 1px red solid;
	padding-left: 4px;
	padding-right: 4px;
}
</style>


<script type="text/javascript" src="combo-test.js"></script>
<script type="text/javascript" src="bfilter.js"></script>
<script type="text/javascript">

var combo_active = 1;
var combo_last_value = null;

var debug2_lines = 0;

function debug2(text) {
	var el = self.document.myfilter.element_id('debug2');
	debug2_lines++;
	if (debug2_lines > 10) {
		el.innerHTML = "...<br>";
		debug2_lines = 0;
	}
	if (el) el.innerHTML += debug2_lines+": "+text+"<br>";
	return true;
}

// keypress in dropdown
function combo_dropdown_keydown(event) {
	var d = event.keyCode;

	debug2("dropdown key: "+d);

	var el_textbox = self.document.myfilter.element_id('textfilter');
	var el_sel = self.document.myfilter.element_id('sel');

	// return to textbox and hide results on
	// enter, backspace, left, right, esc
	if (d == 13 || d == 8 || d == 37 || d == 39 || d == 27) {
		el_textbox.focus();
		self.document.myfilter.clear_results();

		// ignore backspace (to prevent back in history)
		if (d == 8)  return false;

		if (d == 27) {
			el_textbox.value = combo_last_value;
		}

	}

	// up or down on first/last element?
	var sel = el_sel.selectedIndex;
	var max = el_sel.options.length - 1;
	debug2("selected: "+sel+" max: "+max);
	if ( (d == 38 && sel == 0) || (d == 40 && sel == max) ) {
		self.document.myfilter.clear_results();
		el_textbox.value = combo_last_value;
		el_textbox.focus();
		combo_active = 0;
	}

	return true;

}

// keypress in textbox
function combo_textbox_keydown(e) {
	var d = e.keyCode;
	debug2("textbox key: "+d);

	var el = self.document.myfilter.element_id('sel');
	if (! el) return false;

	combo_active = 0;

	// up, down -- go to dropdown
	if ((d == 38) || (d == 40)) {
		var el_sel = self.document.myfilter.element_id('sel');
		// filter if no results
		debug2("existing results: "+el_sel.options.length);
		if (el_sel.options.length <= 0) {
			var el_textbox = self.document.myfilter.element_id('textfilter');
			self.document.myfilter.show_filter(el_textbox.value);
		} else {
			self.document.myfilter.show_results();
		}
		el_sel.focus();
		return false;
	}

	// if not enter, show combo
	if (d != 13) combo_active = 1;

	// left, right -- hide dropdown
	if (d == 37 || d == 39) {
		self.document.myfilter.clear_results();
		return false;
	}

	return true;
}


function myfilter() {

	self.document.myfilter = new BFilter(headlines);

	self.document.myfilter.result = function (arr) {
		var el = self.document.myfilter.element_id('sel');
		el.options[el.options.length] = new Option(arr[0],arr[1]);
		return true;
	}

	self.document.myfilter.clear_results = function () {
		var el = self.document.myfilter.element_id('sel');
		combo_active = 0;
		el.style.display = 'none';
		el.options.length = 0;
		el.selectedIndex = null;
		return true;
	}

	self.document.myfilter.show_results = function () {
		var el_textbox = self.document.myfilter.element_id('textfilter');
		var el_dropdown = self.document.myfilter.element_id('sel');
		el_dropdown.style.display = '';
		combo_last_value = el_textbox.value;
		return true;
	}

	var el_textbox = self.document.myfilter.element_id('textfilter');

	el_textbox.focus();
	el_textbox.caretPos=1;
//	el_textbox.select();
}

function combo_filter(value) {

	debug2("combo filter: "+value+" ["+combo_active+"]");
	if (! combo_active) {
		return null;
	}

	return self.document.myfilter.filter(value);
}

</script>




</HEAD>

<BODY onload="myfilter();">

<div id="debug" style="float: right; width: 20em; font-size: 70%; color: gray;">
</div>
<div id="debug2" style="float: right; width: 20em; font-size: 70%; color: gray;">
</div>

<div id="filterholder">
<div id="textfilterholder">
<input autocomplete="off" id="textfilter" type="text"
 onKeyDown="combo_textbox_keydown(event);"
 onKeyUp="combo_filter(this.value);"
 onClick="self.document.myfilter.clear_results();"
value="">
<img class="down" src="down.gif" alt="show alternatives" onClick="self.document.myfilter.show_filter(self.document.getElementById('textfilter').value);">
</div>

<div id="dropdown">
<select id="sel" size="5"
 onKeyDown="combo_dropdown_keydown(event);"
 onChange="self.document.getElementById('textfilter').value = this.options[this.selectedIndex].text;"
 onClick="self.document.myfilter.clear_results();"
 style="display: none;"
></select>
</div>

</div>

<div id="status">
</div>

<div style="color: #a0a0a0">
If this combobox isn't working for you, try running <tt>make combo</tt> to create
example data from first 10000 words in <tt>/usr/share/dict/words</tt>.
</div>


</BODY>
</HTML>