23

I'm looking for a workaround for a rendering bug in Chrome. It shows up when a select element has about 90%+ hidden option elements. In Chrome, the dropdown height becomes too short to use. This does not appear to happen on other browsers. View example on jsFiddle.

img

HTML Example
Note: Some options were removed to keep the code brief.
The bug does not show up unless all options are present.

100 Options, 90% Hidden:<br>
<select>
<option value="">Select an Option</option>
<option value="0" style="display: none">Option 0</option>
<option value="1" style="display: none">Option 1</option>
<option value="2" style="display: none">Option 2</option>
<option value="3" style="display: none">Option 3</option>
<!-- Options removed for brevity. -->
<option value="86" style="display: none">Option 86</option>
<option value="87" style="display: none">Option 87</option>
<option value="88" style="display: none">Option 88</option>
<option value="89" style="display: none">Option 89</option>
<option value="90">Option 90</option>
<option value="91">Option 91</option>
<option value="92">Option 92</option>
<option value="93">Option 93</option>
<option value="94">Option 94</option>
<option value="95">Option 95</option>
<option value="96">Option 96</option>
<option value="97">Option 97</option>
<option value="98">Option 98</option>
<option value="99">Option 99</option>
</select>

Browsers Tested:

  • Chrome 27 & 28 (Fail)
  • Firefox 21 (Pass)
  • IE 9 (Pass)
  • Opera 12 (Pass)
  • Safari 5.1 (Pass)

View Example on jsFiddle
Alternate Example Link

Update: I did some reading on the subject, and apparently options are not supposed to be hidden within a select. You can disable options, but they will not disappear. If you don't want an option to be in the select at all, you're supposed to remove the node entirely. The ability to hide options doesn't appear to work completely cross-browser, and in most you can continue to select the "hidden" options by using the arrow keys. I need to toggle options on and off, which makes this inconvenient to my particular situation, but this appears to be the only method that will work thus far.

Community
  • 1
  • 1
Jordan Mack
  • 8,223
  • 7
  • 30
  • 29
  • 4
    You caught a good bug! – frenchie Jun 20 '13 at 01:27
  • @frenchie Thanks. I've already reported it to Google, but I still need to find a workaround in the mean time. – Jordan Mack Jun 20 '13 at 01:33
  • Chrome 28 on Mac displays both the same, it shows all the hidden items. – Barmar Jun 20 '13 at 01:34
  • Thank you for the update on why Chrome doesn't support this. Good to know; although I still think that hiding options should be supported! If you have a lot of options, you don't to write code that wastes time removing the elements and putting them back in. – levininja Mar 19 '15 at 18:40
  • 1
    Looks like this Chrome bug is fixed! – frenchie May 13 '15 at 07:44
  • 1
    I think this bug is back in Chrome 78, I've filed a report to Google, here's a JS Fiddle of the new bug (needs more than 100) http://jsfiddle.net/e7Lburzg/ – Budd Nov 18 '19 at 03:08
  • @Budd Your example also shows the issue for me on Chrome Version 78.0.3904.108. On Firefox it renders properly, but it lags it for several seconds. – Jordan Mack Nov 18 '19 at 22:56

7 Answers7

3

Adding this might be considered a workaround:

 $(document).ready(function () {

    $('#ph2').mouseenter(function () {

      var html = '';

        $(this).find('option').each(function () {

            if ($(this).css('display') !== 'none') {

                html = html + '<option>' + $(this).text() + '</option>';   
            }
        });

        $(this).html(html);
    })
});

Here's the jsFiddle; I'm using jquery just for simplicity. In this case, I'm just redoing the HTML on mouseenter. It's not ideal but it could get you going further. Also, note that you have ph2 set up as a div in your HTML; I think you should set it as a select element from the start and on the fiddle you can see the change I made to the html. But overall, until the bug is fixed, I think something like this is going to be as close as you'll get to having a working option.

frenchie
  • 51,731
  • 109
  • 304
  • 510
  • 3
    +1 for a working fix. I need to be able to toggle the options, which doesn't make things that easy with a fix like this. It actually appears that this is less a bug, and more undefined functionality. I updated my answer to include this info. – Jordan Mack Jun 20 '13 at 01:59
  • Well then maybe you can store the options in a key-value object. In this object you'd keep track of what's toggled visible, and then redo the HTML with that object on click or mouseenter. Take a look at my other answer here: http://stackoverflow.com/questions/17076429/why-is-this-simple-function-not-working for the object pattern. – frenchie Jun 20 '13 at 02:03
  • This works for me the first time, but because I'm also changing which values are hidden separately on the page, the 'html' doesn't store any future items which might be selected, any ideas how i'd go about getting around this? – Ed Harrod May 29 '14 at 08:52
  • Well then store the state of each option in a separate object and use that object to determine which options to include in the HTML when regenerating the element. You can use key:value where key is the option and value stores whether or not the option is visible. See the answer in my comment above. – frenchie May 29 '14 at 10:49
2

The problem is already active on all major browser (Edge, Chrome, Opera,....) but Firefox. The problem arises as soon as the number of hidden items is greater than 1000. Be careful, because with just 100 items, all browser seem to work

The problem also disappears if the active items (not hidden, not disabled) are at the top of the list. More exactly, when you click on the "select" input field, the browser open a list with a number of rows that is equal to the number of active items included in the first 1000 item. For example, if you build a list of items with first x items active, then y items "inactive" (where y if greater than 1000) and then again z items active, you will see a list wide x rows with x+z items.

By the way, a workaround to the problem could be the sorting of the items list

This behaviour has been verified on Chrome, Opera, Edge

cyMimmo
  • 21
  • 2
1

As a workaround for this bug I can propose the following solution:

  • To hide an option 'convert' it to some other tag and hide it with .hide().
  • To show an option 'convert' it back to option and show it with .show().

For 'conversion' we need something like this: https://stackoverflow.com/a/9468280.

Example:

// some `replaceTagName` implementation here

// hiding options
$('.option-selector').replaceTagName('span').hide();

// showing options
$('.option-selector').replaceTagName('option').show();

A bit heavy but working :)

Community
  • 1
  • 1
1

I had this problem and this is what I did:

var originalSelect = $("#the_select").clone();

function hideSomeOptions(){
  $('#the_select .hide_me').remove();
}

function restoreAllOptions(){
  $("#the_select").replaceWith(originalSelect[0]);
}

The target select input has the ID "the_select" and the options or optgroups that need to be toggled have the "hide_me" class.

Sebastián Grignoli
  • 32,444
  • 17
  • 71
  • 86
0

I found that the order of the hidden/visible options make a difference. It is like chrome stops counting for the height for the drop down at the first hidden option. One way around is to move the shown options to the top of the select. If you are using jquery something like this.

var select = "select#MySelect";
$(select).children("option").hide();  //hide all options
$(select).children("Selector for items to show").each(function(idx, elm) {
           $(elm).parent().prepend(elm);  //move item to the top of parent
});
$(select).children("Selector for items to show").show(); //show selected options
Robert
  • 9
  • 2
  • This solution does not account for the issue that you can still select the hidden options with the keyboard. It's easy to fix, anyway: add .prop({"disabled":true}) to the second line. – Sebastián Grignoli May 13 '15 at 05:16
0

I ran into the same problem (Chrome 40) and found that the following workaround works well for me.

var originalOptions = [];

$(document).ready(function(){
    originalOptions = $("yourSelect").children("option");

    $("someElement").someEvent(function(){
        $("yourSelect").children("option").remove();
        $(originalOptions).each(function(){
            if(/*criteria here*/){$("yourSelect").append($(this));}
        });
    });
});
KST
  • 164
  • 2
  • 13
-1

The best fix is to add at the end on the last

<option></option> in your Select Element. Add this code:

<optgroup></optgroup>

This will add a blank group element, and for now is the best Easy and fast FIX to this rare BUG.

Thanks!

pqsk
  • 2,124
  • 3
  • 23
  • 28