JQuery UI autocomplete not scrolling with arrow keys in Firefox
Asked Answered
O

3

9

I am working with the JQuery UI autocomplete 1.8 with JQuery 1.6.1. (Getting newer versions of software is extremely difficult in my company so I am stuck with these.)

I have a long list of strings placed in the autocomplete pane, so I styled the .ui-autocomplete class like this

.ui-autocomplete {height:200px; overflow-y:scroll; overflow-x: hidden;}

Now when the autocomplete dropdown pops up it, it has a scroll bar as desired. However, when I use arrow keys to navigate the dropdown, the panel does not scroll with the selection. The selections still happen. Eventually I run off the bottom of the list and the cursor is returned to the top. Everything behaves as expected except that the scroll pane does not scroll.

In tests outside of work where I have access to other browsers, I find that chrome scrolls properly and IE 8 scrolls properly. Is this a bug with the firefox 3.6 linux browser or am I missing something?

I am handcuffed to Firefox 3.6 ua:(Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv1.9.2.12) Gecko/20101026 Firefox/3.6.1.2)

Is this a bug with this version of the browser or am I missing something?

EDIT: I was able to find a machine with ie6 and one with firefox 3.5.3. ie6 scrolled and firefox 3.5.3 did not. It appears it might be an issue with firefox.

Overexpose answered 12/8, 2011 at 20:19 Comment(6)
Have you found a solution to this? Having the same problemInfiltration
No, I have not. I'm surprised that I have not gotten any response on this.Overexpose
Same here. +1 on the question. Hopefully someone has an answerInfiltration
What version of jQuery UI are you running? it appears to work fine in the latest (tested on Chrome): jsfiddle.net/69uk3/3Hildebrand
See first sentence in above post. "I am working with the JQuery UI autocomplete 1.8 with JQuery 1.6.1.". With that nonsense out of the way, the behavior does not change on jquery 1.7.0.Overexpose
Had the same issue with IE8 / jQueryUI v1.8.11. Upgraded to v1.8.21 and it is fixed.Glamour
A
5

I had similar issue with our app running on jQuery v1.7.2 and jQuery UI v1.8.11 on any browser. However I have found out that it was fixed on jQuery UI v1.8.13 changelog.

So according to the fix in the changeset, all I did was just override two functions as below and it fixes the issue.

$.widget("ui.menu", $.extend({ }, $.ui.menu.prototype, {
activate: function (event, item) {
    this.deactivate();
    if (this.hasScroll()) {
        var offset = item.offset().top - this.element.offset().top,
            scroll = this.element.scrollTop(),
            elementHeight = this.element.height();
        if (offset < 0) {
            this.element.scrollTop(scroll + offset);
        } else if (offset >= elementHeight) {
            this.element.scrollTop(scroll + offset - elementHeight + item.height());
        }
    }
    this.active = item.eq(0)
                      .children("a")
                      .addClass("ui-state-hover")
                      .attr("id", "ui-active-menuitem")
                      .end();
    this._trigger("focus", event, { item: item });
},

hasScroll: function () {
    return this.element.height() < this.element[$.fn.prop ? "prop" : "attr"]("scrollHeight");
}}));
Attainable answered 28/11, 2012 at 22:38 Comment(0)
F
2

Solution: Upgrading to jQuery UI 1.8.18 fixed this problem for me.

This isn't an answer but it might provide more information on the issue. If you follow the calls when you press the up or down keys when the menu is open, you get to the activate method of the menu widget which calls the hasScroll method (Line 5487 using v1.8.11);

hasScroll: function() {
    return this.element.height() < this.element.attr("scrollHeight");
},

It seems like the problem is that the scrollHeight attribute is not defined for the menu ul element and thus this method always returns false.

Here is the activate method:

activate: function( event, item ) {
        this.deactivate();
        if (this.hasScroll()) {
            var offset = item.offset().top - this.element.offset().top,
                scroll = this.element.attr("scrollTop"),
                elementHeight = this.element.height();
            if (offset < 0) {
                this.element.attr("scrollTop", scroll + offset);
            } else if (offset >= elementHeight) {
                this.element.attr("scrollTop", scroll + offset - elementHeight + item.height());
            }
        }
        this.active = item.eq(0)
            .children("a")
                .addClass("ui-state-hover")
                .attr("id", "ui-active-menuitem")
            .end();
        this._trigger("focus", event, { item: item });
    }

Even if you force the hasScroll method to return true, you run into another problem as the scrollTop attribute is not defined either.

I'll let you know if I figure out a solution to this as it is plaguing my application as well.

Fr answered 21/12, 2011 at 18:1 Comment(1)
If I can get a hold of jQuery UI 1.8.18, I will give it a try and accept the answer if it works!Overexpose
R
0

I noticed that this.element.attr("scrollHeight") in

hasScroll: function () {
        return this.element.height() < this.element.attr("scrollHeight");
    },

returns undefined. If you change this.element.attr("scrollHeight") to this.element.prop("scrollHeight") instead, you will get a scrollHeight.

But then the same problem appears in activate: function (event, item) {, so you will also need to change all occurrences of

this.element.attr("scrollTop") to this.element.prop("scrollTop")

in that function as well to make it work.

You can read about .prop() in the jQuery API but basically the reason for this is

Before jQuery 1.6, the .attr() method sometimes took property values into account when retrieving some attributes, which could cause inconsistent behavior. As of jQuery 1.6, the .prop() method provides a way to explicitly retrieve property values, while .attr() retrieves attributes.

Research answered 1/3, 2012 at 12:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.