#248 new
Richard Cook

Results popup from Ajax.Autocompleter disappear when user clicks on scrollbars in IE6/IE7

Reported by Richard Cook | October 21st, 2009 @ 03:32 AM

This issue is described in some detail here. The basic problem is that IE6/IE7 treat the user clicking on the top-level window's scrollbars as a "blur" event: i.e. focus is taken away from the auto-complete control. This closes the auto-complete results if the user attempts to scroll the viewport: this is a very real usability problem since with this behaviour the user has no way of viewing all the auto-complete search results if the popup exceeds the height of the viewport.

Here is my workaround:

var HackedAutocompleter = null;
if (Prototype.Browser.IE && "undefined" == typeof document.documentMode || Prototype.Browser.IE && document.documentMode < 8) {
  // In IE7 and earlier and IE8 in quirks mode, the Ajax.Autocompleter will disappear if the user
  // clicks on the window's scrollbar since this causes the auto-completer to blur. Under IE8 and
  // and later in standards mode and Firefox the scrollbar does not cause the auto-completer to blur.
  // This fix works around this issue by delaying the blur by 200ms and determining if the user has
  // clicked on a real HTML element or not.
  // See http://www.nabble.com/AutoComplete-results-disappear-when-using-scrollbar-in-IE-td23612503.html
  // for discussion of this issue.
  HackedAutocompleter = Class.create(Ajax.Autocompleter, {
    initialize: function($super, element, update, url, options) {
      $super(element, update, url, options);
      this.clicked_outside = false;
      Event.observe(document, "click", this.onDocumentClick.bindAsEventListener(this));
      this.element.stopObserving("blur");
      this.element.observe("blur", this.onBlurOverride.bindAsEventListener(this));
    },
    onDocumentClick: function(event) {
      if (this.element.id != event.target.id) {
        this.clicked_outside = true;
      }
    },
    onBlurOverride: function(event) {
      var thisObject = this;
      var callback = function() {
        if (thisObject.clicked_outside) {
          thisObject.clicked_outside = false;
          thisObject.onBlur(event);
        }
        else {
          thisObject.element.focus();
        }
      }
      setTimeout(callback, 200);
    }
  });
}
else {
  HackedAutocompleter = Ajax.Autocompleter;
}

This is the rough idea of how this workaround functions:

  1. We intercept document.onclick in order to track the element that the user clicks on. In the case of the top-level scrollbars, this handler will not fire at all and this.clicked_outside will remain false. For real user clicks, this flag will be set to true unless the user is clicking on the auto-completer itself.
  2. We intercept onblur and provide logic to defer the blur response a little and to check the this.clicked_outside flag to determine if the onblur event should be bubbled up to the default handler or not.

Now I use HackedAutocompleter wherever I would normally use Ajax.Autocompleter. I would like to see a fix equivalent to this workaround moved down into the Ajax.Autocompleter implementation itself: the way I have chained my own blur behaviour into the class's events is a hack at best.

Comments and changes to this ticket

  • Jens

    Jens April 27th, 2010 @ 09:27 PM

    I am having the exact same issue too, even with IE8's "standards" mode. Did this ever get committed to the main source tree?

  • Richard Cook

    Richard Cook April 27th, 2010 @ 09:42 PM

    Jens,

    I don't have commit privileges to Prototype unfortunately and no one seems to have shown any interest in this bug or the fix that I've suggested - as you can see I submitted this ticket back in October 2009. Perhaps we will have more luck together!

    -Richard

  • Jens

    Jens April 28th, 2010 @ 06:37 PM

    I tried hacking your fix into another patch which fixes scrolling with the cursor keys, and also implements a local cache. However, this doesn't work (see attachment), even with IE8's standards mode (as well as IE8's quirks mode, IE7 and IE6) the autocomplete always closes upon the first click on the result lists' scrollbar.

    Can you try to reproduce this? I attached the patched cached-autocompleter.js which includes your patch from above. You can just include it into a file and replace the call to Ajax.Autocompleter with Ajax.CachedAutocompleter in the Rails helper to use it. OR use this patch

    --- a/vendor/gems/repeated_auto_complete-0.1.0/lib/auto_complete_macros_helper.rb
    +++ b/vendor/gems/repeated_auto_complete-0.1.0/lib/auto_complete_macros_helper.rb
    @@ -19,4 +19,5 @@
       # 
       # Addtional +options+ are:
    +  # <tt>:cache</tt>::                true: use CachedAutocompleter, false: use Autocompleter.
       # <tt>:update</tt>::               Specifies the DOM ID of the element whose 
       #                                  innerHTML should be updated with the autocomplete
    @@ -59,5 +60,6 @@
       #                                  request is made. Defaults to POST.
       def auto_complete_field(field_id, options = {})
    -    function =  "var #{field_id}_auto_completer = new Ajax.Autocompleter("
    +    cache = options[:cache] ? "Cached" : ""
    +    function =  "var #{field_id}_auto_completer = new Ajax.#{cache}Autocompleter("
         function << "'#{field_id}', "
         function << "'" + (options[:update] || "#{field_id}_auto_complete") + "', "
    

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile ยป

script.aculo.us is an open-source JavaScript framework for visual effects and interface behaviours.
<br/><b>Source available from github</b>
The Git repository resides at:
<a href="http://github.com/madrobby/scriptaculous">http://github.com/madrobby/scriptaculous</a>
<br/>Check out the current development trunk with:
<code>git clone git://github.com/madrobby/scriptaculous.git</code>
<br/>As <b>script.aculo.us 1.xx is feature-frozen</b>, this development trunk is for <b>bugfixes only</b>.
<br/>New development should happen only for
<b>script.aculo.us 2</b>.
<br/><b>Creating a bug report</b>
When creating a bug report, be sure to include as much relevant information as possible. Post a an example that shows off the problem. Preferably, <b>alter the unit tests</b> and show through either changed or added tests how the expected behavior is not occuring.

People watching this ticket

Attachments

Pages