// autocomplete and related changes // Copyright 2004 Leslie A. Hensley // hensleyl@papermountain.org // you have a license to do what ever you like with this code // orginally from Avi Bryant // http://www.cincomsmalltalk.com/userblogs/avi/blogView?entry=3268075684 // modified for 'autocomplete for zip codes at unizo.be' by Johan Reynaert if (navigator.userAgent.indexOf("Safari") > 0) { isSafari = true; isMoz = false; isIE = false; } else if (navigator.product == "Gecko") { isSafari = false; isMoz = true; isIE = false; } else { isSafari = false; isMoz = false; isIE = true; } function AutocompletePostcode(id) { function liveUpdater(uriFunc, postFunc, preFunc){ if(!postFunc) postFunc = function () {}; if(!preFunc) preFunc = function () {}; //actually not used var request = null; function removeChildren(parentElement){ for(var i = parentElement.childNodes.length-1; i>=0; i--) parentElement.removeChild(parentElement.childNodes[i]); } function update() { request = new XMLHttpRequest(); //important to make a new request --> this needs XMLHttpRequest-script preFunc(); request.onreadystatechange = processRequestChange; request.open("GET", uriFunc()); request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=ISO-8859-1'); request.send(null); return true; } function processRequestChange(){ if (request.readyState == 4 && (request.status == 200 || request.status == 304)){ var xmlDoc = request.responseXML //via nodes naar li (met id attribute) var result = getNode(xmlDoc,'result'); var popup = gEBI(getNodeValue(result,'id')+'_popup'); var postcodes = getNode(result,"postcodes"); if(postcodes.childNodes.length>0){ removeChildren(popup); //remove all 'options' in popup var cell_ul = document.createElement("ul"); //just for styling and IE ;( popup.appendChild(cell_ul); for(var i=0;i= 0) separator = "&"; return uri + separator + "s=" + escape(inputField.value)+'&id='+id+'&popupId='+popupId+'&noCache='+new Date().getTime(); } function hidePopup(){ popup.style.visibility = 'hidden'; } function handlePopupOver(){ removeListener(inputField, 'blur', hidePopup); } function handlePopupOut(){ if(popup.style.visibility == 'visible') addListener(inputField, 'blur', hidePopup); } function handleClick(e){ inputField.value = eventElement(e).innerHTML; if (inputFieldHidden) inputFieldHidden.value = eventElement(e).id; ////ja en welke optionvalue zit in attrib id popup.style.visibility = 'hidden'; inputField.focus(); } function handleOver(e){ options[current].className = ''; current = eventElement(e).index; options[current].className = 'selected'; } function post(){ current = 0; options = popup.getElementsByTagName("li"); if((options.length > 1) || (options.length == 1 && options[0].innerHTML != inputField.value)){ setPopupStyles(); for(var i = 0; i < options.length; i++){ options[i].index = i; addOptionHandlers(options[i]); } options[0].className = 'selected'; } else { popup.style.visibility = 'hidden'; } } function setPopupStyles(){ var maxHeight if(isIE){ maxHeight = 200; popup.style.left = '0px'; popup.style.top = (originalPopupTop + inputField.offsetHeight) + 'px'; } else { popup.style.top = (originalPopupTop + inputField.offsetHeight) + 'px'; //na aanpassingen voor IE8 maxHeight = window.outerHeight/3; } if(popup.offsetHeight < maxHeight) { popup.style.overflow = 'hidden'; } else if(isMoz) { popup.style.maxHeight = maxHeight + 'px'; popup.style.overflow = '-moz-scrollbars-vertical'; } else { popup.style.height = maxHeight + 'px'; popup.style.overflowY = 'auto'; } popup.scrollTop = 0; popup.style.visibility = 'visible'; } function addOptionHandlers(option) { addListener(option, "click", handleClick); addListener(option, "mouseover", handleOver); } function start(e) { if (timeout) window.clearTimeout(timeout); if(e.keyCode == 38){ //up arrow if(current > 0){ options[current].className = ''; current--; options[current].className = 'selected'; options[current].scrollIntoView(false); } } else if(e.keyCode == 40) { //down arrow if(current < options.length - 1){ options[current].className = ''; current++; options[current].className = 'selected'; options[current].scrollIntoView(false); } } else if((e.keyCode == 13 || e.keyCode == 9) && popup.style.visibility == 'visible') { //enter or tab inputField.value = options[current].innerHTML; //en ook hidden veld voor submit if (inputFieldHidden) inputFieldHidden.value = options[current].id; popup.style.visibility = 'hidden'; inputField.focus(); if(isIE){ event.returnValue = false; } else { e.preventDefault(); } } else { //no keys timeout = window.setTimeout(updater, 300); } } /* Functions to handle browser incompatibilites */ function eventElement(event){ if(isMoz) return event.currentTarget; else return event.srcElement; } function addKeyListener(element, listener){ if (isSafari) element.addEventListener("keydown",listener,false); else if (isMoz) element.addEventListener("keypress",listener,false); else element.attachEvent("onkeydown",listener); } function addListener(element, type, listener){ if(element.addEventListener) element.addEventListener(type, listener, false); else element.attachEvent('on' + type, listener); } function removeListener(element, type, listener){ if(element.removeEventListener) element.removeEventListener(type, listener, false); else element.detachEvent('on' + type, listener); } /* some shortcuts */ this.getNodeValue = function (el,name){ if (el.getElementsByTagName(name)[0].firstChild == null) return ''; else return el.getElementsByTagName(name)[0].firstChild.nodeValue; } this.setInner = function(el,value){ if (document.getElementById(el)) document.getElementById(el).innerHTML = value; } this.setValue = function (el,value){ if (document.getElementById(el)) document.getElementById(el).value = value; } this.getNode = function(el,name){ return el.getElementsByTagName(name)[0]; } this.getNodes = function(el,name){ return el.getElementsByTagName(name); } this.gEBI = function(el){ return document.getElementById(el); } this.setInner = function(el,value){ if (document.getElementById(el)) document.getElementById(el).innerHTML = value; } var inputField = gEBI(id); var popupId = id+'_popup'; var popup = gEBI(popupId); var inputFieldHidden = gEBI(id+'_h'); var options = new Array(); var current = 0; var originalPopupTop = popup.offsetTop; //where is the xml to query var uri = '/scripts/classes/kmonet/xml/regio/Postcode.getGemeentes.jsp'; //start the show var updater = liveUpdater(constructUri, post); var timeout = false; //listen to the client addKeyListener(inputField, start); addListener(popup, 'mouseover', handlePopupOver); addListener(popup, 'mouseout', handlePopupOut); };