Hi

I have created a Textbox with a JS method that acts as Autocomplete.

For this I have used the onKeyup event that will send the current text in the textbox to my method. This works very well the first time, when I start entering the text the first time, but when I hit backspace to remove the present text completely and start entering text with a different letter, my code stops firing the onKeyUp event. Guess, I am doing something wrong.

Following is the code:

The TextBox Control
<div style="position:relative;overflow:visible">
<input type="text" name="searchfield" id="searchfield" autocomplete=off onkeyup="createAutoComplete(this.value, strSHPTListURL, strUserName, strPass, colList, language)">

The AutoComplete.Js file, this file has the createAutoComplete Method and other handlers (I took this code from here: http://www.webreference.com/programm...pt/gr/column5/) and modified it:
function AutoCompleteDB()
{
// set the initial values.
this.bEnd = false;
this.nCount = 0;
this.aStr = new Object;
}

AutoCompleteDB.prototype.add = function(str)
{
// increment the count value.
this.nCount++;

// if at the end of the string, flag this node as an end point.
if ( str == "" )
this.bEnd = true;
else
{
// otherwise, pull the first letter off the string
var letter = str.substring(0,1);
var rest = str.substring(1,str.length);

// and either create a child node for it or reuse an old one.
if ( !this.aStr[letter] ) this.aStr[letter] = new AutoCompleteDB();
this.aStr[letter].add(rest);
}
}

AutoCompleteDB.prototype.getCount = function(str, bExact)
{
// if end of search string, return number
if ( str == "" )
if ( this.bEnd && bExact && (this.nCount == 1) ) return 0;
else return this.nCount;

// otherwise, pull the first letter off the string
var letter = str.substring(0,1);
var rest = str.substring(1,str.length);

// and look for case-insensitive matches
var nCount = 0;
var lLetter = letter.toLowerCase();
if ( this.aStr[lLetter] )
nCount += this.aStr[lLetter].getCount(rest, bExact && (letter == lLetter));

var uLetter = letter.toUpperCase();
if ( this.aStr[uLetter] )
nCount += this.aStr[uLetter].getCount(rest, bExact && (letter == uLetter));

return nCount;
}

AutoCompleteDB.prototype.getStrings = function(str1, str2, outStr)
{
if ( str1 == "" )
{
// add matching strings to the array
if ( this.bEnd )
outStr.push(str2);

// get strings for each child node
for ( var i in this.aStr )
this.aStr[i].getStrings(str1, str2 + i, outStr);
}
else
{
// pull the first letter off the string
var letter = str1.substring(0,1);
var rest = str1.substring(1,str1.length);

// and get the case-insensitive matches.
var lLetter = letter.toLowerCase();
if ( this.aStr[lLetter] )
this.aStr[lLetter].getStrings(rest, str2 + lLetter, outStr);

var uLetter = letter.toUpperCase();
if ( this.aStr[uLetter] )
this.aStr[uLetter].getStrings(rest, str2 + uLetter, outStr);
}
}


function AutoComplete(aStr, oText, oDiv, nMaxSize)
{
// initialize member variables
this.oText = oText;
this.oDiv = oDiv;
this.nMaxSize = nMaxSize;

// preprocess the texts for fast access
this.db = new AutoCompleteDB();
var i, n = aStr.length;
for ( i = 0; i < n; i++ )
{
this.db.add(aStr[i]);
}

// attach handlers to the text-box
oText.AutoComplete = this;
oText.onkeyup = AutoComplete.prototype.onTextChange;
oText.onblur = AutoComplete.prototype.onTextBlur;
}

AutoComplete.prototype.onTextBlur = function()
{
this.AutoComplete.onblur();
}

AutoComplete.prototype.onblur = function()
{
this.oDiv.style.visibility = "hidden";
}

AutoComplete.prototype.onTextChange = function()
{
this.AutoComplete.onchange();
}

AutoComplete.prototype.onDivMouseDown = function()
{
this.AutoComplete.oText.value = this.innerHTML;
}

AutoComplete.prototype.onDivMouseOver = function()
{
this.className = "AutoCompleteHighlight";
}

AutoComplete.prototype.onDivMouseOut = function()
{
this.className = "AutoCompleteBackground";
}

AutoComplete.prototype.onchange = function()
{
var txt = this.oText.value;

// count the number of strings that match the text-box value
var nCount = this.db.getCount(txt, true);

// if a suitable number then show the popup-div
if ( (this.nMaxSize == -1 ) || ((nCount < this.nMaxSize) && (nCount > 0)) )
{
// clear the popup-div.
while ( this.oDiv.hasChildNodes() )
this.oDiv.removeChild(this.oDiv.firstChild);

// get all the matching strings from the AutoCompleteDB
var aStr = new Array();
this.db.getStrings(txt, "", aStr);

// add each string to the popup-div
var i, n = aStr.length;
for ( i = 0; i < n; i++ )
{
var oDiv = document.createElement('div');
this.oDiv.appendChild(oDiv);
oDiv.innerHTML = aStr[i];
oDiv.onmousedown = AutoComplete.prototype.onDivMouseDown;
oDiv.onmouseover = AutoComplete.prototype.onDivMouseOver;
oDiv.onmouseout = AutoComplete.prototype.onDivMouseOut;
oDiv.AutoComplete = this;
}
this.oDiv.style.visibility = "visible";
}
else // hide the popup-div
{
this.oDiv.innerHTML = "";
this.oDiv.style.visibility = "hidden";
}
}

function createAutoComplete(str, listURL, userName, password, listColumns, language)
{
if(str!="")
{
Sys.Net.WebServiceProxy.invoke('DataSource.asmx', 'GetSuggestions', false, {preText:str, strSHPTUrl: listURL, strUserName: userName, strPassword: password, listColumns: listColumns, pageLanguage: language}, oncreateAutoCompleteSucceeded, oncreateAutoCompleteFailed,null);
}
}

function oncreateAutoCompleteSucceeded(result)
{
new AutoComplete(
result,
document.getElementById('searchfield'),
document.getElementById('theDiv'),
25
);
}

function oncreateAutoCompleteFailed(){ alert("fail");}
As you can see, the createAutoCompelete method calls a webservice method GetSuggestions, it returns an array of matched strings. And then oncreateAutoCompleteSucceeded, creates a drop down with matched fields under my text box.

Now me being complete new to JS, I am not able to do the following:
1. The autocomplete pop down comes only after I enter 2 letters and doesnt start with just 1 letter. This is needed.
2. As I mentioned before, this works very well for the first time. This is what happens:

I start writing with the work W, the web method is called and then all the values starting from W are returned from my web method. Say it returns Worn, Wet, Work.

But, if I delete all the letter in the text box to make it empty. And I start typing with a new letter say A. Now this time, the web method is not called.

Can someone please look into it. Help me out.

The problem is I cannot use the ASP AJAX and I have to use a HTML Textbox. So, please help in either using the same code or if anything else can be done.