#33 new
Gilgamesh

Problem with scrolling on div tags

Reported by Gilgamesh | June 25th, 2008 @ 05:59 PM | in 1.8.3 bugfix release

I've created a sort of combo box using a text input to type the text and with the autocompleter, it fills a container (div tags with overflow:auto), so when i try to drag the scrollbar, the container (div tags) disappears automatically and i can't select any elements from my list.

I think it could come from the onBlur function from the controls.js file.

It only works with Firefox 2.0.0.14, not with IE 7 and lower, Safari and Opera

Comments and changes to this ticket

  • willdonovan

    willdonovan July 18th, 2008 @ 07:31 AM

    I have the same issue, however it is just with a div area displaying a list.

    If the list is bigger than the height of the div then a scroll bar is displayed (overflow:auto;), however in IE 7 and lower, Safari and Opera, if you select the down arrow for the scroll, the box disappears after 1 click and nothing is recorded as being selected.

  • AJ

    AJ October 1st, 2008 @ 05:59 AM

    Hi, I have encountered this problem, and have developed a workaround.

    For some reason the click on the scroll bar is treated as some kind of global action (as is a click on an tag, or a checkbox) and is treated as a clickaway from the div, which makes it disappear.

    For most browsers, adding in the following code will prevent this behavior:

    $('name_of_autocomplete_div').observe('mousedown', function(e) {

    e.stop();
    
    

    });

    For IE, it's a whole different mess. I had to overwrite the Autocompleter.Base onBlur function to check a flag that I would set in the mousedown handler after a delay. I can provide you with the code if you'd like.

    This is definitely a bug in scriptaculous. Hope this helps.

  • ronin-15560 (at lighthouseapp)

    ronin-15560 (at lighthouseapp) November 20th, 2008 @ 05:02 PM

    • Milestone set to 1.8.3 bugfix release

    AJ: can you provide the code that fixes this on IE?

  • AJ

    AJ December 2nd, 2008 @ 06:26 AM

    Hi, Below is the entire workaround I use to deal with all browsers:

    
         if (Prototype.Browser.IE) {
           Autocompleter.Base.prototype.onBlur = function(event) {
             // needed to make click events work
             setTimeout((function(e) {
                   if (this.dontBlur) {
                     this.dontBlur = false;
                     $('name_of_input_box').focus();
                     return;
                   }
                   this.hasFocus = false;
                   this.active = false;
                   this.hide();
                 }).bind(this), 250);
           };
    
           $('name_of_autocomplete_div').observe('mousedown', function(e) {
               autocomplete_object.dontBlur = true;
               e.stop();
             });
         } else {
           $('name_of_autocomplete_div').observe('mousedown', function(e) {
               e.stop();
             });
         }
    

    The IE hack is pretty ugly, and I'm sure it could be improved by someone who has a better handle on IE's event system than I do. But it seems to work. (The 250ms delay could most likely be replaced with a 1ms delay and still work; I verified this on IE7, but as I don't have IE6 immediately available on this computer, I can't be certain.)

    AJ

  • Brett Miller

    Brett Miller February 9th, 2009 @ 06:51 PM

    I also had the problem of a list going away when I either had a scrolling DIV for my results, or if I had a set of results that extended beyond the end of the page.

    However, I think that I might have a better cross-browser solution. The problem seems to be that the search result DIV is hidden when there is any click received at all, not just a click on one of the items in the list. (In IE, the event sequence for this seems to be different than Firefox. In any case, the code below works for both browsers.)

    I modified the onBlur handler (v1.8.2) in the AutoCompleter to check to see if the click was actually on one of the list items, instead of being just anywhere.

    onBlur: function(event) {

    // needed to make click events working
    
    // Make sure that we're on
    // one of the items in the list.  Without this
    // check, scrolling the window causes the list
    // to go away.
    var element = Event.findElement(event, 'LI');
    
    if ( element != null )
    {
        setTimeout(this.hide.bind(this), 250);
        this.hasFocus = false;
        this.active = false;
    }
    
    

    },

    Unless there's something that I missed, this seems to be a cleaner solution. I've tried it in IE7 and Firefox 3.0.6.

    Brett

  • Akio

    Akio February 14th, 2009 @ 10:56 PM

    AJ and Brett Miller,

    Thank you for your fixes regarding the suggestion list disappearing when the scrollbars are clicked on. However, the problem does not seem to be completely fixed.

    Lets suppose the following situation

    1. Enter some text in the autocomplete text box and let the suggestion list appear with scroll bars.

    2. Use the mouse button to click and scroll up or down the list. The suggestion list won't disappear. Very Good! Bug Fixed! But there is more to the story.

    3. Now do NOT select any item from the list.

    4. Click anywhere outside the suggestion list.

    Ideally the suggestion list should disappear now, since we did not select anything from the list and clicked outside the suggestion list. But you see that the suggestion list just sits there unless you select something from the list. So in other words you are forced to select something from the list even if you don't want to or the suggestion list will not go away

    Thomas, I really hope this bug gets fixed as soon as possible so that Autocomplete could become production material.

    Minus this scrollbar problem, Autocomplete is AWESOME!

    -Akio.

  • AJ

    AJ February 17th, 2009 @ 08:34 PM

    Hi Akio (and everyone else), I actually came across and fixed this problem a few weeks ago.

    Here is the list of AutoComplete problems I've fixed:

    1. The hovering behavior on large lists is very slow (up to 1s delay). It iterates through every element and changes each class (very slow in IE). My fix simply remembers only the last hovered item, and switches the class of only that item and the current hovered item.

    2. The list construction mechanism is very slow for large lists. It adds observers to every element, which can take 3-4s for 1000 items in IE6/7. (This freezes the browser for that period of time.) Instead, I rely on a single observer for the entire DIV, and use the findElement function already invoked by Autocompleter.Base.onClick to find out which LI was clicked.

    3. The clickaway bug that Akio described. I use a delayed 'blur' event handler of the autocomplete div to fix it.

    You can see the fixed autocompleter in action at http://www.modista.com/ (click on "Refine By >", and then click in the brands box).

    It should work for all major browsers. If it fixes problems people care about, I'd be happy to post all the code here.

    Thanks, AJ

  • Akio

    Akio February 22nd, 2009 @ 06:25 PM

    Hey AJ,

    I checked out the site http://www.modista.com/ (Awesome site by the way!) to see if the click away problem I described in my earlier post is fixed. It seems to not have been fix.

    Maybe the fix was not released onto the site yet.

    Would be great if you could post the code here.

    Thanks for your help.

    -Akio

  • AJ

    AJ February 23rd, 2009 @ 03:10 AM

    Hi Akio, What version of IE are you using? I've verified that it works for IE 6 and 7.

    Here is exactly what I am doing: 1. Go to the site 2. Click on "Women's Shoes" 3. Click on "Refine By >" 4. Click in the Brands text box. At this point a large scrolling list of brands (800+) should appear. 5. Without typing anything, use the mouse to scroll down the list of brands by dragging the slider. 6. Move the mouse pointer outside the list to a black area of the Refine By dialog. 7. Click. At this point the list of brands should disappear.

    Is this not what you are seeing?

  • willdonovan

    willdonovan February 23rd, 2009 @ 04:03 AM

    added the following to the onBlur functions and so far it is all working fine:

    if ( element != null ) {

    setTimeout(this.hide.bind(this), 250);
    this.hasFocus = false;
    this.active = false;
    
    

    }

  • Akio

    Akio February 23rd, 2009 @ 10:43 AM

    Hey AJ,

    I could swear I saw the suggestion list just sit there and not go away. But I cant seem to reproduce how.

    Anyway, It would be great if you could post the code here. That would help a lot

    I appreciate your help and contribution.

    Thanks! Akio

  • AJ

    AJ March 5th, 2009 @ 07:45 PM

    All right, it's a fair deal of code. We assume the autocompleter pointed to by the variable "autocompleter", and then hack it to behave properly, since I'm not sure how interested Thomas is in applying these patches to the code base. Of course, a proper bug fix would change this code directly in the controls.js file.

    1. Fixing the hovering problem. @@@javascript Autocompleter.Base.prototype.render = function() {
        if(this.entryCount > 0) {
          if (this.selected_item)
            Element.removeClassName(this.getEntry(this.selected_item-1),"selected");
          Element.addClassName(this.getEntry(this.index),"selected");
          this.selected_item = this.index+1;
          if(this.hasFocus) {
            this.show();
            this.active = true;
          }
        } else {
          this.active = false;
          this.hide();
        }
      };
      
      
    
    
    2. Speeding up list construction
    * Rather than adding observers to every LI, we add them once to the entire div.
    @@@javascript
    Event.observe('the_autocomplete_div', "mouseover", autocomplete.onHover.bindAsEventListener(autocomplete));
    Event.observe('the_autocomplete_div', "click", autocomplete.onClick.bindAsEventListener(autocomplete));
    
    • Then we make onHover slightly more forgiving. @@@javascript Autocompleter.Base.prototype.onHover = function(event) {
         var element = Event.findElement(event, 'LI');
         if(element && defined(element.autocompleteIndex) && this.index != element.autocompleteIndex) {
           this.index = element.autocompleteIndex;
           this.render();
         }
         Event.stop(event);
      
      
      };
    
    (only change here it to make sure that the mouse was actually over an LI in the DIV before doing anything)
    
    * Finally, we update the addObservers function so that it does nothing when it is invoked for every element by updateChoices.
    @@@javascript
         Autocompleter.Base.prototype.addObservers = Prototype.emptyFunction;
    
    1. Fixing weird IE behavior. @@@javascript if (Prototype.Browser.IE) {
      Autocompleter.Base.prototype.onBlur = function(event) {
        setTimeout((function(e) {
              if (this.dontBlur) {
                this.dontBlur = false;
                return;
              }
              this.hasFocus = false;
              this.active = false;
              this.hide();
            }).bind(this), 100);
      };
      
      

      }

      // then after the autocompleter object is instantiated if (Prototype.Browser.IE) { $('the_autocomplete_div').observe('mousedown', (function(e) {

         autocomplete.dontBlur = true;
         e.stop();
       });
      
      
      $('the_autocomplete_div').observe('blur', (function(e) {
         setTimeout((function() {
             if (! $('the_input_box').focused)
               this.onBlur(e);
           }).bind(this), 100);
         e.stop();
       }).bindAsEventListener(autocomplete));
      
      
      $('the_input_box').observe('focus', function() { $('the_input_box').focused = true; }); $('the_input_box').observe('blur', function() { $('the_input_box').focused = false; }); } else { $('the_autocomplete_div').observe('mousedown', function(e) {
         e.stop();
       });
      
      
      }
    
    
    Apologies for typos and erroneous formatting. I couldn't find a preview button, and am adapting this from my own code. Also, the "focused" field added to the input box mirrors the autocompleter's hasFocus and activate fields somewhat, but their semantics appear to be a bit different, so I had to add this additional field to get things to work. I'm sure there's a more elegant solution involving those existing fields.
    
  • AJ

    AJ March 5th, 2009 @ 07:46 PM

    All right, it's a fair deal of code. We assume the autocompleter pointed to by the variable "autocompleter", and then hack it to behave properly, since I'm not sure how interested Thomas is in applying these patches to the code base. Of course, a proper bug fix would change this code directly in the controls.js file.

    1. Fixing the hovering problem.
    
         Autocompleter.Base.prototype.render = function() {
             if(this.entryCount > 0) {
               if (this.selected_item)
                 Element.removeClassName(this.getEntry(this.selected_item-1),"selected");
               Element.addClassName(this.getEntry(this.index),"selected");
               this.selected_item = this.index+1;
               if(this.hasFocus) {
                 this.show();
                 this.active = true;
               }
             } else {
               this.active = false;
               this.hide();
             }
           };
    
    1. Speeding up list construction
    • Rather than adding observers to every LI, we add them once to the entire div.
    
    Event.observe('the_autocomplete_div', "mouseover", autocomplete.onHover.bindAsEventListener(autocomplete));
    Event.observe('the_autocomplete_div', "click", autocomplete.onClick.bindAsEventListener(autocomplete));
    
    • Then we make onHover slightly more forgiving.
    
         Autocompleter.Base.prototype.onHover = function(event) {
             var element = Event.findElement(event, 'LI');
             if(element && defined(element.autocompleteIndex) && this.index != element.autocompleteIndex) {
               this.index = element.autocompleteIndex;
               this.render();
             }
             Event.stop(event);
         };
    

    (only change here it to make sure that the mouse was actually over an LI in the DIV before doing anything)

    • Finally, we update the addObservers function so that it does nothing when it is invoked for every element by updateChoices.
    
         Autocompleter.Base.prototype.addObservers = Prototype.emptyFunction;
    
    1. Fixing weird IE behavior.
    
         if (Prototype.Browser.IE) {
           Autocompleter.Base.prototype.onBlur = function(event) {
             setTimeout((function(e) {
                   if (this.dontBlur) {
                     this.dontBlur = false;
                     return;
                   }
                   this.hasFocus = false;
                   this.active = false;
                   this.hide();
                 }).bind(this), 100);
           };
         }
    
         // then after the autocompleter object is instantiated
         if (Prototype.Browser.IE) {
           $('the_autocomplete_div').observe('mousedown', (function(e) {
               autocomplete.dontBlur = true;
               e.stop();
             });
           $('the_autocomplete_div').observe('blur', (function(e) {
               setTimeout((function() {
                   if (! $('the_input_box').focused)
                     this.onBlur(e);
                 }).bind(this), 100);
               e.stop();
             }).bindAsEventListener(autocomplete));
    
           $('the_input_box').observe('focus', function() { $('the_input_box').focused = true; });
           $('the_input_box').observe('blur', function() { $('the_input_box').focused = false; });
         } else {
           $('the_autocomplete_div').observe('mousedown', function(e) {
               e.stop();
             });
         }
    

    Apologies for typos and erroneous formatting. I couldn't find a preview button, and am adapting this from my own code. Also, the "focused" field added to the input box mirrors the autocompleter's hasFocus and activate fields somewhat, but their semantics appear to be a bit different, so I had to add this additional field to get things to work. I'm sure there's a more elegant solution involving those existing fields.

  • mindVex

    mindVex March 6th, 2009 @ 11:19 AM

    @AJ: Thanks a lot, this really saved my day. But you got a missing parenthesis in this function:

    
           $('the_autocomplete_div').observe('mousedown', (function(e) {
               autocomplete.dontBlur = true;
               e.stop();
             });
    

    The first parenthesis on "observe" is not closing.

    And I had to remove the function "defined()" from the onhover-method because I got an error saying it was "undefined" ;-)

    Nevertheless a great job!

  • Marcelo Barbudas

    Marcelo Barbudas April 9th, 2009 @ 05:42 PM

    Is there a scriptaculous version that contains this fix?

  • AJ

    AJ May 15th, 2009 @ 07:44 PM

    Hi MindVex,
    Thanks for pointing that out. I forgot to remove "defined" -- it's a helper function I use. You could replace it with the Prototype equivalent, "! isUndefined()"

  • aperrin54

    aperrin54 July 27th, 2009 @ 05:07 PM

    For me with two Autocompleter in the same windows, it works only with the first autocompleter.

    When the 1.8.3 release arrived ?

  • aperrin54

    aperrin54 July 28th, 2009 @ 10:28 AM

    The second autocompleter doesn't works even if it is alone in the windows

  • aperrin54

    aperrin54 July 28th, 2009 @ 01:16 PM

    If i put

     

    between input and div it's work ...
  • cdesign (at btinternet)

    cdesign (at btinternet) April 6th, 2016 @ 12:12 AM

    • Tag changed from autocompleter, ie, scriptaculous, scrolling to autocompleter ie scriptaculous scrolling
    • Assigned user cleared.

    In the end, I got sick of the bugs & unreliability of prototype.js scriptaculous autocompleter.

    Don't get me wrong, I love the prototype.js framework, but this particular system is flawed.
    I switched to jQuery autocomplete. It took me 5 minutes to change, and works seemlessly.

    Trust me. Just switch. It saves a whole lot of time...

  • Kennett

    Kennett May 22nd, 2018 @ 07:37 AM

    Seeing your last payment, scheduling future settlements Citicards Login that the more than 200 million clients that desire to use.

  • Hilliard

    Hilliard May 24th, 2018 @ 01:17 PM

    you need to include the right password Credit Karma Login My Account It uses various innovations suches as cookies.

  • meruveruki001 (at outlook)

    meruveruki001 (at outlook) November 24th, 2018 @ 09:07 AM

    [url=https://apkextractor.org/hungry-shark-world-mod-apk/ ] download mod apk[/url] Game Killer v6.01 is best game hacking app with or no root access required to run, download gamekiller app from this official website.

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.

Referenced by

Pages