Auto complete javascript text field

This is a javascript example for an auto complete text field. You can use the mouse or the up and down keys to select an entry. By pressing escape you leave the suggestion box. It runs fine with Mozilla, IExplorer 5+6. It also works in opera, but it has some minor glitches.
Please enter something with "B" at the beginning:
Javascript code:
<script type="text/javascript">
<!--
	var suggestions = new Array("Boris", "Bäcker", "Peter", "Test","Bums");
	var outp;
	var oldins;
	var posi = -1;
	var words = new Array();
	var input;
	var key;

	function setVisible(visi){
		var x = document.getElementById("shadow");
		var t = document.getElementsByName("text")[0];
		x.style.position = 'absolute';
		x.style.top =  (findPosY(t)+3)+"px";
		x.style.left = (findPosX(t)+2)+"px";
		x.style.visibility = visi;
	}

	function init(){
		outp = document.getElementById("output");
		window.setInterval("lookAt()", 100);
		setVisible("hidden");
		document.onkeydown = keygetter; //needed for Opera...
		document.onkeyup = keyHandler;
	}

	function findPosX(obj)
	{
		var curleft = 0;
		if (obj.offsetParent){
			while (obj.offsetParent){
				curleft += obj.offsetLeft;
				obj = obj.offsetParent;
			}
		}
		else if (obj.x)
			curleft += obj.x;
		return curleft;
	}

	function findPosY(obj)
	{
		var curtop = 0;
		if (obj.offsetParent){
			curtop += obj.offsetHeight;
			while (obj.offsetParent){
				curtop += obj.offsetTop;
				obj = obj.offsetParent;
			}
		}
		else if (obj.y){
			curtop += obj.y;
			curtop += obj.height;
		}
		return curtop;
	}
	
	function lookAt(){
		var ins = document.getElementsByName("text")[0].value;
		if (oldins == ins) return;
		else if (posi > -1);
		else if (ins.length > 0){
			words = getWord(ins);
			if (words.length > 0){
				clearOutput();
				for (var i=0;i < words.length; ++i) addWord (words[i]);
				setVisible("visible");
				input = document.getElementsByName("text")[0].value;
			}
			else{
				setVisible("hidden");
				posi = -1;
			}
		}
		else{
			setVisible("hidden");
			posi = -1;
		}
		oldins = ins;
	}
	
	function addWord(word){
		var sp = document.createElement("div");
		sp.appendChild(document.createTextNode(word));
		sp.onmouseover = mouseHandler;
		sp.onmouseout = mouseHandlerOut;
		sp.onclick = mouseClick;
		outp.appendChild(sp);
	}
	
	function clearOutput(){
		while (outp.hasChildNodes()){
			noten=outp.firstChild;
			outp.removeChild(noten);
		}
		posi = -1;
	}
	
	function getWord(beginning){
		var words = new Array();
		for (var i=0;i < suggestions.length; ++i){
			var j = -1;
			var correct = 1;
			while (correct == 1 && ++j < beginning.length){
				if (suggestions[i].charAt(j) != beginning.charAt(j)) correct = 0;
			}
			if (correct == 1) words[words.length] = suggestions[i];
		}
		return words;
	}
	
	function setColor (_posi, _color, _forg){
		outp.childNodes[_posi].style.background = _color;
		outp.childNodes[_posi].style.color = _forg;
	}
	
	function keygetter(event){
		if (!event && window.event) event = window.event;
		if (event) key = event.keyCode;
		else key = event.which;
	}
		
	function keyHandler(event){
		if (document.getElementById("shadow").style.visibility == "visible"){
		var textfield = document.getElementsByName("text")[0];
		if (key == 40){ //Key down
			//alert (words);
			if (words.length > 0 && posi  words.length-1){
				if (posi >=0) setColor(posi, "#fff", "black");
				else input = textfield.value;
				setColor(++posi, "blue", "white");
				textfield.value = outp.childNodes[posi].firstChild.nodeValue;
			}
		}
		else if (key == 38){ //Key up
			if (words.length > 0 && posi >= 0){
				if (posi >=1){
					setColor(posi, "#fff", "black");
					setColor(--posi, "blue", "white");
					textfield.value = outp.childNodes[posi].firstChild.nodeValue;
				}
				else{
					setColor(posi, "#fff", "black");
					textfield.value = input;
					textfield.focus();
					posi--;
				}
			}
		}
		else if (key == 27){ // Esc
			textfield.value = input;
			setVisible("hidden");
			posi = -1;
			oldins = input;
		}
		else if (key == 8){ // Backspace
			posi = -1;
			oldins=-1;
		}
		}
	}
	
	var mouseHandler=function(){
		for (var i=0; i < words.length; ++i)
			setColor (i, "white", "black");
	
		this.style.background = "blue";
		this.style.color= "white";
	}
	
	var mouseHandlerOut=function(){
		this.style.background = "white";
		this.style.color= "black";
	}
	
	var mouseClick=function(){
		document.getElementsByName("text")[0].value = this.firstChild.nodeValue;
		setVisible("hidden");
		posi = -1;
		oldins = this.firstChild.nodeValue;
	}
//-->
</script>
Css code:
<STYLE TYPE="text/css">
<!--
.output
{
	font-family:Arial;
	font-size: 10pt;
	color:black;
	padding-left: 3px;
	padding-top: 3px;
	border: 1px solid #000000;
	width: 100px;
	background: #fff;
}
.shadow
{
	width:102px;
	position:relative;
	top: 2px;
	left: 2px;
	background: #555;
}
.shadow div{
	position:relative;
	top: -2px;
	left: -2px;
}
-->
</STYLE>
html code for the Test:
<body onLoad="init();">
<form name="test" id="test">
<input type="text" name="text" autocomplete="off">
</form>
<div class="shadow" id="shadow">
<div class="output" id="output">
</div>
</div>
</body>
Good explanation about finding positions: http://www.quirksmode.org/js/findpos.html

I totally agree with you. SF

I totally agree with you. SF its getting worse. When you take a look at status bar, you see a static.
static

Case Insensitive Script

To become the script case insensitive just change this line:

if (suggestions[i].charAt(j) != beginning.charAt(j)) correct = 0;

to this code:

if (suggestions[i].charAt(j) != beginning.charAt(j).toLowerCase())
{
if (suggestions[i].charAt(j) != beginning.charAt(j).toUpperCase())
correct = 0;
}

The getWord function to case insentive:

function getWord(beginning){
var words = new Array();
for (var i=0;i

Additional Info

This is to populate text field in case enter key is pressed

else if (key == 13){ //Key ENTER
//alert (words);
textfield.value = outp.childNodes[posi].firstChild.nodeValue;
setVisible("hidden");
posi = -1;

}

Drupal Problem

Hi...

...Anybody knows how to use this code in drupal?
Thanks in advance for the help.

Code

Hi this code is good,but i think there is one small error in the code scripting that is provided in the Javascript file.

if (words.length > 0 && posi words.length-1){
if (posi >=0) setColor(posi, "#fff", "black");
else input = textfield.value;
setColor(++posi, "blue", "white");
textfield.value = outp.childNodes[posi].firstChild.nodeValue;
}

in the above code the if condition should have been

if (words.length > 0 && posi < words.length-1){

Hence the above code is throwing errors.

Thanks.

Add scroll bar

So in this script how can you add scroll bar? I was playing on the limitation of this script and I have 10's and thousand of list. Any ideas would really be helpful!

Thanks!

A question

Hi...
I saw the code and your input the code. I have a question on using this code in Drupal.
Would you please tell me how I can add this to a page content (body section) in a drupal?
I have included all the code in the body section and checked the full HTML option but still doesn't work.
Your answer will be much appreciated. Thanks a lot.

good really good

Thanks to given this example because i solve my problem using this logic( code )

Perfect

Perfect, this is almost what i was looking for!
great work.

Ajax is a headache for this, as large data search will kill the server.

Like it! can you not allow anything but

I really like this code.. but, how would you be able to set it so that the user can only input one of the available names? Not let them tab out of the box without selecting one of the drop down choices. Or have a pop-up letting them know that they need to select one of the suggested names.

I have a list of 2,475 names and I want them to be able start typing a child's name and then have the choices shrink as they type. Then only allow them to select one of the suggested names. If their child's name is not available maybe they can select a shorten name that is.

Willing to try suggestions from anybody.. not just the creator of this great code.

Very interesting, but static only

I was looking for that kind of program for something I'm working on, but I've never managed to make it fit with dynamic data (AJAX). It's not really easy to integrate so I simply gave up. It'd be interesting though.

Also, it would be a good idea to replace the missing symbol as a previous user pointed out ...

no Funciona

intente probar el ejemplo por todos los medios y sale que se esperaba un objeto no lo pude correr.

Wonderful

This is great, thank you for taking the time to compose this for us.

Missing < in line 127

In the script part is an error in line 127. You forgot a <.

question

is there a way to modify this script to work with multiple fields in the same form??