I came across a problem recently, using the Autocompleter API of the script.aculo.us library. Some amount of Googling later and I still couldn’t find a solution, but I discovered that there was misery in company – other devs were having the same issue.
Basically, when the autocomplete list is generated, and said list has a scrollbar on it, clicking on a scrolling arrow (or the scrollbar itself) would cause the list to disappear. Why? Because the input field’s onblur() would fire and close the list.
So I looked through the code a bit, and came up with this simple solution.
First: make sure that you save a reference to the Ajax.Autocompleter object that you create:
var oAutocompleter = new Ajax.Autocompleter()
Second: define an undocumented option in the options parm list:
onHide: fOnHide
…where fOnHide is a function we’ll define later.
Third: add a boolean var to the Autocompleter object:
oAutocompleter.lcl_bActive = false;
Fourth: apply some event handlers to the div that is populated with the results:
oAutocompleter.update.onmouseover = function() {oAutocompleter.lcl_bActive = true;};
oAutocompleter.update.onmouseout = function() {oAutocompleter.lcl_bActive = false; oAutocompleter.element.focus();};
Fifth, and finally: define the fOnHide() function:
function fOnHide() {
if (!oAutocompleter.lcl_bActive) {
new Effect.Fade(oAutocompleter.update,{duration:0.15});
}
}
Now – how does this work? (good to know, since I’m sure it’s inevitable that it won’t work for somebody or at some point in time)
It seems that somebody ends up calling the onHide() function of your instantiated Ajax.Autocompleter object whenever the input field’s onblur() fires. Normally this results in an Effect.Fade being instantiated, and your result list fades out of existence.
We interrupt that process – instead of calling the Effect.Fade() directly, we first check to see if a flag has been set. The flag is set to true whenever the pointer is hovering over the list – manipulating the scroll buttons or scrollbar or just hanging out. In those instances, the onHide will essentially do nothing, and your autocomplete list will not disappear.
Once you move away from the list, the flag is reset and, crucially, focus is returned to the input field. This is done so that the field’s onblur() can fire when appropriate, as it would have done before we made any code changes. Now, when the field loses focus, the fOnHide() function will perform the default task of running the Effect.Fade() function.
Easy breezy 🙂