55

Currently I am using jQuery to hide/show select options using following code.

$("#custcol7 option[value=" + sizeValue + "]").hide();

This works fine in Firefox, but doesnt do any good in other browsers. How to I hide options from select in Chrome, Opera and IE?

Kara
  • 6,115
  • 16
  • 50
  • 57
ITRushn
  • 555
  • 1
  • 6
  • 10
  • This good walkthrough solves the problem: http://fiddle.jshell.net/2tAqe/ – Flo. Jul 24 '12 at 01:21
  • 1
    @Flo.: That "works" by creating an invalid DOM structure and hoping the browser handles it properly. Bad. Idea. – T.J. Crowder Sep 20 '15 at 15:07
  • The OP's code above works fine now in Chrome 62 and Edge 41. In IE 11, it sets "style=display:none;" on the option but doesn't actually hide it. – Russell G Nov 22 '17 at 15:42
  • 1
    $('#someoption').hide() works in FireFox and Chrome, but doesn't work in Internet Explorer and Edge – jocassid Jun 13 '18 at 17:10

18 Answers18

44

I just came across this and instead of cloning the entire select over and over I just replaced the options that need to be hidden with span elements and hiding the spans ( though the browser didnt visually show them anyway, I think ) - you may need to change your code ( if complex ) to iterate through the spans for complex logic.

The spans store a reference to the option and replace themselves with it when they need to be shown.

This code can obviously be refactored and prettified.

http://fiddle.jshell.net/FAkEK/12/show/

EDIT #2 ( USE THIS INSTEAD ): It occurred to me that instead of doing all this clone/reference/replace crap, just wrap the option with a span, hide the span, and on show just replace the span with the option again..

http://fiddle.jshell.net/FAkEK/25/show/

meder omuraliev
  • 183,342
  • 71
  • 393
  • 434
31

I think meder has provided valid answer and here it is slightly changed to reflect what works for me:

$.fn.optVisible = function( show ) {
    if( show ) {
        this.filter( "span > option" ).unwrap();
    } else {
        this.filter( ":not(span > option)" ).wrap( "<span>" ).parent().hide();
    }
    return this;
}

Tested with (long live BrowserStack):

  • Windows XP: IE 6.0, Firefox 3.0, Safari 4.0, Opera 10.0, Chrome 14.0
  • Windows 8: IE 10.0 Metro
  • iOS 3.2 (iPad), iOS 6.0 (iPhone 5)
  • Android 1.6 (Sony Xperia X10)

jsfiddle

nrodic
  • 3,026
  • 3
  • 33
  • 38
  • 4
    Be careful when using a .val() on the selector with this method because it'll return the hidden value instead of the selected. [jsfiddle](http://jsfiddle.net/rjPeU/) – mhoofman Mar 03 '13 at 21:10
11

You don't, it's not supported in IE (and assumably not in Chrome or Opera either). You would have to remove the options altogether and add them back later if you want them to be truly invisible. But in most cases a simple disabled="disabled" should suffice and is a heck of a lot simpler than handling the removing and adding of options.

Tatu Ulmanen
  • 123,288
  • 34
  • 187
  • 185
  • IIRC, you can't disable options in IE6 or IE7 (was fixed in IE8) http://webbugtrack.blogspot.com/2007/11/bug-293-cant-disable-options-in-ie.html – scunliffe Jan 09 '10 at 00:41
  • 31
    Duuummbbb!!! I hate IE with a passion. They can't get anything right!! Freaking text and password boxes aren't even the same width by default for no apparent reason!? Rounded corners don't work? Nothing lines up properly... I don't get it !! – mpen Apr 22 '10 at 07:42
  • 1
    @Mark: For serious... Why do they even bother? – Andy Oct 10 '11 at 19:31
  • For clarity, regarding the 'disabled' approach, in jQuery, that code would be `$("#custcol7 option[value=" + sizeValue + "]").prop('disabled', true);` – jay May 19 '16 at 18:56
10

try detach(). you can reattach it later if needed using append() or insertAfter()

murraybiscuit
  • 839
  • 7
  • 15
  • interesting... didn't know about this functionality :-) – Zathrus Writer Nov 03 '10 at 20:35
  • 1
    The problem with this is that if you want to hide specific options in the middle of the menu, it's way too much work to try to insert them back into their original places. – BadHorsie Sep 13 '12 at 16:32
8

To Remove options use:

var opt=$("option").detach();

To show options use:

opt.appendTo( "select" );
Sachin B. R.
  • 941
  • 4
  • 16
  • 30
  • 1
    This seems to be the valid HTML and a simple elegant solution. `opt` will be an array of `option` elements which can be added back to the `select` element using appendTo.I wish this answer could be bumped up or selected as the Best answer since the other solutions up there just threw me off for a while, and are either valid or straight forward. Thanks Sachin. – Babak K Jan 20 '17 at 20:36
3

Just deleted it and store it in a var in your JavaScript. You can just create the new object when you need it later.

Otherwise try the disabled attribute mentioned above.

JP Silvashy
  • 46,977
  • 48
  • 149
  • 227
2
/**
* Change visibility of select list option elements
* @param  {boolean}   stateVal      show hidden options if true; hide it otherwise. If not setted then toggle visibility, based on it's current state
*/
$.fn.toggleOptionVisibility = function (stateVal) {
    var isBool = typeof stateVal === "boolean";
    return this.each(function () {
         var $this = $(this);
         if (isBool) {
             if (stateVal) $this.filter("span > option").unwrap();
             else $this.filter(":not(span > option)").wrap("<span>").parent().hide();
         }
         else {
             $this.filter("span > option").toggleOptionVisibility(true);
             $this.filter(":not(span > option)").toggleOptionVisibility(false);
        }
    });
};
AuthorProxy
  • 7,946
  • 3
  • 27
  • 40
2

the way you did it should work in chrome but nvm.Here is another way

select = $('#custcol7');
select.find('option[value=["'+sizeValue +'"]').remove();

and if you want to show it again:

select.append('<option value="'+sizeValue+'"></option>');

It works perfectly on every browser and its really simple code. The problem is if you want to hide several options it is more typing .. but that can be solved by putting them into variables if they don't change dynamically like that :

var options = '<option value="'+sizeValue1+'"></option><option value="'+sizeValue2+'"></option><option value="'+sizeValue3+'"></option>';

select.append(options);

This way if you have to remove/append on several places you only typed the options once.Hope i gave another interesting option. Best Regards.

Lachezar Raychev
  • 2,113
  • 4
  • 24
  • 34
1

using the solution provided by AuthorProxy, it works fine for IE but when I attempt to do a .val() on the dropdown in firefox I get some funky values that don't make any sense. I have modified their option to include browser specific functionality, hide/show works for firefox.

$.fn.toggleOptionVisibility = function (stateVal) {
    var isBool = typeof stateVal === "boolean";
    return this.each(function () {
        var $this = $(this);
        if (navigator.userAgent.indexOf('MSIE') > -1 || navigator.userAgent.indexOf('Trident') > -1) {
            if (isBool) {
                if (stateVal) $this.filter("span > option").unwrap();
                else $this.filter(":not(span > option)").wrap("<span>").parent().hide();
            }
            else {
                $this.filter("span > option").toggleOptionVisibility(true);
                $this.filter(":not(span > option)").toggleOptionVisibility(false);
            }   
        }
        else {              
            if (isBool) {
                $this.show();
            }
            else {
                $this.hide();
            }
        }
    });
};
Chris Brickhouse
  • 650
  • 5
  • 15
1

My take is bit different to other answers.

The aim is not to hide the options but just make them disable(to keep the UI consistent).

My Scenario :

I have multiple selects in a form and when an user selects an option in one of the selects the other selects should disable this option and vice versa. User is restricted from selecting the same option which is already selected. We normally disable the option but for IE 7 which does not support it. User also gets an option to add new selects.

Solution :

On load :

If the browser is IE7 then while populating the the selects and disabling the already selected options on other selects I am adding a custom attribute to the option("data-ie7-disabled") and also changing the color of the disabled options to '#cccccc'(which is the standard color for disabled options). This makes the UI look same across browsers.

On Change :

I save the previous option in a local variable(this is saved on focus).

When a user tries to change an option

  1. User selects a complete new option which is not selected in any other dropdown. Then I loop through other selects and change the color and add custom attribute to this selected option on other selects.

  2. When user selects an option that is already selected(The option which has grayed out color). I check if the option has this custom attribute on it first. If it has then > I simply revert the option to the previous one with an error message saying "This option is already selected or BLAH BLAH".

  3. When user changes his existing option to a brand new option which is not selected in any other dropdown's. I again loop through all the other select options and remove the color on it and also the custom attribute.

Hope this helps.

Venkata K. C. Tata
  • 5,539
  • 4
  • 22
  • 35
1

You can use through combinations of var $opt=$('select>option').clone() and $('select option[value="'+val+'"').remove(). There is another example: try this. https://jsfiddle.net/sherali/jkw8fxzf/12/

var $secondOption= $('#second-choice>option').clone();

$("#first-choice").change(function() {
    var userSelected = $(this).val();

    $('#second-choice').html($secondOption);
    $('#second-choice option[value="'+userSelected+'"').remove()
});
Sherali Turdiyev
  • 1,745
  • 16
  • 29
1

There's also the the .load method:

s_parent.change(function(){
   s_child.load('./fetch_options.php",{'v',s_parent.val()});
}

The 'fetch_options.php' script would simply print the option tags based on whatever data source you use and the parent value(s) being passed in.

mstone42
  • 49
  • 2
  • This AJAX technique I've found to work very well indeed, and resolves all the browser inconsistency issues (at the minor cost of another call to the server). – RET Jul 08 '11 at 03:41
0

You will need to remove it and then add it again for Internet Explorer.

To remove:

$("#custcol7 option[value=" + sizeValue + "]").remove();

To add:

$("#custcol7").append( "<option value='sizeValue'>sizeValue</option>" );

Note that you need to have sizeValue also in the option text, to actually see something.

Aris
  • 4,643
  • 1
  • 41
  • 38
0

You can also replace the html within the select.

Html:

<input id="Button1" type="button" value="hide option" />

<select id="foo">
<option >stuff</option>
<option >stuff2</option>
</select>

Jquery:

    $("#Button1").change(function () {
       $('#foo').html('<option >stuff</option>');
    });

Not exactly what you want, but perhaps it helps. For smaller dropdowns, it is definitely easier.

mr.Eli
  • 1
  • 3
0

In IE 11(Edge), the following code is working.

 $("#id option[value='1']").remove();

and to ad back,

$('<option>').val('1').text('myText').appendTo('#id');
Jobin Mathew
  • 124
  • 1
  • 8
0

meder's solution is what I went with for this, but with a small tweak to prevent it from wrapping an option in a span that was already in a span:

$.fn.hideOption = function() {
    this.each(function() {
        if (!$(this).parent().is('span')) {
            $(this).wrap('<span>').hide();
        }
    });
};
$.fn.showOption = function() {
    this.each(function() {
        var opt = $(this).find('option').show();
        $(this).replaceWith(opt);
    });
};
gazchap
  • 23
  • 6
0
    <html>
    <head><script> 
    $(document).ready(function(){
    $("#l1").change(function(){
            var selectedId=$("#dl1 option[value='"+$(this).val()+"']").attr("id");
            $("#dl2 option[data-id ='"+selectedId+"']").removeAttr('disabled');
            $("#dl2 option[data-id !='"+selectedId+"']").attr('disabled','disabled');
            $("#l2").val("");
    });
    });
    </script></head>
    <body>
    <label for="l1">choose country</label>
    <input list="dl1" name="l1" id="l1" type='select'>
        <datalist id="dl1" name="dl1">
            <option value="India" id=1>
            <option value="US" id=2>
            <option value="Germany" id=3>
        </datalist>
    <br>
    <label for="l2">choose City</label>
    <input list="dl2" name="l2" id="l2" type='select'>
        <datalist id="dl2">
            <option value="New Delhi" id="11" data-id="1">
            <option value="Washington DC" id="12" data-id="2">
            <option value="Berlin" id="13" data-id="3">
            <option value="Mumbai"id="14" data-id="1">
            <option value="NewYork" id="15" data-id="2">
            <option value="Munich" id="16" data-id="3">
        </datalist>
    </body>
    </html>
  • 6
    Thank you for taking the time to provide a solution. Code-only answers are discouraged. Please provide some context to your answer and describe why your approach is preferable to the other 17 (as of this point) answers. – DaveL17 May 16 '21 at 11:43
-1

You can use this:

$("#custcol7 option[value=" + sizeValue + "]").css({display:'none'});

It works fine on all browsers except Safari and Opera. I'm searching for another best solution :)

LaurentG
  • 11,128
  • 9
  • 51
  • 66