[javascript] How to hide a <option> in a <select> menu with CSS?

I've realized that Chrome, it seems, will not allow me to hide <option> in a <select>. Firefox will.

I need to hide the <option>s that match a search criteria. In the Chrome web tools I can see that they are correctly being set to display: none; by my JavaScript, but once then <select> menu is clicked they are shown.

How can I make these <option>s that match my search criteria NOT show when the menu is clicked? Thanks!

This question is related to javascript jquery css dom

The answer is


You should remove them from the <select> using JavaScript. That is the only guaranteed way to make them go away.


For HTML5, you can use the 'hidden' attribute.

<option hidden>Hidden option</option>

It is not supported by IE < 11. But if you need only to hide a few elements, maybe it would be better to just set the hidden attribute in combination with disabled in comparison to adding/removing elements or doing not semantically correct constructions.

_x000D_
_x000D_
<select>  _x000D_
  <option>Option1</option>_x000D_
  <option>Option2</option>_x000D_
  <option hidden>Hidden Option</option>_x000D_
</select>
_x000D_
_x000D_
_x000D_

Reference.


// Simplest way

var originalContent = $('select').html();

$('select').change(function() {
    $('select').html(originalContent); //Restore Original Content
    $('select option[myfilter=1]').remove(); // Filter my options
});

Ryan P's answer should be changed to:

    jQuery.fn.toggleOption = function (show) {
        $(this).toggle(show);
        if (show) {
            if ($(this).parent('span.toggleOption').length)
                $(this).unwrap();
        } else {
            **if ($(this).parent('span.toggleOption').length==0)**
                $(this).wrap('<span class="toggleOption" style="display: none;" />');
        }
    };

Otherwise it gets wrapped in too many tags


!!! WARNING !!!

Replace the second "IF" by "WHILE" or doesn't work !

jQuery.fn.toggleOption = function( show ) {
    jQuery( this ).toggle( show );
    if( show ) {
        while( jQuery( this ).parent( 'span.toggleOption' ).length )
            jQuery( this ).unwrap( );
    } else {
        jQuery( this ).wrap( '<span class="toggleOption" style="display: none;" />' );
    }
};

Since you're already using JS, you could create a hidden SELECT element on the page, and for each item you are trying to hide in that list, move it to the hidden list. This way, they can be easily restored.

I don't know a way offhand of doing it in pure CSS... I would have thought that the display:none trick would have worked.


The toggleOption function is not perfect and introduced nasty bugs in my application. jQuery will get confused with .val() and .arraySerialize() Try to select options 4 and 5 to see what I mean:

<select id="t">
<option value="v1">options 1</option>
<option value="v2">options 2</option>
<option value="v3" id="o3">options 3</option>
<option value="v4">options 4</option>
<option value="v5">options 5</option>
</select>
<script>
jQuery.fn.toggleOption = function( show ) {
    jQuery( this ).toggle( show );
    if( show ) {
        if( jQuery( this ).parent( 'span.toggleOption' ).length )
            jQuery( this ).unwrap( );
    } else {
        jQuery( this ).wrap( '<span class="toggleOption" style="display: none;" />' );
    }
};

$("#o3").toggleOption(false); 
$("#t").change(function(e) {
    if($(this).val() != this.value) {
    console.log("Error values not equal", this.value, $(this).val());
    }
});
</script>

Late to the game, but most of these seem quite complicated.

Here's how I did it:

var originalSelect = $('#select-2').html();

// filter select-2 on select-1 change
$('#select-1').change(function (e) {

    var selected = $(this).val();

    // reset select ready for filtering
    $('#select-2').html(originalCourseSelect);

    if (selected) {
        // filter
        $('#select-2 option').not('.t' + selected).remove();
    }

});

markup of select-1:

<select id='select-1'>
<option value=''>Please select</option>
<option value='1'>One</option>
<option value='2'>Two</option>
</select>

markup of select-2:

<select id='select-2'>
<option class='t1'>One</option>
<option class='t2'>Two</option>
<option>Always visible</option>
</select>

Simple answer: You can't. Form elements have very limited styling capabilities.

The best alternative would be to set disabled=true on the option (and maybe a gray colour, since only IE does that automatically), and this will make the option unclickable.

Alternatively, if you can, completely remove the option element.


I would suggest that you do not use the solutions that use a <span> wrapper because it isn't valid HTML, which could cause problems down the road. I think the preferred solution is to actually remove any options that you wish to hide, and restore them as needed. Using jQuery, you'll only need these 3 functions:

The first function will save the original contents of the select. Just to be safe, you may want to call this function when you load the page.

function setOriginalSelect ($select) {
    if ($select.data("originalHTML") == undefined) {
        $select.data("originalHTML", $select.html());
    } // If it's already there, don't re-set it
}

This next function calls the above function to ensure that the original contents have been saved, and then simply removes the options from the DOM.

function removeOptions ($select, $options) {
    setOriginalSelect($select);
    $options.remove();
 }

The last function can be used whenever you want to "reset" back to all the original options.

function restoreOptions ($select) {
    var ogHTML = $select.data("originalHTML");
    if (ogHTML != undefined) {
        $select.html(ogHTML);
    }
}

Note that all these functions expect that you're passing in jQuery elements. For example:

// in your search function...
var $s = $('select.someClass');
var $optionsThatDontMatchYourSearch= $s.find('options.someOtherClass');
restoreOptions($s); // Make sure you're working with a full deck
removeOptions($s, $optionsThatDontMatchYourSearch); // remove options not needed

Here is a working example: http://jsfiddle.net/9CYjy/23/


Select inputs are tricky in this way. What about disabling it instead, this will work cross-browser:

$('select').children(':nth-child(even)').prop('disabled', true);

This will disable every-other <option> element, but you can select which ever one you want.

Here is a demo: http://jsfiddle.net/jYWrH/

Note: If you want to remove the disabled property of an element you can use .removeProp('disabled').

Update

You could save the <option> elements you want to hide in hidden select element:

$('#visible').on('change', function () {
    $(this).children().eq(this.selectedIndex).appendTo('#hidden');
});

You can then add the <option> elements back to the original select element:

$('#hidden').children().appendTo('#visible');

In these two examples it's expected that the visible select element has the id of visible and the hidden select element has the id of hidden.

Here is a demo: http://jsfiddle.net/jYWrH/1/

Note that .on() is new in jQuery 1.7 and in the usage for this answer is the same as .bind(): http://api.jquery.com/on


this one seems to work for me in chrome

$("#selectid span option").unwrap();
$("#selectid option:not([filterattr=filtervalue])").wrap('<span/>');

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to jquery

How to make a variable accessible outside a function? Jquery assiging class to th in a table Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Getting all files in directory with ajax Bootstrap 4 multiselect dropdown Cross-Origin Read Blocking (CORB) bootstrap 4 file input doesn't show the file name Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource how to remove json object key and value.?

Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width

Examples related to dom

How do you set the document title in React? How to find if element with specific id exists or not Cannot read property 'style' of undefined -- Uncaught Type Error adding text to an existing text element in javascript via DOM Violation Long running JavaScript task took xx ms How to get `DOM Element` in Angular 2? Angular2, what is the correct way to disable an anchor element? React.js: How to append a component on click? Detect click outside React component DOM element to corresponding vue.js component