if (!window.Richfaces) window.Richfaces = { }; if (!Richfaces.Selection) Richfaces.Selection = { }; Richfaces.Selection.getStart = function (element) { if (element.setSelectionRange) { return element.selectionStart; } else if (document.selection && document.selection.createRange) { var r = document.selection.createRange().duplicate(); r.moveEnd('character', element.value.length); if (r.text == '') return element.value.length; return element.value.lastIndexOf(r.text); } } Richfaces.Selection.getEnd = function (element) { if (element.setSelectionRange) { return element.selectionEnd; } else if (document.selection && document.selection.createRange) { var r = document.selection.createRange().duplicate(); r.moveStart('character', - element.value.length); return r.text.length; } } Richfaces.Selection.setCaretTo = function (element, pos) { if (element.setSelectionRange) { element.focus(); element.setSelectionRange(pos, pos); } else if (element.createTextRange) { var range = element.createTextRange(); range.collapse(true); range.moveEnd('character', pos); range.moveStart('character', pos); range.select(); } } var Suggestion = { }; Suggestion.Base = function () { }; Suggestion.Base.prototype = { baseInitialize: function (element, update, options) { this.isOpera = (RichFaces.navigatorType() == RichFaces.OPERA ? true : false); this.element = $(element); this.update = $(update); this.hasFocus = false; this.changed = false; this.active = false; this.index = 0; this.prevIndex = - 1; this.entryCount = 0; this.keyEvent = false; this.oldValue = this.element.value; this.skipHover = false; this.selectedItems = [ ]; this.selectedItemsCache = { }; options.selection = update + '_selection'; var needIframe = (RichFaces.navigatorType() == RichFaces.MSIE); if (needIframe) { options.iframeId = update + '_iframe'; } if (this.setOptions) this.setOptions(options); else this.options = options || { }; this.options.param = this.options.param || this.element.name; this.options.selectedClasses = (this.options.selectedClass || 'rich-sb-int-sel').split(' '); this.options.selectValueClass = this.options.selectValueClass || ' '; this.options.tokens = $A(options.tokens) || [ ]; this.options.frequency = this.options.frequency || 0.4; this.options.minChars = isNaN(this.options.minChars) ? 1 : parseInt(this.options.minChars); this.options.onShow = this.options.onShow || function (element, update, options) { if (!update.style.position || update.style.position == 'absolute') { update.style.position = 'absolute'; RichFaces.Position.smartClone(element, update, options); } if (!window.opera) { Effect.Appear(update, { duration: 0.15 }); $(update).show(); if (options.iframeId) { Effect.Appear($(options.iframeId), { duration: 0.15, to: 0.01 }); $(options.iframeId).show(); } } else { Effect.Appear(update, { duration: 0.15, to: 0.999999 }); } }; this.options.onHide = this.options.onHide || function (element, update, options) { if (options.iframeId) { try { new Effect.Fade($(options.iframeId), { duration: 0.15 }); } catch (e) { $(options.iframeId).hide(); } } try { new Effect.Fade(update, { duration: 0.15 }); } catch (e) { $(update).hide(); } }; this.options.width = this.options.width || 'auto'; if (typeof (this.options.tokens) == 'string') this.options.tokens = new Array(this.options.tokens); for (var i = 0; i < this.options.tokens.length; i++) { var token = this.options.tokens[i]; if (token.charAt[0] == '\'' && token.charAt[token.length - 1] == '\'') this.options.tokens[i] = token.substring(1, - 1); } this.observerHandle = null; this.element.setAttribute('autocomplete', 'off'); Element.hide(this.update); this.onBlurListener = this.onBlur.bindAsEventListener(this); Event.observe(this.element, 'blur', this.onBlurListener); if (RichFaces.navigatorType() == RichFaces.MSIE) { Event.observe(this.element, 'focusout', function (event) { var elt = event.toElement; while (elt) { if (elt == this.update) { this.element.keepFocus = true; elt = undefined; } else { elt = elt.parentNode; } } }.bindAsEventListener(this)); } this.onKeyDownListener = this.onKeyDown.bindAsEventListener(this); Event.observe(this.element, 'keydown', this.onKeyDownListener); if (this.isOpera) { this.onKeyPressListener = this.onKeyPress.bindAsEventListener(this); Event.observe(this.element, 'keypress', this.onKeyPressListener); this.onKeyUpListener = this.onKeyUp.bindAsEventListener(this); Event.observe(this.element, 'keyup', this.onKeyUpListener); this.upDown = 0; } this.onScrollListener = this.onScroll.bindAsEventListener(this); if (options.popupClass) { var selected = Element.select(this.update, '.rich-sb-ext-decor-3'); Element.addClassName(selected[0], options.popupClass); } this.onNothingLabelClick = this.hideNLabel.bindAsEventListener(this); this.scrollElements = null; this.eventOnScroll = this.eventOnScroll.bindAsEventListener(this); }, cancelSubmit: function (event) { Event.stop(event); }, disableSubmit: function () { if (this.isOpera) { var el = this.element; while (el.parentNode && (!el.tagName || (el.tagName.toUpperCase() != 'FORM'))) el = el.parentNode; if (el.tagName && (el.tagName.toUpperCase() == 'FORM')) { this.parentForm = el; this.onSubmitListener = this.cancelSubmit.bindAsEventListener(this); Event.observe(el, 'submit', this.onSubmitListener); } } }, enableSubmit: function () { if (this.isOpera) { if (this.parentForm) { Event.stopObserving(this.parentForm, 'submit', this.onSubmitListener); } } }, onKeyPress: function (event) { if (this.upDown != 0) { if (this.upDownMark) { this.upDownMark = false; } else { if (this.upDown == 1) { this.keyEvent = true; this.markPrevious(); this.render(); } else if (this.upDown == 2) { this.keyEvent = true; this.markNext(); this.render(); } else if (this.upDown == 3) { this.keyEvent = true; this.markPreviousPage(); this.render(); } else if (this.upDown == 4) { this.keyEvent = true; this.markNextPage(); this.render(); } } } }, onKeyUp: function (event) { this.upDownMark = false; this.upDown = 0; }, show: function () { if (RichFaces.SAFARI == RichFaces.navigatorType()) { this.wasScroll = false; this.wasBlur = false; if (!this.overflow) { var selected = Element.select(this.update, '.rich-sb-overflow'); this.overflow = selected[0]; } Event.observe(this.overflow, 'scroll', this.onScrollListener); } if (Element.getStyle(this.update, 'display') == 'none') { this.options.onShow(this.element, this.update, this.options); } this.disableSubmit(); Richfaces.removeScrollEventHandlers(this.scrollElements, this.eventOnScroll); this.scrollElements = Richfaces.setupScrollEventHandlers($(this.options.selection), this.eventOnScroll); }, hide: function () { Richfaces.removeScrollEventHandlers(this.scrollElements, this.eventOnScroll); if (RichFaces.SAFARI == RichFaces.navigatorType()) { if (this.wasScroll) { this.wasScroll = false; return; } Event.stopObserving(this.overflow, 'scroll', this.onScrollListener) } this.stopIndicator(); if (Element.getStyle(this.update, 'display') != 'none') { this.options.onHide(this.element, this.update, this.options); } this.enableSubmit(); this.hasFocus = false; this.active = false; }, eventOnScroll: function (e) { this.hide(); }, hideNLabel: function (event) { var nothingLabel = $(this.update.id + 'NothingLabel'); if (nothingLabel) { Element.hide(nothingLabel); Event.stopObserving(nothingLabel, 'click', this.onNothingLabelClick); Event.stopObserving(this.element, 'blur', this.onNothingLabelClick); this.hide(); } }, startIndicator: function () { if (this.options.indicator) Element.show(this.options.indicator); }, stopIndicator: function () { if (this.options.indicator) Element.hide(this.options.indicator); }, isUnloaded: function () { if (this.element.parentNode && this.update.parentNode) { return false; } LOG.info('Element unloaded from DOM'); if (this.element) { Event.stopObserving(this.element, 'blur', this.onBlurListener); Event.stopObserving(this.element, 'keydown', this.onKeyDownListener); if (this.onKeyPressListener) { Event.stopObserving(this.element, 'keypress', this.onKeyPressListener); this.onKeyPressListener = undefined; } if (this.onKeyUpListener) { Event.stopObserving(this.element, 'keyup', this.onKeyUpListener); this.onKeyUpListener = undefined; } } return true; }, onKeyDown: function (event) { if (this.isUnloaded()) return; if (!this.initialized) { if (this.options.iframeId) { var iFrame = $(this.options.iframeId); var iTemp = iFrame.cloneNode(true); iFrame.parentNode.removeChild(iFrame); document.body.insertBefore(iTemp, document.body.firstChild); } var temp = this.update.cloneNode(true); this.update.parentNode.removeChild(this.update); this.update = temp; this.update.component = this; this['rich:destructor'] = 'destroy'; var scripts = temp.getElementsByTagName('script'); for (var i = 0; i < scripts.length; i++) { var script = scripts[i]; if (script.parentNode) { script.parentNode.removeChild(script); } } event.target.parentNode.insertBefore(this.update, event.target.parentNode.firstChild); this.initialized = true; } this.wasBlur = false; if (this.active) { this.wasScroll = false; var surrogateEvent = (event.rich && event.rich.isCallSuggestion); switch (event.keyCode) { case Event.KEY_TAB: case Event.KEY_RETURN: this.selectEntry(event); Event.stop(event); case Event.KEY_ESC: this.hide(); this.active = false; Event.stop(event); if (this.isOpera) { this.element.focus(); } return; case Event.KEY_LEFT: case Event.KEY_RIGHT: return; case Event.KEY_UP: this.keyEvent = true; this.markPrevious(); this.render(); if (navigator.appVersion.indexOf('AppleWebKit') > 0) Event.stop(event); if (this.isOpera && !surrogateEvent) { this.upDown = 1; this.upDownMark = true; } return; case Event.KEY_DOWN: this.keyEvent = true; this.markNext(); this.render(); if (navigator.appVersion.indexOf('AppleWebKit') > 0) Event.stop(event); if (this.isOpera && !surrogateEvent) { this.upDown = 2; this.upDownMark = true; } return; case 33: this.keyEvent = true; this.markPreviousPage(); this.render(); if (navigator.appVersion.indexOf('AppleWebKit') > 0) Event.stop(event); if (this.isOpera && !surrogateEvent) { this.upDown = 3; this.upDownMark = true; } return; case 34: this.keyEvent = true; this.markNextPage(); this.render(); if (navigator.appVersion.indexOf('AppleWebKit') > 0) Event.stop(event); if (this.isOpera && !surrogateEvent) { this.upDown = 4; this.upDownMark = true; } return; } } else if (event.keyCode == Event.KEY_TAB || event.keyCode == Event.KEY_RETURN || event.keyCode == Event.KEY_ESC) { return; } this.changed = true; this.hasFocus = true; if (this.observerHandle) { LOG.debug('clear existing observer'); window.clearTimeout(this.observerHandle) }; LOG.debug('set timeout for request suggestion'); var domEvt = { }; try { domEvt.target = event.target; domEvt.srcElement = event.srcElement; domEvt.type = event.type; domEvt.altKey = event.altKey; domEvt.button = event.button; domEvt.clientX = event.clientX; domEvt.clientY = event.clientY; domEvt.ctrlKey = event.ctrlKey; domEvt.keyCode = event.keyCode; domEvt.modifiers = event.modifiers; domEvt.pageX = event.pageX; domEvt.pageY = event.pageY; domEvt.screenX = event.screenX; domEvt.screenY = event.screenY; domEvt.shiftKey = event.shiftKey; domEvt.which = event.which; domEvt.rich = event.rich; } catch (e) { LOG.warn('Exception on clone event'); } if ((event.rich && event.rich.ignoreFrequency)) { this.onObserverEvent(domEvt); } else { this.observerHandle = window.setTimeout(this.onObserverEvent.bind(this, domEvt), this.options.frequency * 1000); } }, _findTr: function (event) { var elt = Event.element(event); while (elt && (!elt.tagName || elt.tagName.toUpperCase() != 'TR')) { elt = elt.parentNode; } return elt; }, onHover: function (event) { var element = this._findTr(event); if (!this.skipHover) { if (this.index != element.autocompleteIndex) { this.index = element.autocompleteIndex; this.render(); } if (event.type == 'mousemove') { Event.stopObserving(element, 'mousemove', this.onHover); } } else { this.skipHover = false; Event.observe(element, 'mousemove', this.onHover.bindAsEventListener(this)); } Event.stop(event); }, onClick: function (event) { if (this.active) { this.wasScroll = false; this.wasBlur = false; var element = this._findTr(event); this.index = element.autocompleteIndex; this.selectEntry(event); this.hide(); } }, onMouseOut: function (event) { var element = this._findTr(event); Event.stopObserving(element, 'mousemove', this.onHover); }, onBlur: function (event) { if (this.isUnloaded()) return; this.wasBlur = true; if (!this.active) return; if (this.element.keepFocus) { this.element.keepFocus = false; this.element.focus(); } else { setTimeout(this.hide.bind(this), 250); } }, onScroll: function (event) { if (RichFaces.SAFARI == RichFaces.navigatorType() && this.wasBlur) { if (this.element) { this.element.focus(); this.wasScroll = true; this.wasBlur = false; } } }, calcEntryPosition: function (entry, scroll) { var item = entry; var realOffset = 0; while (item && (item != scroll)) { if (RichFaces.SAFARI == RichFaces.navigatorType() && 'TR' == item.tagName.toUpperCase()) { realOffset += item.select('.rich-sb-cell-padding') [0].offsetTop; } else realOffset += item.offsetTop; if (item.parentNode == scroll) break; item = item.offsetParent; } var entryOffsetHeight; if (RichFaces.SAFARI == RichFaces.navigatorType()) { var tdElement = item.select('.rich-sb-cell-padding') [0]; entryOffsetHeight = tdElement.offsetTop + tdElement.offsetHeight; } else entryOffsetHeight = entry.offsetHeight; return { realOffset: realOffset, entryOffsetHeight: entryOffsetHeight }; }, countVisibleEntries: function () { var entry = this.getEntry(this.index); var selected = Element.select(this.update, '._suggestion_size_'); var scroll = selected[0] || this.update; var entryPosition = this.calcEntryPosition(entry, scroll); var countAll = Math.round(scroll.clientHeight / entryPosition.entryOffsetHeight); var current = Math.round((entryPosition.realOffset - scroll.scrollTop) / entryPosition.entryOffsetHeight); return { current: current, all: countAll }; }, render: function () { if (this.entryCount > 0) { LOG.debug('render for index ' + this.index + ' and old index ' + this.prevIndex); if (this.prevIndex != this.index) { var entry = this.getEntry(this.index); for (var i = 0; i < this.options.selectedClasses.length; i++) Element.addClassName(entry, this.options.selectedClasses[i]); var cells = entry.select('.rich-sb-cell-padding'); for (var i = 0; i < cells.length; i++) { Element.addClassName(cells[i], this.options.selectValueClass); } if (this.keyEvent) { var selected = Element.select(this.update, '._suggestion_size_'); var scroll = selected[0] || this.update; var entryPosition = this.calcEntryPosition(entry, scroll); var oldScrollTop = scroll.scrollTop; if (entryPosition.realOffset > scroll.scrollTop + scroll.clientHeight - entryPosition.entryOffsetHeight) { scroll.scrollTop = entryPosition.realOffset - scroll.clientHeight + entryPosition.entryOffsetHeight; } else if (entryPosition.realOffset < scroll.scrollTop) { scroll.scrollTop = entryPosition.realOffset; } if (oldScrollTop != scroll.scrollTop) { this.skipHover = true; } this.keyEvent = false; } if (this.prevIndex >= 0) { var prevEntry = this.getEntry(this.prevIndex); if (prevEntry) { var prevCells = prevEntry.select('.rich-sb-cell-padding'); for (var i = 0; i < prevCells.length; i++) { Element.removeClassName(prevCells[i], this.options.selectValueClass); } for (var i = 0; i < this.options.selectedClasses.length; i++) Element.removeClassName(prevEntry, this.options.selectedClasses[i]); } } } this.prevIndex = this.index; if (this.hasFocus && !this.wasBlur) { this.show(); this.active = true; } } else { var nothingLabel = $(this.update.id + 'NothingLabel'); if (!nothingLabel || 'none' == nothingLabel.style.display) { this.active = false; this.hide(); } } }, markPrevious: function () { if (this.index > 0) this.index--; }, markNext: function () { if (this.index < this.entryCount - 1) this.index++; }, markPreviousPage: function () { var pos = this.countVisibleEntries(); if (this.index > 0) { if (pos.current > 0) { this.index = this.index - Math.min(pos.current, pos.all); } else { this.index = this.index - pos.all; } if (this.index < 0) { this.index = 0; } } }, markNextPage: function () { var pos = this.countVisibleEntries(); if (this.index < this.entryCount - 1) { if ((pos.current < pos.all - 1) && pos.current >= 0) { this.index = this.index + (pos.all - pos.current - 1); } else { this.index = this.index + pos.all; } if (this.index > this.entryCount - 1) { this.index = this.entryCount - 1; } } }, getEntry: function (index) { var element = $(this.contentTable).firstChild; while (!element.tagName || element.tagName.toLowerCase() != 'tbody') { element = element.nextSibling; } return $(element.childNodes[index]); }, getCurrentEntry: function () { return this.getEntry(this.index); }, selectEntry: function (event) { this.active = false; var input = $(this.options.selection); input.value = this.index; var value = ''; this.updateElement(this.getCurrentEntry(), event); if (this.options.onselect) { this.options.onselect(this, event); } if (this.update.onselect) { this.update.onselect(this, event); } input.value = ''; }, updateElement: function (selectedElement, event) { if (this.options.updateElement) { this.options.updateElement(selectedElement); return; } var value = ''; var obj = selectedElement.firstChild; while (!obj.tagName || obj.tagName.toLowerCase() != 'td') obj = obj.nextSibling; value = Element.collectTextNodes(obj); this.insertValue(value, event); this.oldValue = this.element.value; this.element.focus(); if (this.options.afterUpdateElement) this.options.afterUpdateElement(this.element, selectedElement); }, updateChoices: function (choices) { if (!this.changed && this.hasFocus) { if (choices) { this.update.firstChild.replaceChild(choices, this.update.firstChild.firstChild); } this.update.firstChild.firstChild.firstChild.firstChild.firstChild.firstChild.firstChild.style.width = null; var entryes = [ ]; if (this.options.entryClass) { var selected = Element.select(this.update, '.' + this.options.entryClass); entryes = selected || [ ]; } else if (this.update.firstChild && this.update.firstChild.firstChild && this.update.firstChild.firstChild.childNodes) { Element.cleanWhitespace(this.update); Element.cleanWhitespace(this.update.firstChild); Element.cleanWhitespace(this.update.firstChild.firstChild); entryes = this.update.firstChild.firstChild.childNodes; } this.entryCount = entryes.length; for (var i = 0; i < this.entryCount; i++) { var entry = entryes[i]; entry.autocompleteIndex = i; this.addObservers(entry); } this.stopIndicator(); var selected = Element.select(this.update, '._suggestion_size_'); var scroll = selected[0] || this.update; scroll.scrollTop = - 1; scroll.scrollLeft = - 1; this.index = 0; this.prevIndex = - 1; var nothingLabel = $(this.update.id + 'NothingLabel'); if (nothingLabel && this.hasFocus && !this.wasBlur) { if (this.entryCount < 1) { Element.show(nothingLabel); Event.observe(nothingLabel, 'click', this.onNothingLabelClick); Event.observe(this.element, 'blur', this.onNothingLabelClick); this.show(); } } this.render(); } }, addObservers: function (element) { Event.observe(element, 'mouseover', this.onHover.bindAsEventListener(this)); Event.observe(element, 'click', this.onClick.bindAsEventListener(this)); Event.observe(element, 'mouseout', this.onMouseOut.bindAsEventListener(this)); }, onObserverEvent: function (event) { LOG.debug('Observer event occurs'); this.changed = false; var oldValue = this.element.value; if ((event.rich && event.rich.isCallSuggestion) || this.oldValue != oldValue) { this.startPosition = 0; this.endPosition = oldValue.length; if (this.options.tokens.length != 0) { var tokens = this.options.tokens.join(''); this.startPosition = this.endPosition = Richfaces.Selection.getStart(this.element); while (this.endPosition < oldValue.length && tokens.indexOf(oldValue.charAt(this.endPosition)) == - 1) this.endPosition++; while (this.startPosition > 0 && tokens.indexOf(oldValue.charAt(this.startPosition - 1)) == - 1) this.startPosition--; } if (this.options.usingSuggestObjects) this.updateItems(oldValue); } if ((event.rich && event.rich.ignoreMinChars) || this.getToken().length >= this.options.minChars) { LOG.debug('Call data for update choices'); if (event.keyCode == Event.KEY_DOWN || this.oldValue != oldValue) { this.startIndicator(); this.getUpdatedChoices(event); } } else { if (this.isSelectedItemsUpdated) { this.isSelectedItemsUpdated = false; this.callOnObjectChangeListener(event); } this.active = false; this.hide(); } this.oldValue = oldValue; this.observerHandle = null; }, callSuggestion: function (ignoreMinChars) { if (this.active) return; if (!this.hasFocus) { this.element.focus(); Richfaces.Selection.setCaretTo(this.element, this.element.value.length); } var domEvt = { }; domEvt.target = this.element; domEvt.type = 'keydown'; domEvt.altKey = false; domEvt.clientX = 0; domEvt.clientY = 0; domEvt.ctrlKey = false; domEvt.keyCode = 40; domEvt.pageX = 0; domEvt.pageY = 0; domEvt.screenX = 0; domEvt.screenY = 0; domEvt.shiftKey = false; domEvt.which = 40; domEvt.rich = { 'isCallSuggestion': true, 'ignoreMinChars': ignoreMinChars, 'ignoreFrequency': true }; this.onKeyDownListener(domEvt); }, getSelectedItems: function () { var result = new Array(); if (this.options.usingSuggestObjects) { for (var i = 0; i < this.selectedItems.length; i++) { if (this.selectedItems[i].object) result.push(this.selectedItems[i].object); } } return result; }, updateItems: function (newValue) { this.isSelectedItemsUpdated = false; var oldSelectedItems = this.selectedItems; var value = newValue.replace(/^\s+/, '').replace(/\s+$/, ''); var itm = ''; this.selectedItems = [ ]; var newItemsCache = { }; if (this.options.tokens.length != 0) { var re = new RegExp('\\s*[\\' + this.options.tokens.join('|\\') + ']\\s*'); var items = value.split(re); for (var i = 0; i < items.length; i++) { itm = this.selectedItemsCache[items[i]]; if (!itm) itm = { text: items[i], object: null }; this.selectedItems.push(itm); newItemsCache[itm.text] = itm; } } else { itm = this.selectedItemsCache[value]; if (!itm) { itm = { text: value, object: null }; } this.selectedItems.push(itm); newItemsCache[itm.text] = itm; } this.selectedItemsCache = newItemsCache; if (this.selectedItems.length != oldSelectedItems.length) this.isSelectedItemsUpdated = true; else { for (var i = 0; i < this.selectedItems.length; i++) { if (this.selectedItems[0].text != oldSelectedItems.text || this.selectedItems[0].object != oldSelectedItems.object) { this.isSelectedItemsUpdated = true; break; } } } }, updateSelectedItems: function (items) { for (var i = 0; i < this.selectedItems.length; i++) { if (!this.selectedItems[i].object) { var obj = items[this.selectedItems[i].text]; if (obj) { this.selectedItems[i].object = obj; this.isSelectedItemsUpdated = true; } } } }, getItemListForUpdate: function () { var list = [ ]; var result = ''; if (this.options.tokens.length != 0) { for (var i = 0; i < this.selectedItems.length; i++) { if (!this.selectedItems[i].object && this.selectedItems[i].text.length == 0) list.push(this.selectedItems[i].text); } result = list.join(this.options.tokens[0]); } else if (this.selectedItems.length != 0 && !this.selectedItems[0].object) result = this.selectedItems[0].object; return result; }, insertValue: function (value, event) { var startStr = this.element.value.substr(0, this.startPosition); var endStr = this.element.value.substr(this.endPosition); var str = this.element.value.substring(this.startPosition, this.endPosition); var whitespace = str.match(/^\s+/); if (whitespace) startStr += whitespace[0]; whitespace = str.match(/\s+$/); if (whitespace) endStr = whitespace[0] + endStr; this.element.value = startStr + value + endStr; Richfaces.Selection.setCaretTo(this.element, (startStr + value).length); this.endPosition = this.startPosition + value.length; if (this.options.usingSuggestObjects) { var index = 0; if (this.options.tokens.length != 0) { var tokens = this.options.tokens.join(''); var p = 0; while (p < this.startPosition) { if (tokens.indexOf(this.element.value.charAt(p)) != - 1) index++; p++; } } var itm = { text: value, object: this.fetchValues[this.index] } var flag = (!this.selectedItems[index] || this.selectedItems[index].text != value || this.selectedItems[index].object == null ? true : false); this.selectedItemsCache[value] = itm; if (!this.selectedItems[index]) this.selectedItems.push(itm); else this.selectedItems[index] = itm; if (flag) { this.callOnObjectChangeListener(event); } } }, getToken: function () { var ret = this.element.value.substring(this.startPosition, this.endPosition).replace(/^\s+/, '').replace(/\s+$/, ''); return /\n/.test(ret) ? '' : ret; }, callOnObjectChangeListener: function (event) { if (this.options.onobjectchange) { this.options.onobjectchange(this, event); } } } Richfaces.SuggestionBox = { } Richfaces.SuggestionBox.defaultOptions = { popupClass: '', popupStyle: '', width: 200, height: 200, entryClass: 'richfaces_suggestionEntry', selectedClass: '', param: 'inputvalue', frequency: 0.4, minChars: 0, tokens: null, selectValueClass: 'richfaces_suggestionSelectValue', usingSuggestObjects: false, zindex: 200 } RichFaces.Suggestion = Class.create(); Object.extend(Object.extend(RichFaces.Suggestion.prototype, Suggestion.Base.prototype), { initialize: function (actionUrl, element, content, options) { this.options = Object.clone(Richfaces.SuggestionBox.defaultOptions); Object.extend(this.options, options); var update = content || 'ac1update'; if (!$(update)) this.create(element, update, content, this.options); this.baseInitialize(element, update, this.options); this.options.asynchronous = true; this.options.onajaxcomplete = this.options.oncomplete; this.options.oncomplete = this.onComplete.bind(this); this.options.defaultParams = this.options.parameters || null; this.content = content; this.contentTable = content + ':suggest'; this.actionUrl = actionUrl; if (this.options.onsubmit && this.options.onsubmit != 'null') { this.onsubmitFunction = new Function(this.options.onsubmit + ';return true;').bind(this.element); } this.update.component = this; this['rich:destructor'] = 'destroy'; return this; }, destroy: function () { this.update.component = null; }, getUpdatedChoices: function (event) { this.options.parameters[this.options.param] = this.getToken(); if (this.options.usingSuggestObjects) this.options.parameters[this.options.param + 'request'] = this.getItemListForUpdate(); if (this.onsubmitFunction && !this.onsubmitFunction()) { return; } A4J.AJAX.Submit(this.actionUrl, event, this.options); }, onComplete: function (request, event, data) { LOG.debug('AJAX response complete - updateChoices'); if (!this.update.style.position || this.update.style.position == 'absolute') { this.update.style.position = 'absolute'; RichFaces.Position.smartClone(this.element, this.update, this.options); } this.updateChoices(); if (this.options.usingSuggestObjects && data) { this.fetchValues = data.suggestionObjects; this.updateSelectedItems(data.requestedObjects); if (this.isSelectedItemsUpdated) { this.isSelectedItemsUpdated = false; this.callOnObjectChangeListener(event); } LOG.debug('Choices updated'); } if (this.options.onajaxcomplete) { this.options.onajaxcomplete(request, event); } }, create: function (element, suggestion, content, options) { if (!$(element)) return; var style = 'display:none;' + (options.popupStyle || 'border:1px solid black;position:absolute; background-color:white;'); var styleClass = options.popupClass ? ' class="' + options.popupClass + '" ' : ''; new Insertion.Top($(element).ownerDocument.body, '