var __autoComplete__; function autoComplete(elementId) { /* variables */ this.maxResults = 10; this.delay = 100; this.url = ""; this.enabled = false; this.width = null; /* private variables */ this._xmlHttp; this._his = ''; this._selected = -1; this._searchCount = 0; this._searchResult = Array(); this._search_element; this._result_element; this.sr; /* constructor*/ if(elementId != undefined) { this._search_element = document.getElementById(elementId); } this.init = function(elementId) { this._search_element = document.getElementById(elementId); }; this.enable = function() { if(!this._search_element) return; if(this.enabled) return; var _this = this; this.sr = this.randomString(8); this._search_element.setAttribute('autocomplete', 'off'); this._search_element.onclick = function(e){ if(_this.validate()) _this.startTimer(); }; this._search_element.onkeydown = function(e) { // detect keycode var key = 0; if (!e) var e = window.event; if (e.keyCode) key = e.keyCode; else if (e.which) key = e.which; // can we? if(!_this.validate()){ _this.hideSearchElement(); return true; } // action per key switch (key) { case 27: // escape _this.hideSearchElement(); return false; break; case 38: // up arrow _this.prevSearch(); _this.updateSearch(); return false; break; case 40: // down arrow _this.nextSearch(); _this.updateSearch(); return false; break; case 13: // enter if( (!_this.searchIsHidden())&& (_this._selected != -1) ) { _this.setSelectedSearch(_this._selected); _this.hideSearchElement(); return false; } break; default: _this.startTimer(); break; } return true; }; // do we have a result element?? if(!this._result_element) { this._result_element = document.createElement('div'); this._result_element.setAttribute("id", this.randomString(8)); this._result_element.className = "search-results"; this._result_element.style.display = 'none'; document.body.appendChild(this._result_element); } __autoComplete__ = this; // nasty! if (this._search_element.addEventListener) this._search_element.addEventListener('blur', _this.searchBlur, false); else this._search_element.attachEvent("onblur", _this.searchBlur); if(window.addEventListener) window.addEventListener('resize', function(){_this.updateSearchPosition();}, false); else window.attachEvent('onresize', function(){_this.updateSearchPosition()}); this.enabled = true; }; this.disable = function() { if(!this.enabled) return; var _this = this; this.hideSearchElement(); this._search_element.removeAttribute('autocomplete'); this._search_element.onclick = function(){}; this._search_element.onkeydown = function(){}; if (this._search_element.addEventListener) this._search_element.removeEventListener('blur', _this.searchBlur, false); else this._search_element.detachEvent("onblur", _this.searchBlur); if(window.addEventListener) window.removeEventListener('resize', function(){_this.updateSearchPosition();}, false); else window.detachEvent('onresize', function(){_this.updateSearchPosition()}); this.enabled = false; if(this._result_element) { document.body.removeChild(this._result_element); this._result_element = null; } }; this.searchBlur = function() { if(this._selected) { if(this._selected == -1) this.hideSearchElement(); } else if(__autoComplete__) { if(__autoComplete__._selected == -1) __autoComplete__.hideSearchElement(); } }; this.validate = function() { /* bogus validate function, can overwrite var suggest = new autoComplete(); suggest.validate = function(){if(valid)return true; else return false;}; */ return true; }; this.onShow = function() { /* fired when search result box is showing... */ }; this.onHide = function() { /* fired when search result box is hiding... */ return true; }; this.timerExpired = function() { // validate value var value = this._search_element.value; if(value.length == 0) { this.hideSearchElement(); return; } if(value == this._his) { return; } this._his = value; var _this = this; var _url = this.url + escape(value); _url += "&limit=" + this.maxResults; _url += "&rand="+ Math.random(); this._xmlHttp = new window.XMLHttpRequest(); this._xmlHttp.open("GET",_url,true); this._xmlHttp.onreadystatechange = function() { if(_this._xmlHttp.readyState==4 && _this._xmlHttp.status == 200) { var response = eval('(' + _this._xmlHttp.responseText + ')'); if(response['succes'] == true) _this.process(response['data'], value); else alert(response['message']); } }; this._xmlHttp.send(null); }; this.process = function(data, searchValue) { var length = Math.min(data.length, this.maxResults); var _this = this; this._searchCount = length; this._result_element.innerHTML = ''; for (i=0; i"+searchValue+""); var divResCount= document.createElement('span'); divResCount.className = 'src'; if(data[i]['count']) { divResCount.innerHTML = data[i]['count'] + " resultaten"; } var divMain = document.createElement('div'); divMain.setAttribute("id", this.sr+"_"+i); divMain.className = 'sr'; divMain.onclick = function(){ _this.clickSearchElement()}; divMain.onmouseout = function(){_this.setSelectedSearch(-1);}; divMain.onmouseover = function(){var id = this.id.split('_');_this.setSelectedSearch(id[id.length-1]);}; divMain.appendChild(divValue); divMain.appendChild(divResCount); this._result_element.appendChild(divMain); } this._searchResult[-1] = {"naam" : searchValue}; if(length > 0) this.showSearchElement(); else this.hideSearchElement(); }; /* search element aanpassen */ this.hideSearchElement = function() { if(this._result_element) { if(this._result_element.style.display != 'none') { this._result_element.style.display = 'none'; this.onHide(); } } __autoComplete__ = null; // nasty! this._his = ""; this._selected = -1; this._searchCount = 0; this._searchResult = Array(); }; this.showSearchElement = function() { __autoComplete__ = this; // nasty! this._result_element.style.display = 'block'; this._search_element.focus(); this.updateSearchPosition(); this.updateSearchPosition(); this.onShow(); }; this.updateSearchPosition = function() { if(!this._result_element) return; var curleft = curtop = 0; var obj = this._search_element; if (obj.offsetParent) { curleft = obj.offsetLeft curtop = obj.offsetTop while (obj = obj.offsetParent) { curleft += obj.offsetLeft curtop += obj.offsetTop } } pos = [curleft,curtop]; this._result_element.style.top = pos[1] + this._search_element.offsetHeight + "px"; this._result_element.style.left = (1+pos[0]) + "px"; if(this.width == null) this._result_element.style.width = this._search_element.clientWidth + "px"; else this._result_element.style.width = this.width+"px"; }; this.prevSearch = function() { if(!this.searchIsHidden()) { this._selected-=1; if(this._selected < -1) this._selected = this._searchCount-1; this._search_element.value = this._searchResult[this._selected]['naam']; } else { this.startTimer(); } }; this.updateSearch = function() { for(k=0; k this._searchCount-1) this._selected = -1 //_selected = Math.min(_searchCount-1, _selected+1); this._search_element.value = this._searchResult[this._selected]['naam']; } else { this.startTimer()(); } }; this.searchIsHidden = function() { return this._result_element.style.display == 'none'; }; this.setSelectedSearch = function(id) { this._selected = id; this.updateSearch(); }; this.clickSearchElement = function() { this._search_element.value = this._searchResult[this._selected]['naam']; this.hideSearchElement(); }; /* helpers */ this.randomString = function(size) { var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz"; var string_length = 8; var randomstring = ''; if(size)string_length = size; for (var i=0; i 0) this.resetTimer(); var _this = this; this.tp = window.setTimeout(function(){_this.timerExpired();}, this.delay); }; this.resetTimer = function() { if (this.tp > 0) window.clearTimeout(this.tp); this.tp = 0; }; if (!window.XMLHttpRequest) { window.XMLHttpRequest = function() { var types = ['MSXML2.XMLHTTP.6.0', 'MSXML2.XMLHTTP.3.0']; for (var i = 0; i < types.length; i++) { try { return new ActiveXObject(types[i]); } catch(e) {} } return undefined; } } };