How can I hide select options with JavaScript? (Cross browser)

This should work:

$('option').hide(); // hide options

It works in Firefox, but not Chrome (and probably not in IE, not tested).

A more interesting example:

<select>
    <option class="hide">Hide me</option>
    <option>visible option</option>
</select>
<script type="text/javascript">
// try to hide the first option
$('option.hide').hide();

// to select the first visible option
$('option:visible').first().attr('selected', 'selected');
</script>

Or see the example at http://jsfiddle.net/TGxUf/

Is the only option to detach the option elements from the DOM? I need to show them again later, so this would not be very effective.

Answers:

Answer

Unfortunately, you can't hide option elements in all browsers.

In the past when I have needed to do this, I have set their disabled attribute, like so...

$('option').prop('disabled', true);

I've then used the hiding where it is supported in browsers using this piece of CSS...

select option[disabled] {
    display: none;
}
Answer

As has been said, you can't display:none individual <option>s, because they're not the right kind of DOM elements.

You can set .prop('disabled', true), but this only grays out the elements and makes them unselectable -- they still take up space.

One solution I use is to .detach() the <select> into a global variable on page load, then add back only the <option>s you want on demand. Something like this (http://jsfiddle.net/mblase75/Afe2E/):

var $sel = $('#sel option').detach(); // global variable

$('a').on('click', function (e) {
    e.preventDefault();
    var c = 'name-of-class-to-show';
    $('#sel').empty().append( $sel.filter('.'+c) );
});

At first I thought you'd have to .clone() the <option>s before appending them, but apparently not. The original global $sel is unaltered after the click code is run.


If you have an aversion to global variables, you could store the jQuery object containing the options as a .data() variable on the <select> element itself (http://jsfiddle.net/mblase75/nh5eW/):

$('#sel').data('options', $('#sel option').detach()); // data variable

$('a').on('click', function (e) {
    e.preventDefault();
    var $sel = $('#sel').data('options'), // jQuery object
        c = 'name-of-class-to-show';
    $('#sel').empty().append( $sel.filter('.'+c) );
});
Answer

Had a crack at it myself and this is what I came up with:

(function($){

    $.fn.extend({detachOptions: function(o) {
        var s = this;
        return s.each(function(){
            var d = s.data('selectOptions') || [];
            s.find(o).each(function() {
                d.push($(this).detach());
            });
            s.data('selectOptions', d);
        });
    }, attachOptions: function(o) {
        var s = this;
        return s.each(function(){
            var d = s.data('selectOptions') || [];
            for (var i in d) {
                if (d[i].is(o)) {
                    s.append(d[i]);
                    console.log(d[i]);
                    // TODO: remove option from data array
                }
            }
        });
    }});   

})(jQuery);

// example
$('select').detachOptions('.removeme');
$('.b').attachOptions('[value=1]');');

You can see the example at http://www.jsfiddle.net/g5YKh/

The option elements are fully removed from the selects and can be re-added again by jQuery selector.

Probably needs a bit of work and testing before it works well enough for all cases, but it's good enough for what I need.

Answer

Hiding an <option> element is not in the spec. But you can disable them, which should work cross-browser.

$('option.hide').prop('disabled', true);

http://www.w3.org/TR/html401/interact/forms.html#h-17.6

Answer

You can try wrapping the option elements inside a span so that they wont be visible but still be loaded in the DOM. Like below

jQ('#ddlDropdown option').wrap('<span>');

And unwrap the option which contains the 'selected' attribute as follows to display already selected option.

var selectedOption = jQ('#ddlDropdown').find("[selected]");
jQ(selectedOption).unwrap();

This works across all the browsers.

Answer

Three years late, but my Googling brought me here so hopefully my answer will be useful for someone else.

I just created a second option (which I hid with CSS) and used Javascript to move the s backwards and forwards between them.

<select multiple id="sel1">
  <option class="set1">Blah</option>
</select>
<select multiple id="sel2" style="display:none">
  <option class="set2">Bleh</option>
</select>

Something like that, and then something like this will move an item onto the list (i.e., make it visible). Obviously adapt the code as needed for your purpose.

$('#sel2 .set2').appendTo($('#sel1'))
Answer

This is an enhanced version of @NeverEndingLearner's answer:

  • full browsers support for not using unsupported CSS
  • reserve positions
  • no multiple wrappings

$("#hide").click(function(){
  $("select>option.hide").wrap('<span>'); //no multiple wrappings
});

$("#show").click(function(){
  $("select span option").unwrap(); //unwrap only wrapped
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<select>
    <option class="hide">Hide me</option>
    <option>visible option</option>
</select>
<button id="hide">hide</button>
<button id="show">show</button>

Answer

Since you mentioned that you want to re-add the options later, I would suggest that you load an array or object with the contents of the select box on page load - that way you always have a "master list" of the original select if you need to restore it.

I made a simple example that removes the first element in the select and then a restore button puts the select box back to it's original state:

http://jsfiddle.net/CZcvM/

Answer

just modify dave1010's code for my need

 (function($){
    $.fn.extend({hideOptions: function() {
        var s = this;
        return s.each(function(i,e) {
            var d = $.data(e, 'disabledOptions') || [];
            $(e).find("option[disabled=\"disabled\"]").each(function() {
                d.push($(this).detach());
            });
            $.data(e, 'disabledOptions', d);
        });
    }, showOptions: function() {
        var s = this;
        return s.each(function(i,e) {       
            var d = $.data(e, 'disabledOptions') || [];
            for (var i in d) {
                $(e).append(d[i]);
            }
        });
    }});    
})(jQuery);

http://jsfiddle.net/AbzL3/1/

Answer

I thought I was bright ;-)

In CSS:

option:disabled {display:none;}

In Firefox and Chrome, a select with only the enabled options were created. Nice.

In IE, the enabled options were shown, the disabled where just blank lines, in their original location. Bad.

In Edge, the enabled options shown at top, followed by blank lines for disabled options. Acceptable.

Answer

On pure JS:

let select = document.getElementById("select_id")                   
let to_hide = select[select.selectedIndex];
to_hide.setAttribute('hidden', 'hidden');

to unhide just

to_hide.removeAttr('hidden');

or

to_hide.hidden = true;   // to hide
to_hide.hidden = false;  // to unhide
Answer

I know this is a little late but better late than never! Here's a really simple way to achieve this. Simply have a show and hide function. The hide function will just append every option element to a predetermined (hidden) span tag (which should work for all browsers) and then the show function will just move that option element back into your select tag. ;)

function showOption(value){
    $('#optionHolder option[value="'+value+'"]').appendTo('#selectID');             
}

function hideOption(value){
    $('select option[value="'+value+'"]').appendTo('#optionHolder');
}
Answer

Here's an option that:

  • Works in all browsers
  • Preserves current selection when filtering
  • Preserves order of items when removing / restoring
  • No dirty hacks / invalid HTML

`

$('select').each(function(){
    var $select = $(this);
    $select.data('options', $select.find('option'));
});

function filter($select, search) {
    var $prev = null;
    var $options = $select.data('options');
    search = search.trim().toLowerCase();
    $options.each(function(){
        var $option = $(this);
        var optionText = $option.text();
        if(search == "" || optionText.indexOf(search) >= 0) {
            if ($option.parent().length) {
                    $prev = $option;
                return;
            }
            if (!$prev) $select.prepend($option);
            else $prev.after($option);
            $prev = $option;
        }
        else {
              $option.remove();
        }
    });
}

`

JSFiddle: https://jsfiddle.net/derrh5tr/

Answer

It's possible if you keep in object and filter it in short way.

<select id="driver_id">
<option val="1" class="team_opion option_21">demo</option>
<option val="2" class="team_opion option_21">xyz</option>
<option val="3" class="team_opion option_31">ab</option>
</select>

-

team_id= 31;

var element = $("#driver_id");
originalElement = element.clone();  // keep original element, make it global


element.find('option').remove();   
originalElement.find(".option_"+team_id).each(function() { // change find with your needs
        element.append($(this)["0"].outerHTML); // append found options
});

https://jsfiddle.net/2djv7zgv/4/

Answer

Try this:

$(".hide").css("display","none");

But I think it doesn't make sense to hide it. if you wanna remove it, just:

$(".hide").remove();

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us Javascript

©2020 All rights reserved.