var autocomplete = new function () { var me = this; var inputNodes; var listContainerNode; var bodyNode; var minLength; var req; var currentLookupString = ""; var currentFocusedInputNode = null; var numberCurrentValues; var lastLookupString ="", lastLookupValues; me.values = null; me.x = -1; me.y = -1; me.init = function () { if (EventHelpers.hasPageLoadHappened(arguments)) return; bodyNode = document.getElementsByTagName('body')[0]; minLength = config.getIntegerValue('autocomplete.values.minLength', 0); createListContainerNode(); setInitialEvents(); } function createListContainerNode () { listContainerNode = document.createElement('div'); listContainerNode.style.display = 'none'; listContainerNode.style.position= 'absolute'; listContainerNode.id = 'autocomplete-selection' bodyNode.appendChild(listContainerNode); } function setInitialEvents () { inputNodes = CSSHelpers.getElementsByClassName(document, 'autocomplete_input'); for (var i=0; i 0) { firstListItemNode = listItemNodes[0] } else { firstListItemNode = listItemNodes; } jslog.debug('firstListItemNode: ' + firstListItemNode.nodeName) if (firstListItemNode) { switch (firstListItemNode.nodeName) { case "OPTION": //listNode.focus(); //jslog.debug(DebugHelpers.getProperties(firstListItemNode)); firstListItemNode.selected = 'selected'; replaceValue(firstListItemNode); listNode.focus(); break; } //firstListItemNode.focus(); } //jslog.debug('listNode properties: ' + DebugHelpers.getProperties(listNode)) } function getListEvent(e) { activeInputNode = EventHelpers.getEventTarget(e); currentLookupString=activeInputNode.value; if (currentLookupString.length < minLength) { listContainerNode.innerHTML = ""; return; } me.x = CSSHelpers.getAbsoluteLeft(activeInputNode); me.y = CSSHelpers.getAbsoluteTop(activeInputNode) + CSSHelpers.getHeight(activeInputNode); var id=activeInputNode.name.replace(/ /g, '_' ); var URL = config.getScriptedValue('autocomplete.urls.' + id, { inputID: id, inputValue: currentLookupString }); listContainerNode.innerHTML = config.getValue('autocomplete.templates.pleaseWait'); showAutocompleteBox(); /* * if this is not the old request with a few letters tacked on, * do an httpRequest to this. Otherwise, do call setValues(). */ if (lastLookupString != "" && currentLookupString.toLowerCase().indexOf(lastLookupString.toLowerCase()) == 0) { showDropDown(lastLookupValues); } else { if (req) { req.abort(); } req = XMLHelpers.getXMLHttpRequest(URL, getListRequest); } } function getListRequest() { if (!req) { //DebugHelpers.log("XMLHttpRequest was null: exiting"); return; } if (req.readyState == ReadyState.COMPLETED) { // only if "OK" if (req.status == HttpCode.OK) { var values = req.responseText.split('\n'); showDropDown(values); lastLookupString=currentLookupString; lastLookupValues=values; } } } function showDropDown(values) { removeAutocompleteBoxEvents(); me.setValues(values); jslog.debug(numberCurrentValues) if (numberCurrentValues == 0) { hideAutocompleteBox(); } else { jslog.debug('not zeri') setAutocompleteBoxEvents(); showAutocompleteBox(); } } me.setValues = function (values) { me.values = values; var lastElement = me.values.pop(); if (lastElement.trim() != "") { me.values.push(lastElement) } if (me.values.length == 0) { listContainerNode.innerHTML = ""; } else { var valuesHTMLSb = new StringBuffer(); numberCurrentValues = 0; for (var i = 0; i < me.values.length; i++) { var value = me.values[i].trim(); if (value != "" && value.toLowerCase().indexOf(currentLookupString.toLowerCase()) == 0 ) { numberCurrentValues++; valuesHTMLSb.append(config.getScriptedValue('autocomplete.templates.listItem', { listItem: me.values[i] })) } } listContainerNode.innerHTML = config.getScriptedValue('autocomplete.templates.list', { listItemsHTML: valuesHTMLSb.toString() }); } } function selectKeyEvent (e) { var key = EventHelpers.getKey(e); switch(key){ case CharCode.ESC: case CharCode.ENTER: hideAutocompleteBox(e); currentFocusedInputNode.focus(); break; case CharCode.TAB: focusOnInputField(e); break; case CharCode.BACKSPACE: currentFocusedInputNode.value = ""; hideAutocompleteBox(e); currentFocusedInputNode.focus(); // prevents browser from going back a page. EventHelpers.preventDefault(e); break; } } function focusOnInputField(e) { currentFocusedInputNode.focus(); if (BrowserDetect.browser == "Explorer") { EventHelpers.preventDefault(e); } } function showAutocompleteBox () { CSSHelpers.moveTo(listContainerNode, me.x, me.y) listContainerNode.style.display = 'block'; } function hideAutocompleteBox(e) { listContainerNode.style.display = 'none'; removeAutocompleteBoxEvents(); listContainerNode.innerHTML = ''; } function getListItemNodes () { var valueNodes = cssQuery( config.getValue('autocomplete.selectors.listItem'), listContainerNode ); return valueNodes; } function getListNode () { var listNodes = cssQuery( config.getValue('autocomplete.selectors.list'), listContainerNode ); if (listNodes && listNodes.length > 0) { return listNodes[0]; } else { return null; } } function setAutocompleteBoxEvents() { var valueNodes = getListItemNodes(); var listNode = getListNode(); if (listNode) { EventHelpers.addEvent(listNode, 'change', replaceValueEvent); EventHelpers.addEvent(listNode, 'blur', hideAutocompleteBox); EventHelpers.addEvent(listNode, 'keyup', selectKeyEvent); EventHelpers.addEvent(listNode, 'keydown', selectKeyEvent); EventHelpers.addEvent(listNode, 'blur', focusOnInputField); } if (valueNodes) { for (var i = 0; i < valueNodes.length; i++) { EventHelpers.addEvent(valueNodes[i], 'click', replaceValueEvent); } } } function removeAutocompleteBoxEvents() { var valueNodes = getListItemNodes(); var listNode = getListNode(); if (listNode) { EventHelpers.removeEvent(listNode, 'change', replaceValueEvent); EventHelpers.removeEvent(listNode, 'blur', hideAutocompleteBox); } if (valueNodes) { for (var i = 0; i < valueNodes.length; i++) { EventHelpers.removeEvent(valueNodes[i], 'click', replaceValueEvent); } } } function replaceValueEvent(e){ var valueNode = EventHelpers.getEventTarget(e); replaceValue(valueNode) } function replaceValue(valueNode) { var value = valueNode.value; jslog.debug(valueNode.value); if (!value) { value = valueNode.innerHTML; } activeInputNode.value = value; } function turnOffNativeAutocomplete(formNode) { formNode.setAttribute('autocomplete', 'off'); } } EventHelpers.addPageLoadEvent('autocomplete.init');