使用 jQuery 在选择列表中隐藏选项

我有一个对象,其中包含我想从选择列表中隐藏/删除的键/值对选项。 以下两个选项选择器都不工作。我遗漏了什么?

$.each(results['hide'], function(name, title) {
$("#edit-field-service-sub-cat-value option[value=title]").hide();
$("#edit-field-service-sub-cat-value option[@value=title]").hide();
});
415039 次浏览

Take a look at this question and the answers -

Disable select options...

Looking at your code, you may need to quote the attribute value

$("#edit-field-service-sub-cat-value option[value='title']").hide();

from jQuery attribute selectors

Quotes are optional in most cases, but should be used to avoid conflicts when the value contains characters like "]"

EDIT:

Just realised that you're getting the title from the function parameter, in which case the syntax should be

$("#edit-field-service-sub-cat-value option[value='" + title + "']").hide();

For what it's worth, the second form (with the @) doesn't exist in jQuery 1.3. The first isn't working because you're apparently expecting variable interpolation. Try this:

$("#edit-field-service-sub-cat-value option[value=" + title + "]").hide();

Note that this will probably break in various hideous ways if title contains jQuery selector metacharacters.

You cannot do this x-browser. If I recall ie has issues. The easiest thing to do is keep a cloned copy of the select before you remove items, this allows you to easily remove and then append the missing items back.

I was trying to hide options from one select-list based on the selected option from another select-list. It was working in Firefox3, but not in Internet Explorer 6. I got some ideas here and have a solution now, so I would like to share:

The JavaScript code

function change_fruit(seldd) {
var look_for_id=''; var opt_id='';
$('#obj_id').html("");
$("#obj_id").append("<option value='0'>-Select Fruit-</option>");
if(seldd.value=='0') {
look_for_id='N';
}
if(seldd.value=='1'){
look_for_id='Y';
opt_id='a';
}
if(seldd.value=='2') {
look_for_id='Y';
opt_id='b';
}
if(seldd.value=='3') {
look_for_id='Y';
opt_id='c';
}


if(look_for_id=='Y') {
$("#obj_id_all option[id='"+opt_id+"']").each(function() {
$("#obj_id").append("<option value='"+$(this).val()+"'>"+$(this).text()+"</option>");
});
}
else {
$("#obj_id_all option").each(function() {
$("#obj_id").append("<option value='"+$(this).val()+"'>"+$(this).text()+"</option>");
});
}
}

The HTML

<select name="obj_id" id="obj_id">
<option value="0">-Select Fruit-</option>
<option value="1" id="a">apple1</option>
<option value="2" id="a">apple2</option>
<option value="3" id="a">apple3</option>
<option value="4" id="b">banana1</option>
<option value="5" id="b">banana2</option>
<option value="6" id="b">banana3</option>
<option value="7" id="c">Clove1</option>
<option value="8" id="c">Clove2</option>
<option value="9" id="c">Clove3</option>
</select>


<select name="fruit_type" id="srv_type" onchange="change_fruit(this)">
<option value="0">All</option>
<option value="1">Starts with A</option>
<option value="2">Starts with B</option>
<option value="3">Starts with C</option>
</select>


<select name="obj_id_all" id="obj_id_all" style="display:none;">
<option value="1" id="a">apple1</option>
<option value="2" id="a">apple2</option>
<option value="3" id="a">apple3</option>
<option value="4" id="b">banana1</option>
<option value="5" id="b">banana2</option>
<option value="6" id="b">banana3</option>
<option value="7" id="c">Clove1</option>
<option value="8" id="c">Clove2</option>
<option value="9" id="c">Clove3</option>
</select>

It was checked as working in Firefox 3 and Internet Explorer 6.

It seems that you also have to update the "selected" attribute. Otherwise the currently selected option may continue to display - although it probably will go away when you actually go to select an option (thats what it did for me): Try doing this:

$('#mySelector').children('option').hide();
$('#mySelector').children('option').removeAttr("selected"); //this may be overkill.
$('#mySelector').children('option[value="'+SelVal+'"]').show();
$('#mySelector').children(':visible').attr('selected','selected'); //assuming that something is still on the list.

This works in Firefox 3.0, but not in MSIE 8, nor in Opera 9.62:

jQuery('#destinations').children('option[value="1"]').hide();
jQuery('#destinations').children('option[value="1"]').css('display','none');

But rather hiding an option, one can simply disable it:

jQuery('#destinations').val('2');
jQuery('#destinations').children('option[value="1"]').attr('disabled','disabled');

The first of the the two lines above is for Firefox and pass focus to the 2nd option (assuming it has value="2"). If we omit it, the option is disabled, but the still displays the "enabled" option before we drop it down. Hence, we pass focus to another option to avoid this.

The answer points out that @ is invalid for newer jQuery iterations. While that's correct, some older IEs still dont hide option elements. For anyone having to deal with hiding option elements in those versions affected, I posted a workaround here:

http://work.arounds.org/issue/96/option-elements-do-not-hide-in-IE/

Basically just wrap it with a span and replace on show.

To avoid string concatenation you can use jQuery.grep

$($.grep($("#edit-field-service-sub-cat-value option"),
function(n,i){
return n.value==title;
})
).hide()

In reference to redsquare's suggestion, I ended up doing this:

var selectItems = $("#edit-field-service-sub-cat-value option[value=" + title + "]").detach();

and then to reverse this:

$("#edit-field-service-sub-cat-value").append(selectItems);

It CAN be done cross browser; it just takes some custom programming. Please see my fiddle at http://jsfiddle.net/sablefoste/YVMzt/6/. It was tested to work in Chrome, Firefox, Internet Explorer, and Safari.

In short, I have a hidden field, #optionstore, which stores the array sequentially (since you can't have Associative Arrays in JavaScript). Then when you change the category, it parses the existing options (first time through only) writes them to #optionstore, erases everything, and puts back only the ones associated with the category.

NOTE: I created this to allow different option values from the text displayed to the user, so it is highly flexible.

The HTML:

<p id="choosetype">
<div>
Food Category:
</div>
<select name="category" id="category" title="OPTIONAL - Choose a Category to Limit Food Types" size="1">
<option value="">All Food</option>
<option value="Food1">Fruit</option>
<option value="Food2">Veggies</option>
<option value="Food3">Meat</option>
<option value="Food4">Dairy</option>
<option value="Food5">Bread</option>
</select>
<div>
Food Selection
</div>
<select name="foodType" id="foodType" size="1">
<option value="Fruit1" class="sub-Food1">Apples</option>
<option value="Fruit2" class="sub-Food1">Pears</option>
<option value="Fruit3" class="sub-Food1">Bananas</option>
<option value="Fruit4" class="sub-Food1">Oranges</option>
<option value="Veg1" class="sub-Food2">Peas</option>
<option value="Veg2" class="sub-Food2">Carrots</option>
<option value="Veg3" class="sub-Food2">Broccoli</option>
<option value="Veg4" class="sub-Food2">Lettuce</option>
<option value="Meat1" class="sub-Food3">Steak</option>
<option value="Meat2" class="sub-Food3">Chicken</option>
<option value="Meat3" class="sub-Food3">Salmon</option>
<option value="Meat4" class="sub-Food3">Shrimp</option>
<option value="Meat5" class="sub-Food3">Tuna</option>
<option value="Meat6" class="sub-Food3">Pork</option>
<option value="Dairy1" class="sub-Food4">Milk</option>
<option value="Dairy2" class="sub-Food4">Cheese</option>
<option value="Dairy3" class="sub-Food4">Ice Cream</option>
<option value="Dairy4" class="sub-Food4">Yogurt</option>
<option value="Bread1" class="sub-Food5">White Bread</option>
<option value="Bread2" class="sub-Food5">Panini</option>
</select>
<span id="optionstore" style="display:none;"></span>
</p>

The JavaScript/jQuery:

$(document).ready(function() {
$('#category').on("change", function() {
var cattype = $(this).val();
optionswitch(cattype);
});
});


function optionswitch(myfilter) {
//Populate the optionstore if the first time through
if ($('#optionstore').text() == "") {
$('option[class^="sub-"]').each(function() {
var optvalue = $(this).val();
var optclass = $(this).prop('class');
var opttext = $(this).text();
optionlist = $('#optionstore').text() + "@%" + optvalue + "@%" + optclass + "@%" + opttext;
$('#optionstore').text(optionlist);
});
}


//Delete everything
$('option[class^="sub-"]').remove();


// Put the filtered stuff back
populateoption = rewriteoption(myfilter);
$('#foodType').html(populateoption);
}


function rewriteoption(myfilter) {
//Rewrite only the filtered stuff back into the option
var options = $('#optionstore').text().split('@%');
var resultgood = false;
var myfilterclass = "sub-" + myfilter;
var optionlisting = "";


myfilterclass = (myfilter != "")?myfilterclass:"all";


//First variable is always the value, second is always the class, third is always the text
for (var i = 3; i < options.length; i = i + 3) {
if (options[i - 1] == myfilterclass || myfilterclass == "all") {
optionlisting = optionlisting + '<option value="' + options[i - 2] + '" class="' + options[i - 1] + '">' + options[i] + '</option>';
resultgood = true;
}
}
if (resultgood) {
return optionlisting;
}
}

Here is my spin, likely a bit faster due to native DOM methods

$.each(results['hide'], function(name, title) {
$(document.getElementById('edit-field-service-sub-cat-value').options).each(function(index, option) {
if( option.value == title ) {
option.hidden = true; // not fully compatible. option.style.display = 'none'; would be an alternative or $(option).hide();
}
});
});

Your best bet is to set disabled=true on the option items you want to disable, then in CSS set

option:disabled {
display: none;
}

That way even if the browser doesn't support hiding the disabled item, it still can't be selected.. but on browsers that do support it, they will be hidden.

I found a better way, and it is very simple:

$("option_you_want_to_hide").wrap('<span/>')

To show again, just find that option(not span) and $("option_you_want_to_show").unwrap().

It was tested on Chrome and Firefox.

Anybody stumbling across this question might also consider the use of Chosen, which greatly expands the capabilities of selects.

The problem is that Internet Explorer does not seem to support the hide and show methods for select options. I wanted to hide all options of my ddlReasonCode select which did not have the currently selected type as the value of the attribute "attType".

While the lovely Chrome was quite satisfied with:

//Hiding all options
$("#ddlReasonCode").children().hide();
//Showing only the relevant options
$("#ddlReasonCode").children("option[atttype=\"" + CurrentType + "\"]").show();

This is what IE required (kids, don't try this at CHROME :-)):

//Hiding all options
$("#ddlReasonCode option").each(function (index, val) {
if ($(this).is('option') && (!$(this).parent().is('span')) && ($(this).atttype != CurrentType))
$(this).wrap('<span>').hide();
});
//Showing only the relevant options
$("#ddlReasonCode option").each(function (index, val) {
if (this.nodeName.toUpperCase() === 'OPTION') {
var span = $(this).parent();
var opt = this;
if ($(this).parent().is('span') && ((this).atttype == CurrentType)) {
$(opt).show();
$(span).replaceWith(opt);
}
}
});

I found that wrapping idea at http://ajax911.com/hide-options-selecbox-jquery/

Probably not as elegant or as reusable as a jquery plugin. but another approach is to simply save option elements and swap them out as required:

var SelectFilter = function ()
{
this.allOptions = $("#someSelect option");


this.fooBarOptions= $("#someSelect option[value='foo']");
this.fooBarOptions= this.fooBarOptions.add($("#someSelect option[value='bar']"));




this.showFooBarOptions = function()
{
$("#someSelect option").remove();
$("#someSelect").append(this.fooBarOptions);
};
this.showAllOptions = function()
{
$("#someSelect option").remove();
$("#someSelect").append(this.allOptions);
};






};

do this to use the object:

var filterObject = new SelectFilter();
filterObject.showFooBarOptions ();
$("option_you_want_to_hide").addClass('hidden')

Then, in your css make sure you have

.hidden{
display:none;
}

I know this question has been answered. But my requirement was slightly different. Instead of value I wanted to filter by text. So i modified the answer by @William Herry like this.

var array = ['Administration', 'Finance', 'HR', 'IT', 'Marketing', 'Materials', 'Reception', 'Support'];
if (somecondition) {
$(array).each(function () {
$("div#deprtmnts option:contains(" + this + ")").unwrap();
});
}
else{
$(array).each(function () {
$("div#deprtmnts option:contains(" + this + ")").wrap('<span/>');
});
}

This way you can use value also by replacing contains like this

 $("div#ovrcateg option[value=" + this + "]").wrap('<span/>');

I implemented a solution using a function that filters a combobox (<select>) based on custom data- attributes. This solution supports:

  • Having an <option> to show when the filter would leave the select empty.
  • Respects existing selected attributes.
  • <option> elements without the data-filter attribute are left untouched.

Tested with jQuery 2.1.4 and Firefox, Chrome, Safari and IE 10+.

This is the example HTML:

<select id="myCombobox">
<option data-filter="1" value="AAA">Option 1</option>
<option data-filter="1" value="BBB">Option 2</option>
<option data-filter="2" value="CCC">Option 3</option>
<option data-filter="2" value="DDD">Option 4</option>
<option data-filter="3" value="EEE">Option 5</option>
<option data-filter="3" value="FFF">Option 6</option>
<option data-filter-emptyvalue disabled>No Options</option>
</select>

The jQuery code for the filtering:

function filterCombobox(selectObject, filterValue, autoSelect) {


var fullData = selectObject.data("filterdata-values");
var emptyValue = selectObject.data("filterdata-emptyvalue");


// Initialize if first time.
if (!fullData) {
fullData = selectObject.find("option[data-filter]").detach();
selectObject.data("filterdata-values", fullData);
emptyValue = selectObject.find("option[data-filter-emptyvalue]").detach();
selectObject.data("filterdata-emptyvalue", emptyValue);
selectObject.addClass("filtered");
}
else {
// Remove elements from DOM
selectObject.find("option[data-filter]").remove();
selectObject.find("option[data-filter-emptyvalue]").remove();
}


// Get filtered elements.
var toEnable = fullData.filter("option[data-filter][data-filter='" + filterValue + "']");


// Attach elements to DOM
selectObject.append(toEnable);


// If toEnable is empty, show empty option.
if (toEnable.length == 0) {
selectObject.append(emptyValue);
}


// Select First Occurrence
if (autoSelect) {
var obj = selectObject.find("option[selected]");
selectObject.val(obj.length == 0 ? toEnable.val() : obj.val());
}
}

To use it, you just call the function with the value you want to keep.

filterCombobox($("#myCombobox"), 2, true);

Then the resulting select will be:

<select id="myCombobox">
<option data-filter="2" value="CCC">Option 3</option>
<option data-filter="2" value="DDD">Option 4</option>
</select>

The original elements are stored by the data() function, so subsequent calls will add and remove the correct elements.

For hide option in select use:

option_node.hidden = true; # For hide selcet item
option_node.hidden = false; # For show selcet item

Where option_node is HTMLOptionElement

P.S.: I do not use JQuery, but guessing, that it's will works:

$('.my_select option[value="my_cool_value"]').hidden = true
 $('#id').val($('#id option:eq(0)').hide());

option:eq(0)-hide option at index '0' in select box.

I found it best to just remove the DOM completely.

$(".form-group #selectId option[value='39']").remove();

Cross browser compatible. Works on IE11 too

Having tested, the solutions posted above by various, including chaos, to hide elements do now work in the latest versions of Firefox (66.0.4), Chrome (74.0.3729.169) and Edge (42.17134.1.0)

$("#edit-field-service-sub-cat-value option[value=" + title + "]").hide();
$("#edit-field-service-sub-cat-value option[value=" + title + "]").show();

For IE, this does not work, however you can disable the option

$("#edit-field-service-sub-cat-value option[value=" + title + "]").attr("disabled", "disabled");
$("#edit-field-service-sub-cat-value option[value=" + title + "]").removeAttr("disabled");

and then force the selection of a different value.

$("#edit-field-service-sub-cat-value").val("0");

Note, for a disabled option, the val of the drop down will now be null, not the value of the selected option if it is disabled.

You can show/hide with Value or Class name. Check the below link with working example.
Show/hide jquery chosen options with value or with class name.

$("#ddtypeoftraining option[value=5]").css("display", "none"); $('#ddtypeoftraining').selectpicker('refresh');