Autocomplete: i must press button twice for popup window.
alixey Oct 29, 2013 12:56 AMI have this autocomplete component:
<table> <tr> <td> <rich:autocomplete mode="ajax" autocompleteMethod="#{autocomplete.autocompleteProviders}" minChars="0" var="s" fetchValue="#{s.realName}" id="provider-suggestion" autofill="false" onselectitem="autocompleteChangeProvider(event.target)" style="display: inline;" layout="table" value="#{autocomplete.providerName}" > <a4j:queue requestDelay="500" ignoreDupResponses="true" /> <h:column> <h:outputText style="display:none;" value="#{s.id}"/> <h:outputText style="display:none;" value="#{s.realName}"/> </h:column> <h:column> <h:outputText value="#{s.name}" escape="false"/> </h:column> </rich:autocomplete> </td> <td> <h:graphicImage value="/img/arrow.png" onclick="#{rich:component('provider-suggestion')}.setValue('');#{rich:component('provider-suggestion')}.showPopup();stopEvent(event);" alt=""/> <h:graphicImage value="/img/cancel.png" onclick="#{rich:component('provider-suggestion')}.hidePopup();#{rich:component('provider-suggestion')}.setValue('');autocompleteChangeProvider(null);" alt="#{messages['pages.clear']}" title="#{messages['pages.clear']}"/> <h:inputHidden id="filter-provider-id" value="#{autocomplete.providerId}"/> </td> </tr> </table>
as you can see, i don't use showButton="true", because i need another functionality, i need erase input text before show popup window.
I use JavaScript function "autocompleteChangeProvider" for extract selected id.
I use separate button(/img/cancel.png) for erase input text, as you can see this function just use Richfaces API.
And problem:
if autocomplete.providerName not null and not empty(in rich:autocomplete) and user clicks on cancel button(img/cancel.png), then after that, if user clicks on show button(/img/arrow.png) popup not showing, user must clicks twice on this button.
This problem shows if i use showButton from rich:autocomplete instead my show button.
I think i found a solution of this problem:
Autocomplete.js has this code:
var onChangeValue = function (event, value, callback) { selectItem.call(this, event); // value is undefined if called from AutocompleteBase onChange var subValue = (typeof value == "undefined") ? this.__getSubValue() : value; var oldValue = this.value; this.value = subValue; if ((this.options.isCachedAjax || !this.options.ajaxMode) && this.cache && this.cache.isCached(subValue)) { ... } else { if (event.keyCode == rf.KEYS.RETURN || event.type == "click") { this.__setInputValue(subValue); } if (subValue.length >= this.options.minChars) { if ((this.options.ajaxMode || this.options.lazyClientMode) && oldValue != subValue) { callAjax.call(this, event, callback); } } else { if (this.options.ajaxMode) { clearItems.call(this); this.__hide(event); } } } };
for show popup this must be true: oldValue != subValue, but in this part of code oldValue='' and subValue='', so oldValue != subValue is return false!
i replace this code by this:
var onChangeValue = function (event, value, callback) { selectItem.call(this, event); // value is undefined if called from AutocompleteBase onChange var subValue = (typeof value == "undefined") ? this.__getSubValue() : value; var oldValue = this.value; this.value = subValue; if ((this.options.isCachedAjax || !this.options.ajaxMode) && this.cache && this.cache.isCached(subValue)) { ... } else { if (event.keyCode == rf.KEYS.RETURN || event.type == "click") { this.__setInputValue(subValue); } if (subValue.length >= this.options.minChars) { if ((this.options.ajaxMode || this.options.lazyClientMode) && (oldValue != subValue || (oldValue === '' && subValue === ''))) { callAjax.call(this, event, callback); } } else { if (this.options.ajaxMode) { clearItems.call(this); this.__hide(event); } } } };
so, than oldValue='' and subValue=='' callAjax.call will be called and popup will be showing.
Is this right resolve?