From af0be8f9546fb5dec947be33e465bb6d9e85d0a7 Mon Sep 17 00:00:00 2001 From: Andreas Unterkircher Date: Thu, 27 Mar 2008 22:59:06 +0100 Subject: issue111, first try of auto completion for tag search box Signed-off-by: Andreas Unterkircher --- autocomplete/js/acdropdown.js | 1622 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1622 insertions(+) create mode 100644 autocomplete/js/acdropdown.js (limited to 'autocomplete/js/acdropdown.js') diff --git a/autocomplete/js/acdropdown.js b/autocomplete/js/acdropdown.js new file mode 100644 index 0000000..c5ad240 --- /dev/null +++ b/autocomplete/js/acdropdown.js @@ -0,0 +1,1622 @@ +// +// This script was created +// by Mircho Mirev +// mo /mo@momche.net/ +// Copyright (c) 2004-2005 Mircho Mirev +// +// :: feel free to use it BUT +// :: if you want to use this code PLEASE send me a note +// :: and please keep this disclaimer intact +// + +function cAutocomplete( sInputId ) +{ + this.init( sInputId ) +} + +cAutocomplete.CS_NAME = 'Autocomplete component' +cAutocomplete.CS_OBJ_NAME = 'AC_COMPONENT' +cAutocomplete.CS_LIST_PREFIX = 'ACL_' +cAutocomplete.CS_BUTTON_PREFIX = 'ACB_' +cAutocomplete.CS_INPUT_PREFIX = 'AC_' +cAutocomplete.CS_HIDDEN_INPUT_PREFIX = 'ACH_' +cAutocomplete.CS_INPUT_CLASSNAME = 'dropdown' + +cAutocomplete.CB_AUTOINIT = true + +cAutocomplete.CB_AUTOCOMPLETE = false + +cAutocomplete.CB_FORCECORRECT = false + +//the separator when autocompleting multiple values +cAutocomplete.CB_MATCHSUBSTRING = false +cAutocomplete.CS_SEPARATOR = ',' + +//the separator of associative arrays +cAutocomplete.CS_ARRAY_SEPARATOR = ',' + +//match the input string only against the begining of the strings +//or anywhere in the string +cAutocomplete.CB_MATCHSTRINGBEGIN = true + +cAutocomplete.CN_OFFSET_TOP = 2 +cAutocomplete.CN_OFFSET_LEFT = -1 + +cAutocomplete.CN_LINE_HEIGHT = 19 +cAutocomplete.CN_NUMBER_OF_LINES = 10 +cAutocomplete.CN_HEIGHT_FIX = 2 + +cAutocomplete.CN_CLEAR_TIMEOUT = 300 +cAutocomplete.CN_SHOW_TIMEOUT = 400 +cAutocomplete.CN_REMOTE_SHOW_TIMEOUT = 1000 +cAutocomplete.CN_MARK_TIMEOUT = 400 + +cAutocomplete.hListDisplayed = null +cAutocomplete.nCount = 0 + +cAutocomplete.autoInit = function() +{ + var nI = 0 + var hACE = null + var sLangAtt + + for( nI = 0; nI < document.getElementsByTagName( 'INPUT' ).length; nI++ ) + { + if( document.getElementsByTagName( 'INPUT' )[ nI ].type.toLowerCase() == 'text' ) + { + sLangAtt = document.getElementsByTagName( 'INPUT' )[ nI ].getAttribute( 'acdropdown' ) + if( sLangAtt != null && sLangAtt.length > 0 ) + { + if( document.getElementsByTagName( 'INPUT' )[ nI ].id == null || document.getElementsByTagName( 'INPUT' )[ nI ].id.length == 0 ) + { + document.getElementsByTagName( 'INPUT' )[ nI ].id = cAutocomplete.CS_OBJ_NAME + cAutocomplete.nCount + } + hACE = new cAutocomplete( document.getElementsByTagName( 'INPUT' )[ nI ].id ) + } + } + } + + var nTALength = document.getElementsByTagName( 'TEXTAREA' ).length + for( nI = 0; nI < nTALength; nI++ ) + { + sLangAtt = document.getElementsByTagName( 'TEXTAREA' )[ nI ].getAttribute( 'acdropdown' ) + if( sLangAtt != null && sLangAtt.length > 0 ) + { + if( document.getElementsByTagName( 'TEXTAREA' )[ nI ].id == null || document.getElementsByTagName( 'TEXTAREA' )[ nI ].id.length == 0 ) + { + document.getElementsByTagName( 'TEXTAREA' )[ nI ].id = cAutocomplete.CS_OBJ_NAME + cAutocomplete.nCount + } + hACE = new cAutocomplete( document.getElementsByTagName( 'TEXTAREA' )[ nI ].id ) + } + } + + + var nSelectsLength = document.getElementsByTagName( 'SELECT' ).length + var aSelect = null + for( nI = 0; nI < nSelectsLength; nI++ ) + { + aSelect = document.getElementsByTagName( 'SELECT' )[ nI ] + sLangAtt = aSelect.getAttribute( 'acdropdown' ) + if( sLangAtt != null && sLangAtt.length > 0 ) + { + if( aSelect.id == null || aSelect.id.length == 0 ) + { + aSelect.id = cAutocomplete.CS_OBJ_NAME + cAutocomplete.nCount + } + hACE = new cAutocomplete( aSelect.id ) + nSelectsLength-- + nI-- + } + } +} + +if( cAutocomplete.CB_AUTOINIT ) +{ + if( window.attachEvent ) + { + window.attachEvent( 'onload', cAutocomplete.autoInit ) + } + else if( window.addEventListener ) + { + window.addEventListener( 'load', cAutocomplete.autoInit, false ) + } +} + +cAutocomplete.prototype.init = function( sInputId ) +{ + this.sInputId = sInputId + this.sListId = cAutocomplete.CS_LIST_PREFIX + sInputId + + this.sObjName = cAutocomplete.CS_OBJ_NAME + '_obj_' + (cAutocomplete.nCount++) + this.hObj = this.sObjName + + this.hActiveSelection = null + this.nSelectedItemIdx = -1 + + //the value of the input before the list is displayed + this.sLastActiveValue = '' + this.sActiveValue = '' + this.bListDisplayed = false + this.nItemsDisplayed = 0 + + //if I transform a select option or the supplied array is associative I create a hidden input + //with the name of the original input and replace the original input's name + this.bAssociative = false + this.sHiddenInputId = null + this.bHasButton = false + + //the actual data + this.aData = null + //the search array object + this.aSearchData = new Array() + this.bSorted = false + + //the length of the last matched typed string + this.nLastMatchLength = 0 + + this.bForceCorrect = cAutocomplete.CB_FORCECORRECT + var sForceCorrect = document.getElementById( this.sInputId ).getAttribute( 'autocomplete_forcecorrect' ) + if( sForceCorrect != null && sForceCorrect.length > 0 ) + { + this.bForceCorrect = eval( sForceCorrect ) + } + + //match a only from the beginning or anywhere in the values + this.bMatchBegin = cAutocomplete.CB_MATCHSTRINGBEGIN + var sMatchBegin = document.getElementById( this.sInputId ).getAttribute( 'autocomplete_matchbegin' ) + if( sMatchBegin != null && sMatchBegin.length > 0 ) + { + this.bMatchBegin = eval( sMatchBegin ) + } + //match substrings separated by cAutocomplete.CS_SEPARATOR + this.bMatchSubstring = cAutocomplete.CB_MATCHSUBSTRING + var sMatchSubstring = document.getElementById( this.sInputId ).getAttribute( 'autocomplete_matchsubstring' ) + if( sMatchSubstring != null && sMatchSubstring.length > 0 ) + { + this.bMatchSubstring = true + } + + //autocomplete with the first option from the list + this.bAutoComplete = cAutocomplete.CB_AUTOCOMPLETE + this.bAutocompleted = false + var sAutoComplete = document.getElementById( this.sInputId ).getAttribute( 'autocomplete_complete' ) + if( sAutoComplete != null && sAutoComplete.length > 0 ) + { + this.bAutoComplete = eval( sAutoComplete ) + } + //format function + this.formatOptions = null + var sFormatFunction = document.getElementById( this.sInputId ).getAttribute( 'autocomplete_format' ) + if( sFormatFunction != null && sFormatFunction.length > 0 ) + { + this.formatOptions = eval( sFormatFunction ) + } + //onselect callback function - get called when a new option is selected, either by changing the focus in the list by using the keyboard or by + //clicking on it with the mouse + this.onSelect = null + var sOnSelectFunction = document.getElementById( this.sInputId ).getAttribute( 'autocomplete_onselect' ) + if( sOnSelectFunction != null && sOnSelectFunction.length > 0 ) + { + this.onSelect = eval( sOnSelectFunction ) + } + + //onchange callback function - get called when a new option is selected by clicking on it or by pressing enter + //almost the same as onselect, but will get activated on + /* + this.onChange = null + var sOnSelectFunction = document.getElementById( this.sInputId ).getAttribute( 'autocomplete_onselect' ) + if( sOnSelectFunction != null && sOnSelectFunction.length > 0 ) + { + this.onSelect = eval( sOnSelectFunction ) + } + */ + + //I assume that we always have the associative type + //you can turn it off only with the autocomplete_assoc=false attribute + this.bAssociative = true + var sAssociative = document.getElementById( this.sInputId ).getAttribute( 'autocomplete_assoc' ) + if( sAssociative != null && sAssociative.length > 0 ) + { + if( sAssociative == 'false' ) + { + this.bAssociative = false + } + } + + //if we have remote list then we postpone the list creation + if( this.getListArrayType() != 'url' ) + { + this.bRemoteList = false + } + else + { + this.bRemoteList = true + this.sListURL = this.getListURL() + this.hXMLHttp = XmlHttp.create() + } + this.initListArray() + this.initListContainer() + //this.createList() + this.initInput() + + eval( this.hObj + '= this' ) +} + +cAutocomplete.prototype.initInput = function() +{ + var hInput = document.getElementById( this.sInputId ) + hInput.hAutocomplete = this + var hContainer = document.getElementById( this.sListId ) + hContainer.hAutocomplete = this + + //any element ( and it's children ) with display:none have offset values of 0 ( in mozilla ) + var nWidth = hInput.offsetWidth + if( !nWidth || nWidth == 0 ) + { + //any element ( and it's children ) with display:none have offset values of 0 ( in mozilla ) + var hOWInput = hInput.cloneNode( true ) + hOWInput.style.position = 'absolute' + hOWInput.style.top = '-1000px' + document.body.appendChild( hOWInput ) + var nWidth = hOWInput.offsetWidth + document.body.removeChild( hOWInput ) + } + + var sInputName = hInput.name + var hForm = hInput.form + var bHasButton = false + var sHiddenValue = hInput.value + var sValue = hInput.type.toLowerCase() == 'text' ? hInput.value : '' + + var sHasButton = hInput.getAttribute( 'autocomplete_button' ) + if( sHasButton != null && sHasButton.length > 0 ) + { + bHasButton = true + } + + //if it is a select - I unconditionally add a button + if( hInput.type.toLowerCase() == 'select-one' ) + { + bHasButton = true + if( hInput.selectedIndex >= 0 ) + { + sHiddenValue = hInput.options[ hInput.selectedIndex ].value + sValue = hInput.options[ hInput.selectedIndex ].text + } + } + + //this is the case when the control is a transformed select or the list supplied is of the type - key,value not only values + if( hForm ) + { + var hHiddenInput = document.createElement( 'INPUT' ) + hHiddenInput.id = cAutocomplete.CS_HIDDEN_INPUT_PREFIX + this.sInputId + hHiddenInput.type = 'hidden' + hForm.appendChild( hHiddenInput ) + + if( this.bAssociative ) + { + hHiddenInput.name = sInputName + hInput.name = cAutocomplete.CS_INPUT_PREFIX + sInputName + } + else + { + hHiddenInput.name = cAutocomplete.CS_INPUT_PREFIX + sInputName + } + + hHiddenInput.value = sHiddenValue + this.sHiddenInputId = hHiddenInput.id + } + + if( bHasButton ) + { + this.bHasButton = true + + var hInputContainer = document.createElement( 'DIV' ) + hInputContainer.className = 'acinputContainer' + hInputContainer.style.width = nWidth + + var hInputButton = document.createElement( 'INPUT' ) + hInputButton.id = cAutocomplete.CS_BUTTON_PREFIX + this.sInputId + hInputButton.type = 'button' + hInputButton.className = 'button' + hInputButton.tabIndex = hInput.tabIndex + 1 + hInputButton.hAutocomplete = this + + var hNewInput = document.createElement( 'INPUT' ) + if( this.bAssociative ) + { + hNewInput.name = cAutocomplete.CS_INPUT_PREFIX + sInputName + } + else + { + hNewInput.name = sInputName + } + + hNewInput.type = 'text' + hNewInput.value = sValue + hNewInput.style.width = nWidth-22 + hNewInput.className = cAutocomplete.CS_INPUT_CLASSNAME + hNewInput.tabIndex = hInput.tabIndex + hNewInput.hAutocomplete = this + + hInputContainer.appendChild( hNewInput ) + hInputContainer.appendChild( hInputButton ) + + hInput.parentNode.replaceChild( hInputContainer, hInput ) + + hNewInput.id = this.sInputId + hInput = hNewInput + } + + if( hInput.attachEvent ) + { + hInput.attachEvent( 'onkeyup', cAutocomplete.onInputKeyUp ) + hInput.attachEvent( 'onkeyup', cAutocomplete.saveCaretPosition ) + hInput.attachEvent( 'onkeydown', cAutocomplete.onInputKeyDown ) + hInput.attachEvent( 'onblur', cAutocomplete.onInputBlur ) + hInput.attachEvent( 'onfocus', cAutocomplete.onInputFocus ) + + if( hInputButton ) + { + hInputButton.attachEvent( 'onclick', cAutocomplete.onButtonClick ) + } + } + else if( hInput.addEventListener ) + { + hInput.addEventListener( 'keyup', cAutocomplete.onInputKeyUp, false ) + hInput.addEventListener( 'keyup', cAutocomplete.saveCaretPosition, false ) + hInput.addEventListener( 'keydown', cAutocomplete.onInputKeyDown, false ) + hInput.addEventListener( 'keypress', cAutocomplete.onInputKeyPress, false ) + hInput.addEventListener( 'blur', cAutocomplete.onInputBlur, false ) + hInput.addEventListener( 'focus', cAutocomplete.onInputFocus, false ) + + if( hInputButton ) + { + hInputButton.addEventListener( 'click', cAutocomplete.onButtonClick, false ) + } + } + + //I don't need the standard autocomplete + hInput.setAttribute( 'autocomplete', 'OFF' ) + + if( hForm ) + { + if( hForm.attachEvent ) + { + hForm.attachEvent( 'onsubmit', cAutocomplete.onFormSubmit ) + } + else if( hForm.addEventListener ) + { + hForm.addEventListener( 'submit', cAutocomplete.onFormSubmit, false ) + } + } +} + +cAutocomplete.prototype.initListContainer = function() +{ + var hInput = document.getElementById( this.sInputId ) + var hContainer = document.createElement( 'DIV' ) + hContainer.className = 'autocomplete_holder' + hContainer.id = this.sListId + hContainer.style.zIndex = 10000 + cAutocomplete.nCount + hContainer.hAutocomplete = this + + var hFirstBorder = document.createElement( 'DIV' ) + hFirstBorder.className = 'autocomplete_firstborder' + var hSecondBorder = document.createElement( 'DIV' ) + hSecondBorder.className = 'autocomplete_secondborder' + + var hList = document.createElement( 'UL' ) + hList.className = 'autocomplete' + + hSecondBorder.appendChild( hList ) + hFirstBorder.appendChild( hSecondBorder ) + hContainer.appendChild( hFirstBorder ) + document.body.appendChild( hContainer ) + + if( hContainer.attachEvent ) + { + hContainer.attachEvent( 'onblur', cAutocomplete.onListBlur ) + hContainer.attachEvent( 'onfocus', cAutocomplete.onListFocus ) + } + else if( hInput.addEventListener ) + { + hContainer.addEventListener( 'blur', cAutocomplete.onListBlur, false ) + hContainer.addEventListener( 'focus', cAutocomplete.onListFocus, false ) + } + + + if( hContainer.attachEvent ) + { + hContainer.attachEvent( 'onclick', cAutocomplete.onItemClick ) + } + else if( hContainer.addEventListener ) + { + hContainer.addEventListener( 'click', cAutocomplete.onItemClick, false ) + } +} + +cAutocomplete.prototype.createList = function() +{ + var hInput = document.getElementById( this.sInputId ) + var hContainer = document.getElementById( this.sListId ) + var hList = hContainer.getElementsByTagName( 'UL' )[0] + if( hList ) + { + hList = hList.parentNode.removeChild( hList ) + while( hList.hasChildNodes() ) + { + hList.removeChild( hList.childNodes[ 0 ] ) + } + } + + var hListItem = null + var hListItemLink = null + var hArrKey = null + var sArrEl = null + + var hArr = this.aData + var nI = 0 + var sRealText + for( hArrKey in hArr ) + { + sArrEl = hArr[ hArrKey ] + hListItem = document.createElement( 'LI' ) + hListItemLink = document.createElement( 'A' ) + hListItemLink.setAttribute( 'itemvalue', hArrKey ) + + /* so you can attach data to the element */ + /* it's a hack but seems to work */ + if(sArrEl.split) { + var sArrData = sArrEl.split( cAutocomplete.CS_ARRAY_SEPARATOR ) + if( sArrData.length > 1 ) + { + this.aData[ hArrKey ] = sArrData[ 0 ] + hListItemLink.setAttribute( 'itemdata', sArrEl.substring( sArrEl.indexOf( cAutocomplete.CS_ARRAY_SEPARATOR ) + 1 ) ) + sRealText = sArrData[ 0 ] + } + else + { + sRealText = sArrEl + } + /* end of attach data to the element */ + + hListItemLink.href = '#' + hListItemLink.appendChild( document.createTextNode( sRealText ) ) + hListItemLink.realText = sRealText + if( nI == this.nSelectedItemIdx ) + { + this.hActiveSelection = hListItemLink + this.hActiveSelection.className = 'selected' + } + hListItem.appendChild( hListItemLink ) + hList.appendChild( hListItem ) + this.aSearchData[ nI++ ] = sRealText.toLowerCase() + } + } + var hSecondBorder = hContainer.firstChild.firstChild + hSecondBorder.appendChild( hList ) + this.bListUpdated = false +} + +/* list array functions */ + +cAutocomplete.prototype.initListArray = function() +{ + var hInput = document.getElementById( this.sInputId ) + var hArr = null + + if( hInput.type.toLowerCase() == 'select-one' ) + { + hArr = new Object() + for( var nI = 0; nI < hInput.options.length; nI++ ) + { + hArrKey = hInput.options.item( nI ).value + sArrEl = hInput.options.item( nI ).text + hArr[ hArrKey ] = sArrEl + if( hInput.options.item( nI ).selected ) + { + this.nSelectedItemIdx = nI + } + } + } + else + { + var sAA = hInput.getAttribute( 'autocomplete_list' ) + var sAAS = hInput.getAttribute( 'autocomplete_list_sort' ) + + var sArrayType = this.getListArrayType() + + switch( sArrayType ) + { + case 'array' : hArr = eval( sAA.substring( 6 ) ) + break + + case 'list' : hArr = new Array() + var hTmpArray = sAA.substring( 5 ).split( '|' ) + var aValueArr + for( hKey in hTmpArray ) + { + aValueArr = hTmpArray[ hKey ].split( cAutocomplete.CS_ARRAY_SEPARATOR ) + if( aValueArr.length == 1 ) + { + hArr[ hKey ] = hTmpArray[ hKey ] + this.bAssociative = false + } + else + { + hArr[ aValueArr[ 0 ] ] = aValueArr[ 1 ] + } + } + break + } + if( sAAS != null && eval( sAAS ) ) + { + this.bSorted = true + this.aData = hArr.sort() + hArr = hArr.sort() + } + } + this.setArray( hArr ) +} + +cAutocomplete.prototype.setArray = function( sArray ) +{ + if( typeof sArray == 'string' ) + { + this.aData = eval( sArray ) + } + else + { + this.aData = sArray + } + this.bListUpdated = true +} + +//use this function to change the list of autocomplete values to a new one +//supply as an argument the name as a literal of an JS array object +//well things changed - you can supply an actual array too +cAutocomplete.prototype.setListArray = function( sArray ) +{ + this.setArray( sArray ) + this.updateAndShowList() +} + +cAutocomplete.prototype.getListArrayType = function() +{ + var hInput = document.getElementById( this.sInputId ) + var sAA = hInput.getAttribute( 'autocomplete_list' ) + if( sAA != null && sAA.length > 0 ) + { + if( sAA.indexOf( 'array:' ) >= 0 ) + { + return 'array' + } + else if( sAA.indexOf( 'list:' ) >= 0 ) + { + return 'list' + } + else if( sAA.indexOf( 'url:' ) >= 0 ) + { + return 'url' + } + } +} + +cAutocomplete.prototype.getListURL = function() +{ + var hInput = document.getElementById( this.sInputId ) + var sAA = hInput.getAttribute( 'autocomplete_list' ) + if( sAA != null && sAA.length > 0 ) + { + if( sAA.indexOf( 'url:' ) >= 0 ) + { + return sAA.substring( 4 ) + } + } +} + +cAutocomplete.prototype.setListURL = function( sURL ) +{ + this.sListURL = sURL; +} + +cAutocomplete.prototype.onXmlHttpLoad = function() +{ + if( this.hXMLHttp.readyState == 4 ) + { + var hError = this.hXMLHttp.parseError + if( hError && hError.errorCode != 0 ) + { + alert( hError.reason ) + } + else + { + this.afterRemoteLoad() + } + } +} + +cAutocomplete.prototype.loadListArray = function() +{ + var sURL = this.sListURL + var sStartWith = this.getStringForAutocompletion( this.sActiveValue, this.nInsertPoint ) + sStartWith = sStartWith.replace( /^\s/, '' ) + sStartWith = sStartWith.replace( /\s$/, '' ) + if( sURL.indexOf( '[S]' ) >= 0 ) + { + sURL = sURL.replace( '[S]', sStartWith ) + } + else + { + sURL += this.sActiveValue + } + this.hXMLHttp.open( 'GET', sURL, true ) + + var hAC = this + this.hXMLHttp.onreadystatechange = function() { hAC.onXmlHttpLoad() } + this.hXMLHttp.send( null ) +} + +cAutocomplete.prototype.afterRemoteLoad = function() +{ + var hInput = document.getElementById( this.sInputId ) + + var hArr = new Array() + var hTmpArray = this.hXMLHttp.responseText.split( '|' ) + var aValueArr + for( hKey in hTmpArray ) + { + if(hTmpArray[ hKey ].split) { + aValueArr = hTmpArray[ hKey ].split( cAutocomplete.CS_ARRAY_SEPARATOR ) + if( aValueArr.length == 1 ) + { + hArr[ hKey ] = hTmpArray[ hKey ] + } + else + { + hArr[ aValueArr[ 0 ] ] = hTmpArray[ hKey ].substr( hTmpArray[ hKey ].indexOf( cAutocomplete.CS_ARRAY_SEPARATOR ) + 1 ) + } + } + } + + hInput.className = '' + hInput.readonly = false + hInput.value = this.sActiveValue + this.setListArray( hArr ) +} + +/**/ + +cAutocomplete.prototype.prepareList = function( bFullList ) +{ + var hInput = document.getElementById( this.sInputId ) + this.sActiveValue = hInput.value + if( this.bRemoteList ) + { + hInput.readonly = true + } + + //check if this was invoked by a key that did not change the value + var sST = this.getStringForAutocompletion( this.sActiveValue, this.nInsertPoint ) + var sLST = this.getStringForAutocompletion( this.sLastActiveValue, this.nInsertPoint ) + + if( sLST != sST || bFullList || !this.bListDisplayed || this.bMatchSubstring ) + { + if( this.bRemoteList ) + { + hInput.className = 'search' + hInput.value = 'please wait...' + this.loadListArray() + return + } + this.updateAndShowList( bFullList ) + } +} + +cAutocomplete.prototype.updateAndShowList = function( bFullList ) +{ + var hContainer = document.getElementById( this.sListId ) + var hList = hContainer.getElementsByTagName( 'UL' )[ 0 ] + var hInput = document.getElementById( this.sInputId ) + + if( this.bListUpdated ) + { + this.createList() + } + + //stupid hack just for speed + var sST = this.bMatchSubstring ? this.getStringForAutocompletion( this.sActiveValue, this.nInsertPoint ) : this.sActiveValue + var sLST = this.bMatchSubstring ? this.getStringForAutocompletion( this.sLastActiveValue, this.nInsertPoint ) : this.sLastActiveValue + + //nothing changed since last type - maybe only function keys were pressed + //this is the case when for example the down key was pressed + if( sST == sLST ) + { + if( !this.bMatchSubstring ) + { + bFullList = true + } + } + this.filterOptions( bFullList ) + + if( this.nItemsDisplayed == 0 ) + { + if( this.bForceCorrect ) + { + var aPos = this.getInsertPos( this.sActiveValue, this.nInsertPoint, '' ) + cAutocomplete.markInputRange( hInput, this.nLastMatchLength, aPos[0] ) + } + } + + this.sLastActiveValue = this.sActiveValue + + if( this.nItemsDisplayed > 0 ) + { + if( !bFullList || this.bMatchSubstring ) + { + this.deselectOption() + } + if( this.bAutoComplete && this.nItemsDisplayed == 1 ) + { + //test if we have a full match i.e. the user typed the entire value + var sStartWith = this.getStringForAutocompletion( this.sActiveValue, this.nInsertPoint ) + var sItemText = hList.getElementsByTagName( 'LI' )[ this.nFirstDisplayed ].getElementsByTagName( 'A' )[ 0 ].realText + if( sStartWith.toLowerCase() == sItemText.toLowerCase() ) + { + this.selectOption( hList.getElementsByTagName( 'LI' )[ this.nFirstDisplayed ].getElementsByTagName( 'A' )[ 0 ] ) + this.hideOptions() + //and do not show the list + return + } + } + if( this.bAutoComplete && !bFullList ) + { + this.selectOption( hList.getElementsByTagName( 'LI' )[ this.nFirstDisplayed ].getElementsByTagName( 'A' )[ 0 ] ) + } + this.showList() + } + else + { + this.clearList() + } +} + +cAutocomplete.prototype.showList = function() +{ + if( cAutocomplete.hListDisplayed ) + { + cAutocomplete.hListDisplayed.clearList() + } + var hInput = document.getElementById( this.sInputId ) + var nTop = cDomObject.getOffsetParam( hInput, 'offsetTop' ) + var nLeft = cDomObject.getOffsetParam( hInput, 'offsetLeft' ) + var hContainer = document.getElementById( this.sListId ) + + var hList = hContainer.getElementsByTagName( 'UL' )[ 0 ] + if( this.bHasButton ) + { + hContainer.style.width = document.getElementById( this.sInputId ).parentNode.offsetWidth + } + else + { + hContainer.style.width = document.getElementById( this.sInputId ).offsetWidth + } + var nNumLines = ( this.nItemsDisplayed < cAutocomplete.CN_NUMBER_OF_LINES ) ? this.nItemsDisplayed : cAutocomplete.CN_NUMBER_OF_LINES; + hList.style.height = nNumLines * cAutocomplete.CN_LINE_HEIGHT + cAutocomplete.CN_HEIGHT_FIX + 'px' + + hContainer.style.top = nTop + hInput.offsetHeight + cAutocomplete.CN_OFFSET_TOP + 'px' + hContainer.style.left = nLeft + cAutocomplete.CN_OFFSET_LEFT + 'px' + + hContainer.style.display = 'none' + hContainer.style.visibility = 'visible' + hContainer.style.display = 'block' + + cAutocomplete.hListDisplayed = this + this.bListDisplayed = true +} + +cAutocomplete.prototype.binarySearch = function( sFilter ) +{ + var nLow = 0 + var nHigh = this.aSearchData.length - 1 + var nMid + var nTry, nLastTry + var sData + var nLen = sFilter.length + + var lastTry + + while ( nLow <= nHigh ) + { + nMid = ( nLow + nHigh ) / 2 + nTry = ( nMid < 1 ) ? 0 : parseInt( nMid ) + + sData = this.aSearchData[ nTry ].substr( 0, nLen ) + + if ( sData < sFilter ) + { + nLow = nTry + 1 + continue + } + if ( sData > sFilter ) + { + nHigh = nTry - 1 + continue + } + if ( sData == sFilter ) + { + nHigh = nTry - 1 + nLastTry = nTry + continue + } + return nTry + } + + if ( typeof ( nLastTry ) != "undefined" ) + { + return nLastTry + } + else + { + return null + } +} + +cAutocomplete.prototype.getStringForAutocompletion = function( sString, nPos ) +{ + if( sString == null || sString.length == 0 ) + { + return '' + } + if( this.bMatchSubstring ) + { + var nStartPos = sString.lastIndexOf( cAutocomplete.CS_SEPARATOR, nPos - 1 ) + nStartPos = nStartPos < 0 ? 0 : nStartPos + var nEndPos = sString.indexOf( cAutocomplete.CS_SEPARATOR, nPos ) + nEndPos = nEndPos < 0 ? sString.length : nEndPos + var sStr = sString.substr( nStartPos, nEndPos - nStartPos ) + sStr = sStr.replace( /^(\,?)(\s*)(\S*)(\s*)(\,?)$/g, '$3' ) + return sStr + } + else + { + return sString + } +} + +cAutocomplete.prototype.insertString = function( sString, nPos, sInsert ) +{ + if( this.bMatchSubstring ) + { + var nStartPos = sString.lastIndexOf( cAutocomplete.CS_SEPARATOR, nPos - 1 ) + nStartPos = nStartPos < 0 ? 0 : nStartPos + var nEndPos = sString.indexOf( cAutocomplete.CS_SEPARATOR, nPos ) + nEndPos = nEndPos < 0 ? sString.length : nEndPos + var sStr = sString.substr( nStartPos, nEndPos - nStartPos ) + sStr = sStr.replace( /^(\,?)(\s*)(\S?[\S\s]*\S?)(\s*)(\,?)$/g, '$1$2'+sInsert+'$4$5' ) + sStr = sString.substr( 0, nStartPos ) + sStr + sString.substr( nEndPos ) + return sStr + } + else + { + return sInsert + } +} + +cAutocomplete.prototype.getInsertPos = function( sString, nPos, sInsert ) +{ + nPos = nPos == null ? 0 : nPos + var nStartPos = sString.lastIndexOf( cAutocomplete.CS_SEPARATOR, nPos - 1 ) + nStartPos = nStartPos < 0 ? 0 : nStartPos + var nEndPos = sString.indexOf( cAutocomplete.CS_SEPARATOR, nPos ) + nEndPos = nEndPos < 0 ? sString.length : nEndPos + var sStr = sString.substr( nStartPos, nEndPos - nStartPos ) + sStr = sStr.replace( /^(\,?)(\s*)(\S?[\S\s]*\S?)(\s*)(\,?)$/g, '$1$2'+sInsert ) + return [ nPos, nStartPos + sStr.length ] +} + +cAutocomplete.prototype.filterOptions = function( bShowAll ) +{ + if( this.hActiveSelection && !bShowAll ) + { + this.hActiveSelection.className = '' + } + if( typeof bShowAll == 'undefined' ) + { + bShowAll = false + } + + var hInput = document.getElementById( this.sInputId ) + + var sStartWith = this.getStringForAutocompletion( this.sActiveValue, this.nInsertPoint ) + if( bShowAll ) + { + sStartWith = '' + } + + var hContainer = document.getElementById( this.sListId ) + var hList = hContainer.getElementsByTagName( 'UL' )[ 0 ] + var nItemsLength = hList.childNodes.length + var hLinkItem = null + var nCount = 0 + + var hParent = hList.parentNode + var hList = hList.parentNode.removeChild( hList ) + var hTItems = hList.childNodes + + this.nItemsDisplayed = 0 + + if( sStartWith.length == 0 ) + { + for( var nI = 0; nI < nItemsLength; nI++ ) + { + if( this.formatOptions ) + { + hTItems[ nI ].childNodes[0].innerHTML = this.formatOptions( hTItems[ nI ].childNodes[0].realText, nI ) + } + hTItems[ nI ].style.display = 'block' + } + + nCount = nItemsLength + + if( nItemsLength > 0 ) + { + this.nFirstDisplayed = 0 + this.nLastDisplayed = nItemsLength - 1 + } + else + { + this.nFirstDisplayed = this.nLastDisplayed = -1 + } + + //this.nLastMatchLength = 0 + var aPos = this.getInsertPos( this.sActiveValue, this.nInsertPoint, sStartWith ) + this.nLastMatchLength = aPos[0] + } + else + { + this.nFirstDisplayed = this.nLastDisplayed = -1 + sStartWith = sStartWith.toLowerCase() + var bEnd = false + if( this.bSorted && this.bMatchBegin ) + { + var nStartAt = this.binarySearch( sStartWith ) + for( var nI = 0; nI < nItemsLength; nI++ ) + { + hTItems[ nI ].style.display = 'none' + if( nI >= nStartAt && !bEnd ) + { + if( !bEnd && this.aSearchData[ nI ].indexOf( sStartWith ) != 0 ) + { + bEnd = true + continue + } + if( this.formatOptions ) + { + hTItems[ nI ].childNodes[0].innerHTML = this.formatOptions( hTItems[ nI ].childNodes[0].realText, nI ) + } + hTItems[ nI ].style.display = 'block' + nCount++ + if( this.nFirstDisplayed < 0 ) + { + this.nFirstDisplayed = nI + } + this.nLastDisplayed = nI + } + } + } + else + { + for( var nI = 0; nI < nItemsLength; nI++ ) + { + hTItems[ nI ].style.display = 'none' + if( ( this.bMatchBegin && this.aSearchData[ nI ].indexOf( sStartWith ) == 0 ) || ( !this.bMatchBegin && this.aSearchData[ nI ].indexOf( sStartWith ) >= 0 ) ) + { + if( this.formatOptions ) + { + hTItems[ nI ].childNodes[0].innerHTML = this.formatOptions( hTItems[ nI ].childNodes[0].realText, nI ) + } + hTItems[ nI ].style.display = 'block' + nCount++ + if( this.nFirstDisplayed < 0 ) + { + this.nFirstDisplayed = nI + } + this.nLastDisplayed = nI + } + } + } + + if( nCount > 0 ) + { + //this.nLastMatchLength = this.sActiveValue.length + var aPos = this.getInsertPos( this.sActiveValue, this.nInsertPoint, sStartWith ) + this.nLastMatchLength = aPos[0] + } + } + hParent.appendChild( hList ) + this.nItemsDisplayed = nCount +} + +cAutocomplete.prototype.hideOptions = function() +{ + var hContainer = document.getElementById( this.sListId ) + hContainer.style.visibility = 'hidden' + hContainer.style.display = 'none' + cAutocomplete.hListDisplayed = null +} + +cAutocomplete.prototype.markAutocompletedValue = function() +{ + var hInput = document.getElementById( this.sInputId ) + var sValue = this.hActiveSelection.realText + if( this.bMatchSubstring ) + { + var aPos = this.getInsertPos( this.sLastActiveValue, this.nInsertPoint, sValue ) + var nStartPos = aPos[ 0 ] + var nEndPos = aPos[ 1 ] + } + else + { + var nStartPos = this.nInsertPoint + var nEndPos = sValue.length + } + this.nStartAC = nStartPos + this.nEndAC = nEndPos + + if( this.hMarkRangeTimeout != null ) + { + clearTimeout( this.hMarkRangeTimeout ) + } + this.hMarkRangeTimeout = setTimeout( function() { + cAutocomplete.markInputRange2( hInput.id ) + } + , cAutocomplete.CN_MARK_TIMEOUT ) + //cAutocomplete.markInputRange( hInput, nStartPos, nEndPos ) +} + +cAutocomplete.prototype.selectOptionByIndex = function( nOptionIndex ) +{ + if( this.bListUpdated ) + { + this.createList() + } + + var hContainer = document.getElementById( this.sListId ) + var hList = hContainer.getElementsByTagName( 'UL' )[ 0 ] + var nItemsLength = hList.childNodes.length + if( nOptionIndex >=0 && nOptionIndex < nItemsLength ) + { + this.selectOption( hList.childNodes[ nOptionIndex ].getElementsByTagName( 'A' )[ 0 ] ) + } +} + +cAutocomplete.prototype.selectOptionByValue = function( sValue ) +{ + if( this.bListUpdated ) + { + this.createList() + } + + sValue = sValue.toLowerCase() + + var hContainer = document.getElementById( this.sListId ) + var hList = hContainer.getElementsByTagName( 'UL' )[ 0 ] + var nItemsLength = hList.childNodes.length + + var nSelectedIndex = -1 + for( var nI = 0; nI < nItemsLength; nI++ ) + { + if( this.aSearchData[ nI ].indexOf( sValue ) == 0 ) + { + nSelectedIndex = nI + } + } + if( nSelectedIndex >=0 ) + { + this.selectOption( hList.childNodes[ nSelectedIndex ].getElementsByTagName( 'A' )[ 0 ] ) + } +} + +cAutocomplete.prototype.selectOption = function( hNewOption ) +{ + if( this.hActiveSelection ) + { + if( this.hActiveSelection == hNewOption ) + { + return + } + else + { + this.hActiveSelection.className = '' + } + } + this.hActiveSelection = hNewOption + var hInput = document.getElementById( this.sInputId ) + if( this.hActiveSelection != null ) + { + if( this.sHiddenInputId != null ) + { + if( this.bMatchSubstring ) + { + document.getElementById( this.sHiddenInputId ).value = this.hActiveSelection.getAttribute( 'itemvalue' ) + } + else + { + document.getElementById( this.sHiddenInputId ).value = this.hActiveSelection.getAttribute( 'itemvalue' ) + } + } + + this.hActiveSelection.className = 'selected' + if( this.bAutoComplete ) + { + hInput.value = this.insertString( this.sLastActiveValue, this.nInsertPoint, this.hActiveSelection.realText ) + this.bAutocompleted = true + this.markAutocompletedValue() + } + else + { + var aPos = this.getInsertPos( this.sLastActiveValue, this.nInsertPoint, this.hActiveSelection.realText ) + hInput.value = this.insertString( this.sActiveValue, this.nInsertPoint, this.hActiveSelection.realText ) + //cAutocomplete.setInputCaretPosition( hInput, this.nInsertPoint ) + cAutocomplete.setInputCaretPosition( hInput, aPos[ 1 ] ) + } + + this.sActiveValue = hInput.value + + if( this.onSelect ) + { + this.onSelect() + } + } + else + { + hInput.value = this.sActiveValue + cAutocomplete.setInputCaretPosition( hInput, this.nInsertPoint ) + } +} + +cAutocomplete.prototype.deselectOption = function( ) +{ + if( this.hActiveSelection != null ) + { + this.hActiveSelection.className = '' + this.hActiveSelection = null + } +} + +cAutocomplete.prototype.clearList = function() +{ + //this.deselectOption() + this.hideOptions() + this.bListDisplayed = false +} + +cAutocomplete.prototype.getPrevDisplayedItem = function( hItem ) +{ + if( hItem == null ) + { + var hContainer = document.getElementById( this.sListId ) + hItem = hContainer.getElementsByTagName( 'UL' )[ 0 ].childNodes.item( hContainer.getElementsByTagName( 'UL' )[ 0 ].childNodes.length - 1 ) + } + else + { + hItem = getPrevNodeSibling( hItem.parentNode ) + } + while( hItem != null ) + { + if( hItem.style.display == 'block' ) + { + return hItem + } + hItem = hItem.previousSibling + } + return null +} + +cAutocomplete.prototype.getNextDisplayedItem = function( hItem ) +{ + if( hItem == null ) + { + var hContainer = document.getElementById( this.sListId ) + hItem = hContainer.getElementsByTagName( 'UL' )[ 0 ].childNodes.item( 0 ) + } + else + { + hItem = getNextNodeSibling( hItem.parentNode ) + } + while( hItem != null ) + { + if( hItem.style.display == 'block' ) + { + return hItem + } + hItem = hItem.nextSibling + } + return null +} + +cAutocomplete.onInputKeyDown = function ( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + var hAC = hElement.hAutocomplete + var hContainer = document.getElementById( hAC.sListId ) + var hInput = document.getElementById( hAC.sInputId ) + var hList = hContainer.getElementsByTagName( 'UL' )[ 0 ] + var hEl = getParentByTagName( hElement, 'A' ) + if( hContainer != null && hAC.bListDisplayed ) + { + var hLI = null + var hLINext = null + //the new active selection + if( ( hEvent.keyCode == 13 ) || ( hEvent.keyCode == 27 ) ) + { + var bItemSelected = hEvent.keyCode == 13 ? true : false + hAC.clearList() + } + if( hEvent.keyCode == 38 ) + { + //up key pressed + hLINext = hAC.getPrevDisplayedItem( hAC.hActiveSelection ) + if( hLINext != null ) + { + hAC.selectOption( hLINext.childNodes.item(0) ) + if( hAC.nItemsDisplayed > cAutocomplete.CN_NUMBER_OF_LINES ) + { + if( hList.scrollTop < 5 && hLINext.offsetTop > hList.offsetHeight ) + { + hList.scrollTop = hList.scrollHeight - hList.offsetHeight + } + if( hLINext.offsetTop - hList.scrollTop < 0 ) + { + hList.scrollTop -= hLINext.offsetHeight + } + } + } + else + { + hAC.selectOption( null ) + } + } + else if ( hEvent.keyCode == 40 ) + { + //down key pressed + hLINext = hAC.getNextDisplayedItem( hAC.hActiveSelection ) + if( hLINext != null ) + { + hAC.selectOption( hLINext.childNodes.item(0) ) + if( hAC.nItemsDisplayed > cAutocomplete.CN_NUMBER_OF_LINES ) + { + if( hList.scrollTop > 0 && hList.scrollTop > hLINext.offsetTop ) + { + hList.scrollTop = 0 + } + if( Math.abs( hLINext.offsetTop - hList.scrollTop - hList.offsetHeight ) < 5 ) + { + hList.scrollTop += hLINext.offsetHeight + } + } + } + else + { + hAC.selectOption( null ) + } + } + } + if( hInput.form ) + { + hInput.form.bLocked = true + } + if ( hEvent.keyCode == 13 || hEvent.keyCode == 27 || hEvent.keyCode == 38 || hEvent.keyCode == 40 ) + { + if( hEvent.preventDefault ) + { + hEvent.preventDefault() + } + hEvent.cancelBubble = true + hEvent.returnValue = false + return false + } +} + +cAutocomplete.onInputKeyPress = function ( hEvent ) +{ + if ( hEvent.keyCode == 13 || hEvent.keyCode == 38 || hEvent.keyCode == 40 ) + { + if( hEvent.preventDefault ) + { + hEvent.preventDefault() + } + hEvent.cancelBubble = true + hEvent.returnValue = false + return false + } +} + +cAutocomplete.onInputKeyUp = function ( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + var hAC = hElement.hAutocomplete + var hInput = document.getElementById( hAC.sInputId ) + //if we press the keys for up down enter or escape skip showing the list + switch( hEvent.keyCode ) + { + case 8 : if( hAC.bAutoComplete && hAC.bAutocompleted ) + { + hAC.bAutocompleted = false + return false + } + break + case 38 : + case 40 : if( hAC.bListDisplayed ) + { + if( hEvent.preventDefault ) + { + hEvent.preventDefault() + } + hEvent.cancelBubble = true + hEvent.returnValue = false + return false + } + break + case 13 : + case 32 : + case 46 : + //case 37 : + //case 39 : + case 35 : + case 36 : break; + default : if( hEvent.keyCode < 48 ) + { + if( hEvent.preventDefault ) + { + hEvent.preventDefault() + } + hEvent.cancelBubble = true + hEvent.returnValue = false + return false + } + break + } + + if( hAC.hMarkRangeTimeout != null ) + { + clearTimeout( hAC.hMarkRangeTimeout ) + } + + if( hAC.hShowTimeout ) + { + clearTimeout( hAC.hShowTimeout ) + hAC.hShowTimeout = null + } + var nTimeout = hAC.bRemoteList ? cAutocomplete.CN_REMOTE_SHOW_TIMEOUT : cAutocomplete.CN_SHOW_TIMEOUT + hAC.hShowTimeout = setTimeout( function(){ hAC.prepareList() }, nTimeout ) +} + +cAutocomplete.onInputBlur = function( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + if( hElement.form ) + { + hElement.form.bLocked = false + } + var hAC = hElement.hAutocomplete + if( !hAC.hClearTimeout ) + { + hAC.hClearTimeout = setTimeout( function(){ hAC.clearList() }, cAutocomplete.CN_CLEAR_TIMEOUT ) + } +} + +cAutocomplete.onInputFocus = function( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + var hAC = hElement.hAutocomplete + if( hAC.hClearTimeout ) + { + clearTimeout( hAC.hClearTimeout ) + hAC.hClearTimeout = null + } +} + +cAutocomplete.saveCaretPosition = function( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + var hAC = hElement.hAutocomplete + var hInput = document.getElementById( hAC.sInputId ) + + //there is something weird about hitting up and down keys in a textarea + if( hEvent.keyCode != 38 && hEvent.keyCode != 40 ) + { + hAC.nInsertPoint = cAutocomplete.getInputCaretPosition( hInput ) + } +} + +cAutocomplete.getInputCaretPosition = function( hInput ) +{ + if( typeof hInput.selectionStart != 'undefined' ) + { + if( hInput.selectionStart == hInput.selectionEnd ) + { + return hInput.selectionStart + } + else + { + return hInput.selectionStart + } + } + else if( hInput.createTextRange ) + { + var hSelRange = document.selection.createRange() + if( hInput.tagName.toLowerCase() == 'textarea' ) + { + var hSelBefore = hSelRange.duplicate() + var hSelAfter = hSelRange.duplicate() + hSelRange.moveToElementText( hInput ) + hSelBefore.setEndPoint( 'StartToStart', hSelRange ) + return hSelBefore.text.length + } + else + { + hSelRange.moveStart( 'character', -1*hInput.value.length ) + var nLen = hSelRange.text.length + return nLen + } + } + return null +} + +cAutocomplete.setInputCaretPosition = function( hInput, nPosition ) +{ + if ( hInput.setSelectionRange ) + { + hInput.setSelectionRange( nPosition ,nPosition ) + } + else if ( hInput.createTextRange ) + { + var hRange = hInput.createTextRange() + hRange.moveStart( 'character', nPosition ) + hRange.moveEnd( 'character', nPosition ) + hRange.collapse(true) + hRange.select() + } +} + +cAutocomplete.markInputRange = function( hInput, nStartPos, nEndPos ) +{ + if( hInput.setSelectionRange ) + { + hInput.focus() + hInput.setSelectionRange( nStartPos, nEndPos ) + } + else if( hInput.createTextRange ) + { + var hRange = hInput.createTextRange() + hRange.collapse(true) + hRange.moveStart( 'character', nStartPos ) + hRange.moveEnd( 'character', nEndPos - nStartPos ) + hRange.select() + } +} + +cAutocomplete.markInputRange2 = function( sInputId ) +{ + var hInput = document.getElementById( sInputId ) + var nStartPos = hInput.hAutocomplete.nStartAC + var nEndPos = hInput.hAutocomplete.nEndAC + cAutocomplete.markInputRange( hInput, nStartPos, nEndPos ) +} + + +cAutocomplete.onListBlur = function( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + hElement = getParentByProperty( hElement, 'className', 'autocomplete_holder' ) + var hAC = hElement.hAutocomplete + if( !hAC.hClearTimeout ) + { + hAC.hClearTimeout = setTimeout( function() { hAC.clearList() }, cAutocomplete.CN_CLEAR_TIMEOUT ) + } +} + +cAutocomplete.onListFocus = function( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + hElement = getParentByProperty( hElement, 'className', 'autocomplete_holder' ) + var hAC = hElement.hAutocomplete + if( hAC.hClearTimeout ) + { + clearTimeout( hAC.hClearTimeout ) + hAC.hClearTimeout = null + } +} + +cAutocomplete.onItemClick = function( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + var hContainer = getParentByProperty( hElement, 'className', 'autocomplete_holder' ) + var hEl = getParentByTagName( hElement, 'A' ) + if( hContainer != null ) + { + var hAC = hContainer.hAutocomplete + hAC.selectOption( hEl ) + document.getElementById( hAC.sInputId ).focus() + hAC.clearList() + } + if( hEvent.preventDefault ) + { + hEvent.preventDefault() + } + hEvent.cancelBubble = true + hEvent.returnValue = false + return false +} + +cAutocomplete.onButtonClick = function ( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + var hAC = hElement.hAutocomplete + var hInput = document.getElementById( hAC.sInputId ) + if( hInput.disabled ) + { + return + } + hAC.prepareList( true ) + var hInput = document.getElementById( hAC.sInputId ) + hInput.focus() +} + +cAutocomplete.onFormSubmit = function ( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + if( hElement.bLocked ) + { + hElement.bLocked = false + hEvent.returnValue = false + if( hEvent.preventDefault ) + { + hEvent.preventDefault() + } + return false + } +} -- cgit v1.2.3-18-g5258