// Auto suggestion javascript // Copyright TheDeal LLC 2008 // By Kevin Yan // 4/22/2008 // Default suggestions url ; var suggestUrl = baseHref; // Current Active Suggestion Object var CURRENT_SUG = null; // insert new DIV element into page for displaying suggestions document.write("
"); // if browser is IE, show IFRAME under DIV layer, to layer over SELECT elements if (navigator.appName == 'Microsoft Internet Explorer') { document.write(""); } // Simple Suggestion Object, contains id and value function TD_Suggestion (i, v) { this.id = i; this.value = v; } // Simple Cached Suggestions object, contains, keyword and saved suggestions function TD_CachedSuggestions () { this.text = ""; this.suggestions = []; } // Auto Suggestion object, with default settings. function TD_AutoSuggest (id) { this.id = id; // Id of text element this.element = document.getElementById(id); // element object reference this.url = suggestUrl; // URL for getting suggestions this.minLength = 2; // Minimum lenght of keyword for suggestions this.currentVal = ""; // Current keyword value this.highlited = -1; // Current highlited value from suggestion list this.cached = true; // Is caching turn on/off this.hideAfterAction = true; // hide suggestions if user clicked on highlited item this.highlitedItem = null; this.basicAction = null // Script action when 'Enter' is hit this.matchAction = null // Script action when Mouse Click this.suggestions = []; // Current list of suggestions TD_Suggestion objects this.cachedList = []; // Cached list of suggestions TD_CachedSuggestions objects this.requestObj; // AJAX request object reference var ME = this; // Self reference this.element.onkeypress = function(ev){ return ME.onKeyPress(ev); } // Handle key press event, capture 'ENTER' key before borwser finishs this.element.onkeyup = function(ev){ return ME.onKeyUp(ev); } // Handle key up event, } // Update element object TD_AutoSuggest.prototype.updateElement = function(id) { this.id = id; // Id of text element this.element = document.getElementById(id); // element object reference var ME = this; // Self reference this.element.onkeypress = function(ev){ return ME.onKeyPress(ev); } // Handle key press event, capture 'ENTER' key before borwser finishs this.element.onkeyup = function(ev){ return ME.onKeyUp(ev); } // Handle key up event, } // Handle Key Press event TD_AutoSuggest.prototype.onKeyPress = function(ev) { var key = (window.event) ? window.event.keyCode : ev.keyCode; var rtn = true; switch(key) { // Return key, set current highlited value to text box case 13: this.setHighlitedValue(); break; // Escape key, hide suggestions case 27: hideSuggestions(); break; } CURRENT_SUG = this; return rtn; } // Handle Key Up event TD_AutoSuggest.prototype.onKeyUp = function(ev) { var key = (window.event) ? window.event.keyCode : ev.keyCode; var rtn = true; switch(key) { // Return key, do nothing case 13: this.executeAction(); rtn = false; break; // Up key, move highlited value up case 38: this.hightLiteSuggestion(this.highlited - 1); rtn = false; break; // Down Key, move highlited value down case 40: this.hightLiteSuggestion(this.highlited + 1); rtn = false; break; // Default, get suggestions for current value default: this.getSuggestions(this.element.value); } CURRENT_SUG = this; return rtn; } // Get suggestions for current value TD_AutoSuggest.prototype.getSuggestions = function (val) { // Trim text value first val = val.replace(/^\s*|\s*$/g,""); // if no change in text, return if (val == this.currentVal) return false; // if text is less than required length, hide suggestions, then return if (val.length < this.minLength) { hideSuggestions(); return false; } this.currentVal = val; // Get cached suggestions if available var cachedSug = this.getCachedSuggestions(this.currentVal); if ( cachedSug == null ) { var p = this; try { // Firefox, Opera 8.0+, Safari this.requestObj = new XMLHttpRequest(); } catch (e) { // Internet Explorer try { this.requestObj = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { this.requestObj = new ActiveXObject("Microsoft.XMLHTTP"); } } // Open AJAX request object. var url = this.url + escape(this.currentVal); this.requestObj.onreadystatechange = function () { p.processReturnXML() }; this.requestObj.open("GET", url, true); this.requestObj.send(null); } else { // Display cached suggestions this.suggestions = cachedSug; this.showSuggestions(); } return false; } // Process return suggestion XML from server TD_AutoSuggest.prototype.processReturnXML = function () { if (this.requestObj.readyState == 4) { // only if "OK" if (this.requestObj.status == 200) { //this.onComplete( this.req ); var results = this.requestObj.responseXML.getElementsByTagName('results')[0].childNodes; // Create new list of suggestions var tempList = []; for (var i=0;i= this.minLength ) { var pos = getPosition(this.element); var sugDiv = document.getElementById('sugDiv'); // Create new table for display of suggestions var html = ""; for (var i=0; i" + tempVal.substring(tempHl, tempHl + this.currentVal.length) + "" + this.suggestions[i].value.substring(tempHl + this.currentVal.length); html += ""; } html += "
" + txt + "
Close
"; var sugDiv = document.getElementById('sugDiv'); sugDiv.innerHTML = html; // set position of suggestions DIV under text box sugDiv.style.display = ""; sugDiv.style.left = pos.x; sugDiv.style.top = pos.y + this.element.offsetHeight; sugDiv.style.width = this.element.offsetWidth; sugDiv.style.zIndex = 100; sugDiv.style.border = "solid 2px #000000"; // set position of layer IFRAME on IE, if needed var bgFrame = document.getElementById('sugBgFrame'); if ( bgFrame ) { bgFrame.style.left = pos.x; bgFrame.style.top = pos.y + this.element.offsetHeight; bgFrame.style.width = sugDiv.offsetWidth; bgFrame.style.height = sugDiv.offsetHeight; bgFrame.style.zIndex = sugDiv.style.zIndex -1; } } else { // Hide suggestions if text value is less than min length hideSuggestions(); } this.highlitedItem = null; } // Highlite suggestion with input index (val) TD_AutoSuggest.prototype.hightLiteSuggestion = function (val) { var tbl = document.getElementById('auto_sug_tbl').childNodes[0]; // Reset previous highlited background first if ( this.highlited >= 0 ) { var t = tbl.childNodes[this.highlited]; t.childNodes[0].style.backgroundColor = '#FFFFFF'; } // If index if less than -1, reset, for loop around if ( val < -1 ) { val = this.suggestions.length-1; } // Set current highlited background if ( val >= 0 && val < tbl.childNodes.length-1 ) { var t = tbl.childNodes[val]; t.childNodes[0].style.backgroundColor = '#DFE7DB'; this.highlited = val; } else { this.highlited = -1; } } // Set highlited value to text box, then hide suggestion DIV TD_AutoSuggest.prototype.setHighlitedValue = function () { if ( this.highlited >= 0 ) { this.highlitedItem = this.suggestions[this.highlited]; this.element.value = this.highlitedItem.value; this.highlited = -1; } if ( this.hideAfterAction ) hideSuggestions(); } // Get cached suggestions for input text TD_AutoSuggest.prototype.getCachedSuggestions = function (txt) { var rtn = null; // Check if CACHED is set to true, and if input text is OK if ( this.cached && txt.length >= this.minLength ) { for (var i=0; i= this.minLength ) { var temp = new TD_CachedSuggestions(); temp.text = txt; temp.suggestions = sug; this.cachedList.push(temp); } } TD_AutoSuggest.prototype.executeAction = function () { var a = this.basicAction; if ( this.highlitedItem != null ) { a = this.matchAction.replace(/#id#/g, this.highlitedItem.id); } if ( a != null ) { eval(a); } } // Hide suggestions DIV function hideSuggestions() { var sugDiv = document.getElementById('sugDiv'); if ( sugDiv ) { sugDiv.style.width = 0; sugDiv.style.zIndex = -1; sugDiv.style.border = "none"; sugDiv.style.display = "none"; } var bgFrame = document.getElementById('sugBgFrame'); if ( bgFrame ) { bgFrame.style.width = 0; bgFrame.style.height = 0; bgFrame.style.zIndex = -1; } } // Get page position of element function getPosition ( el ) { var cl = ct = 0; if (el.offsetParent) { while (el.offsetParent) { cl += el.offsetLeft; ct += el.offsetTop; el = el.offsetParent; } } else { cl = el.x; ct = el.y; } return {x:cl, y:ct} }