/*
*/ // ****************** // THESE VARS _MUST_ BE DEFINED IN CALLING PAGE!!!! // ___AFTER___ INCLUDING THIS FILE // ****************** var ajaxpage = '/searchlist.php'; var search_field = 'search'; // shortcut var for clearing the similars list function clearSimilars (f) { f.listbox.style.display = 'none'; while (f.list.hasChildNodes()) { f.list.removeChild(f.list.lastChild); } } // do the actual search list box drawing after we have the list function drawSimilars (f, similarslist) { // have to reset each time we redraw the list // and clean out any existing list items f.idx = -1; clearSimilars(f); // build the html for each similar for (var i = 0; i < similarslist.length; i++) { // this is the line item for this term // but we need to make sure it's not disabled var sLI = document.createElement('li'); sLI.listDisabled = (similarslist[i].count > 0 ? false : true); // if this line item is disabled, it lacks mousing features if (!sLI.listDisabled) { // create a mousing version of the up/down arrow key highlighting sLI.listIndex = i; sLI.onmouseover = function() { highlightSimilar(f, 'f.idx = '+this.listIndex+';'); } // create a link to use the mouse directly to these results var sLIa = document.createElement('a'); sLIa.innerHTML = similarslist[i].term; sLIa.setAttribute('href', similarslist[i].url); sLI.appendChild(sLIa); } // if disabled, the text goes directly into the line item else { sLI.innerHTML = similarslist[i].term; } // add this line item to the list f.list.appendChild(sLI); } // and finally display it f.listbox.style.display = 'block'; } // send this value to the server to get the similars list function showSimilars (e, f)// + '/' + vCode { sendAJAXrequest(ajaxpage, function (data) { drawSimilars(f, data); }, 't=' + encodeURIComponent(f.box.value)); } // hide/remove the similars list function hideSimilars (e, f) { // we have to delay for a split second, // in case this comes from a click on one of the links // (the click will only get looked for after the blur happens // and without the box there, the click never happens!) // HOWEVER, this creates a new problem: obj ceases to exist // if the page changes, so we need the try/catch setTimeout(function() { try { if (f.list) { clearSimilars(f); } } catch (r) {} }, 100); } // turn off current highlighting, highlight new item function highlightSimilar (f, edgecode) { // unhighlight the old item if (f.idx >= 0) { f.list.childNodes[f.idx].className = ''; } // try the next/prev item, but if it's disabled, // go one more until you find an undisabled one in the list // NOTE: if the eval comes after orig assignment, // you'll crash the browser when nothing is selected yet (origIndex == -1) eval(edgecode); origIndex = f.idx; while (f.list.childNodes[f.idx].listDisabled) { eval(edgecode); if (origIndex == f.idx) { break; } } // make sure we found an undisabled item in the list if (!f.list.childNodes[f.idx].listDisabled) { f.list.childNodes[f.idx].className = 'similarsHighlight'; f.box.value = f.list.childNodes[f.idx].lastChild.innerHTML; f.url_link = f.list.childNodes[f.idx].lastChild.href; } // these arrow keystrokes should be ignored return false; } // highlight previous item function prevSimilar (f) { return highlightSimilar(f, 'if (--f.idx < 0) { f.idx = f.list.childNodes.length-1; }'); } // highlight next item function nextSimilar (f) { return highlightSimilar(f, 'if (++f.idx >= f.list.childNodes.length) { f.idx = 0; }'); } // take action on keystrokes in searchbox function checkSearchKeys (e, f) { // generic IE compatibility if (!e) { e = window.event; } // up/down step through similars if (e.keyCode == 38) { return prevSimilar(f); } // up if (e.keyCode == 40) { return nextSimilar(f); } // down // all other keys pressed BUT ENTER should be processed if (e.keyCode != 13) { showSimilars(e, f); } // enter tells us to load that option, if an option has been selected if (e.keyCode == 13 && typeof(f.url_link) != 'undefined') { window.location = f.url_link; } // normal keystrokes should definitely be allowed return true; } // closure making func -- easier to pass dynamic html objects to event handlers // might need this: http://laurens.vd.oever.nl/weblog/items2005/closures/ function eventClosure (func, obj) { return function (e) { func(e, obj); }; } function SimilarsSearchBox (idName) { // get the search input box this.box = document.getElementById(idName); this.box.style.display = 'block'; // list index tracking var this.idx = 0; // create the actual space where the similars get shown this.listbox = document.createElement('div'); this.listbox.className = 'searchlistbox'; // the list where all the suggestions go this.list = document.createElement('ul'); this.list.className = 'nonlist'; clearSimilars(this); // initialize it empty // now put the list and listbox on to the page this.listbox.appendChild(this.list); this.box.parentNode.appendChild(this.listbox); // assign all the event handlers this.box.onfocus = eventClosure(showSimilars, this); this.box.onblur = eventClosure(hideSimilars, this); this.box.onkeyup = eventClosure(checkSearchKeys, this); }