function AutoCompletion_getSelection (n, def)
{
for( i=0; i<10; i ++ )
{
var tr = document.getElementById( n + "tr" + i );
if ( tr == null )
return def;
else if ( tr.style.color == "#ffffff" )
return i;
}
return def;
}
function AutoCompletion_putSelection (n, s)
{
for( i=0; i<10; i ++ )
{
var tr = document.getElementById( n + "tr" + i );
if ( tr == null )
return;
if ( s == i )
{
tr.style.backgroundColor = "#0040D0";
tr.style.color = "#ffffff";
}
else
{
tr.style.backgroundColor = "#ffffff";
tr.style.color = "#000000";
}
}
}
function AutoCompletion_getNum (n)
{
var i;
for( i=0; i<10; i ++ )
{
var tr = document.getElementById( n + "tr" + i );
if ( tr == null )
return i;
}
return i;
}
function AutoCompletion_processResponse (n)
{
var req = document.getElementById( n + "div" ).req;
if ( req.readyState == 4 && req.status == 200 )
{
document.getElementById( n + "div" ).style.display = "block";
document.getElementById( n + "div" ).innerHTML = req.responseText;
}
}
function AutoCompletion_setEditText (n)
{
var sel = AutoCompletion_getSelection (n);
if ( sel == null )
return;
document.getElementById( n ).value = document.getElementById( n + "span" + sel ).innerHTML;
document.getElementById( n + "div" ).style.display = "none";
document.getElementById( n ).focus ();
}
function AutoCompletion_onEditBoxKey (n, key)
{
if ( key == 27 ) // esc.
{
document.getElementById( n + "div" ).style.display = "none";
event.returnValue = false;
return;
}
if ( key == 38 ) // up.
{
var s = AutoCompletion_getSelection (n, 0) - 1;
if ( s < 0 )
s = AutoCompletion_getNum(n) - 1;
AutoCompletion_putSelection( n, s );
event.returnValue = false;
}
else if ( key == 40 ) // down.
{
var s = AutoCompletion_getSelection (n, AutoCompletion_getNum(n)-1) + 1;
if ( s >= AutoCompletion_getNum (n) )
s = 0;
AutoCompletion_putSelection( n, s );
event.returnValue = false;
}
else if ( key == 13 ) // enter.
{
AutoCompletion_setEditText (n);
event.returnValue = false;
}
}
function encodeHtml ( s )
{
s = escape(s);
s = s.replace(/\//g,"%2F");
s = s.replace(/\?/g,"%3F");
s = s.replace(/=/g,"%3D");
s = s.replace(/&/g,"%26");
s = s.replace(/@/g,"%40");
return s;
}
function AutoCompletion_onEditBoxKeyChange (base, n, key)
{
if ( key == 8 || (key >= 32 && key != 38 && key != 40) )
{
var url = base + "?str=" + encodeHtml( document.getElementById( n ).value ) + "&rnd=" + Math.floor(Math.random()*1000000000) + "&n=" + n;
var req = new ActiveXObject("Microsoft.XMLHTTP");
document.getElementById( n + "div" ).req = req;
req.onreadystatechange = new Function ( "AutoCompletion_processResponse('" + n + "');" );
req.open ( "GET", url, true );
req.send ();
}
}
Di seguito è riportata una descrizione di ciascuna funzione JS:
AutoCompletion_getSelection: semplicemente ritorna l’indice dell’elemento attualmente selezionato nel box.
AutoCompletion_putSelection: seleziona un elemento nel box.
AutoCompletion_getNum: restituisce la dimensione del box, come numero di item attualmente visualizzati.
AutoCompletion_setEditText: in base alla selezione corrente nel box, popola l’editbox opportunamente.
AutoCompletion_onEditBoxKey (associata all’evento “onkeydown” dell’editbox): gestisce la pressione dei tasti quando il focus appartiene all’editbox (tasti: esc, su, giù, enter).
AutoCompletion_onEditBoxKeyChange (associata all’evento “onkeyup” dell’editbox): scatena una richiesta GET al server (attraverso l’oggetto "Microsoft.XMLHTTP") alla pressione di un tasto nell’editbox. Come specificato nell’evento “onreadystatechange”, la gestione della risposta da parte del server è demandata alla funzione JS con nome “AutoCompletion_processResponse”.
AutoCompletion_processResponse: questa funzione riceve la risposta del server. In questo caso, il server restituisce HTML (direttamente il contenuto del box di Auto-Completion). In altri casi è frequente trovare l’oggetto "Microsoft.XMLHTTP” coinvolto nello scambio di markup XML tra server e client (questo argomento, però, esula dagli obiettivi di questo post).
Dietro le quinte, una pagina ASPX si occupa di restituire il markup HTML che costituisce il box di Auto-Completion visualizzato. L’URL di tale pagina ASPX è fornito alla funzione “AutoCompletion_onEditBoxKeyChange” nel gestore dell’evento “onkeyup” del nostro INPUT TYPE=”TEXT” (ossia dell’editbox).
Il codice di questa pagina è scaricabile qui (AutoCompletionInterface.aspx (0,45 KB) + AutoCompletionInterface.aspx.cs (2,4 KB)). Il markup della pagina ASPX è trascurabile. La struttura del file di Code-Behind, invece, è molto intuitiva: nel gestore della Page_Load, viene generato dell’HTML secondo la stringa di ricerca passata (ossia ciò che l’utente ha inserito nell’editbox) quindi il markup risultante viene restituito come risposta alla GET della parte JS.
Tale markup verrà quindi visualizzato nella seconda DIV di cui sopra, mostrando il box di Auto-Completion: