17

The following behaves differently between jQuery 1.9 and 1.10+:

<select id="s1">
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
</select>

$('#s1 option[value=1]').hide();
$('#s1').val('');

The idea behind this code is to select the first non-hidden option, after hiding some options, including the currently selected one.

Since jQuery 1.10+ the $('#s1').val(''); no longer selects the first non-hidden option, while .val(<some proper value for the particular select box>) works ok.

Trying the following approaches does not help because both selectedIndex and .first().val() consider the hidden options:

$("#s1").prop("selectedIndex", 0);

$('#s1 option').first().prop('selected', true);

Next thing that comes to mind (also suggested by C-link) also does not work, because the :visible selector does not work properly for select options.

$('#s1 option:visible').first().prop('selected', true);

Looking for some generic way (not depending on knowledge of what are the particular values and what options have been hidden) to achieve the same behaviour as $('#s1').val(''); in old jQuery.

Community
  • 1
  • 1
bbonev
  • 1,406
  • 2
  • 16
  • 33

6 Answers6

16

Compiled from everybody else's answers/comments the following:

$('#s1 option').each(function () {
    if ($(this).css('display') != 'none') {
        $(this).prop("selected", true);
        return false;
    }
});
bbonev
  • 1,406
  • 2
  • 16
  • 33
13

Shortly Like this:

$('#s1').find("option:not(:hidden):eq(0)");
israr
  • 1,155
  • 15
  • 28
2

Try this:

<select id="s1">
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
</select>

$('#s1 option[value=1]').hide();

var firstVisibleValue = '';
$('#s1').children().each(function(){  //iterate options

    //check if option is visible - if not set to display none, which is what `.hide` does.
    if($(this).css('display') != 'none'){  
        firstVisibleValue = $(this).val();
        return false;   //stop iterating
    }
});
$('#s1').val(firstVisibleValue);
p e p
  • 6,593
  • 2
  • 23
  • 32
  • Instead the global `firstVisibleValue = $(this).val();` it may just `$('#s1').val($(this).val())`; anyways I am starting to consider regenerating the whole boxes instead of hide/show-ing options – bbonev Jun 27 '14 at 05:23
2

maybe this:

$('#s1').find("option:not([hidden]):eq(0)");
Matheus B.
  • 29
  • 4
  • 1
    Yes. It works but it should be in the following format: `$('#s1').find("option:not(:hidden):eq(0)");` Instead of `[hidden]` it should be `:hidden` – israr Nov 06 '15 at 06:55
  • In what version? As seen in this fiddle, in both 1.9.1 and 1.10.0 versions it works properly using the [hidden] attribute selector. – Matheus B. Nov 24 '16 at 16:48
1

You can easily do this using class

$('#s1 option[value=1]').hide();
$('#s1 option[value=1]').addClass('hidden');
$('#s1 option[value=1]').removeClass('visible')
$('#s1').val('');
$('#s1 .visible:first').val();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="s1">
    <option class="visible" value="1">1</option>
    <option class="visible" value="2">2</option>
    <option class="visible" value="3">3</option>
</select>
Bhargav Chudasama
  • 6,928
  • 5
  • 21
  • 39
  • Good suggestion, I changed it to a class and it just worked as expected. I would simplify it by having a single class called 'hidden' and use CSS .hidden {display: none;}. – dashingdove Jun 15 '23 at 10:02
-1

Try this code

$('#s1 option[value="1"]').hide();

$('#s1').find('option').each(function()
 {
if($(this).is(':visible'))
{
    $(this).attr("selected","selected");
    return false;
}
 });
Unknownman
  • 473
  • 3
  • 9