jQuery setting prop("selected", true) on multi select list in Chrome only works once

kavun picture kavun · Oct 4, 2012 · Viewed 57.1k times · Source

When trying to set a select list option to selected in order to scroll the select list to that option, it works in all browsers except for Chrome. In Chrome it works once, but successive times do not work in Chrome. How can I ensure that setting the selected attribute of an option in a select list will scroll that option into view?

Here is an example of my issue - http://jsfiddle.net/Z2rQG/

The code I am using to select an option in a list to scroll it into to view is as follows:

(function ($) {
    $.fn.scrollToOption = function (option) {
        var _option = $(option, this);
        // if option is in list
        if(_option) {
            // store the selection state
            var isSelected = _option.is(":selected");

            _option.prop("selected", true); // scroll to the option
            _option.prop("selected", isSelected);  // restore the selection state
        }
        return this;
    };
})(jQuery); 

Edit: I have also tried the scrollTo jQuery plugin, which does not work as well in Chrome. Here is an example - http://jsfiddle.net/kavun/TW4XK/

Edit: Here is a clearer example of what I am trying to do. Select two options from a select list and have the list be scrolled to the last selected option. This works in all browsers except Chrome and Safari. In Chrome the first selection scrolls to the option but the second $('#select option[value=""].prop('selected', true); does not scroll the list - http://jsfiddle.net/kavun/uhnZH/

Answer

Tim Down picture Tim Down · Oct 8, 2012

Browser behaviour is inconsistent with regard to which option is scrolled into view when multiple options are selected. However, selecting the option using its selected property plus setting the selectedIndex property of the <select> element seems to make sure the select is scrolled to the right place in all major browsers. Using this, you can get the correct vertical scrolling, select the options you want and then scroll the select manually.

Opera does not seem to fully support scrollTop for select elements, so this solution does not work in Opera.

Demo: http://jsfiddle.net/uhnZH/10/

Code:

function selectAndScrollToOption(select, option) {
    $select = $(select);

    // Store the currently selected options
    var $selectedOptions = $select.find("option:selected");

    // Select the new option using its selected property and selectedIndex.
    // This seems to make the select scroll to the desired place in all major
    // browsers
    option.selected = true; // Required for old IE
    select.selectedIndex = option.index;

    // Measure the vertical scrolling
    var scrollTop = $select.scrollTop();

    // Re-select the original options
    $selectedOptions.prop("selected", true);

    // Scroll to the correct place
    $select.scrollTop(scrollTop);
}