Ocultar opciones en una lista de selección usando jQuery

98

Tengo un objeto con pares de opciones clave / valor que quiero ocultar / eliminar de una lista de selección. Ninguno de los siguientes selectores de opciones funciona. ¿Qué me estoy perdiendo?

$.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();
}); 
hitfactory
fuente
12
¿Estás seguro de que la respuesta aceptada funciona?
redsquare
@redsquare: es exactamente por eso que publiqué un enlace a otra pregunta sobre cómo ocultar elementos de opciones en un navegador seleccionado que no es cruzado :)
Russ Cam
Descubrí que también debe anular la selección del elemento seleccionado si está oculto después de que se llame a hide () en Chrome 57.0
omarjebari

Respuestas:

127

Por lo que vale, la segunda forma (con @) no existe en jQuery 1.3. El primero no funciona porque aparentemente espera una interpolación de variables. Prueba esto:

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

Tenga en cuenta que esto probablemente se romperá de varias formas horribles si titlecontiene metacaracteres de selector de jQuery.

caos
fuente
50
Ocultar opciones no es compatible con varios navegadores.
mpen
1
Poner comillas simples resolverá la mayoría de los problemas de metacaracteres de jquery
peterjwest
Este concepto me ayudó a encontrar otra solución. Gracias
Ajay Kumar
Por cansado al ocultar <opciones />, ya que esto no actualizará el valor seleccionado. Deberá seleccionar una nueva opción después de que esté oculta. Si está trabajando en optgroup, es complicado atravesar el DOM.
Solvitieg
80

No puede hacer este navegador x. Si mal no recuerdo, es decir, tiene problemas. Lo más fácil de hacer es mantener una copia clonada de la selección antes de eliminar elementos, esto le permite eliminar fácilmente y luego agregar los elementos que faltan.

cuadrado rojo
fuente
2
recuperar opciones no será un problema, ya que es parte de un menú desplegable dependiente con llamadas ajax al servidor para actualizar las opciones cada vez que se cambia. ¿Pero es un caso de hide () que no funciona en IE?
hitfactory
De hecho, es decir, no los esconderá. No estoy seguro acerca de ie8, pero ciertamente uno de los sabores de ie no funciona
redsquare
El ejemplo del enlace pastebin tampoco oculta la opción en Chrome
slolife
5
Aquí hay una respuesta que funciona en todos los navegadores , con un ejemplo aquí : lo he probado en IE6-9, Chrome y FF
Tr1stan
Consulte mi respuesta a continuación, trabajando en IE, FF, Chrome y Safari. Es la opción más flexible (que permite diferentes valores del texto mostrado).
Sablefoste
53

Encontré una mejor manera, y es muy simple:

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

Para volver a mostrar, simplemente busque esa opción (no span) y $("option_you_want_to_show").unwrap().

Fue probado en Chrome y Firefox.

William Herry
fuente
3
¡Eres un genio absoluto! Sólo una fila de magia de navegador cruzado.
Manudea
Frio. Maneja bastante bien el problema de varios navegadores.
Subrat Pattnaik
He votado a favor de este, pero se estropea si no se implementa correctamente: por ejemplo, no se puede usar $("select").val("0").trigger("change"). La solución más fácil es esta
clod986
2
Pierde demasiado control al usar envoltura / desenvolver. es fácil desenvolver accidentalmente elementos que aún no se han empaquetado, por lo tanto, eliminarlos de su elemento padre. También puede estropear los selectores CSS. Usar mostrar / ocultar es mejor, aunque debe recordar anular la selección de cualquier elemento seleccionado también con: $ ('selector-for-dropdown'). Val ('');
omarjebari
1
Me gustó la solución wrap / uwnrap. Solo necesito asegurarnos de no envolver dos veces los que ya están envueltos. Idea similar con los desenvueltos.
anon
47

Aquí está mi giro, probablemente un poco más rápido debido a los métodos DOM nativos

$.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();
      }
    });
});
Caprica Six
fuente
14

Esto funciona en Firefox 3.0, pero no en MSIE 8 ni en Opera 9.62:

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

Pero en lugar de ocultar una opción, simplemente se puede desactivar:

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

La primera de las dos líneas anteriores es para Firefox y pasa el foco a la segunda opción (asumiendo que tiene valor = "2"). Si la omitimos, la opción está deshabilitada, pero aún muestra la opción "habilitada" antes de que la sueltemos. Por tanto, pasamos el foco a otra opción para evitarlo.

entusiasta123
fuente
12

PUEDE hacerse en varios navegadores; solo se necesita un poco de programación personalizada. Vea mi violín en http://jsfiddle.net/sablefoste/YVMzt/6/ . Se probó que funciona en Chrome, Firefox, Internet Explorer y Safari.

En resumen, tengo un campo oculto #optionstore, que almacena la matriz secuencialmente (ya que no puede tener matrices asociativas en JavaScript). Luego, cuando cambia la categoría, analiza las opciones existentes (solo la primera vez) las escribe en#optionstore , borra todo y devuelve solo las asociadas con la categoría.

NOTA: Creé esto para permitir diferentes valores de opción del texto que se muestra al usuario, por lo que es muy flexible.

El 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>

El 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;
    }
}
Sablefoste
fuente
¿Podría explicar el uso de la variable resultgood? Hemos eliminado su uso porque cuando el usuario tiene una lista filtrada y el usuario ingresa un carácter que significa que no hay elementos para mostrar, en realidad no se muestra una lista vacía; el código continúa enumerando los elementos que coinciden con el término de búsqueda sin el carácter extra. Nuestro caso de uso difiere ligeramente del ejemplo: usamos un campo de entrada para aceptar la entrada de un término de búsqueda.
B5A7
El resultgoodes simplemente una comprobación para ver si alguno optionlistingse añadió. si lo fue, <option>se devuelve la lista de s. De lo contrario, no se devuelve nada, que es lo que desearía si accidentalmente incluyera una clase que no estaba realmente allí (en este ejemplo, digamos, sub-Food6). Para devolver un espacio en blanco en un menú desplegable, cambie la línea de declaración al comienzo de la función a var optionlisting="<option value=''></option>";.
Sablefoste
Por cierto, si tuviera que escribir esto hoy, probablemente no usaría class como portador de información, sino más bien como dataatributo; es más semánticamente correcto.
Sablefoste
Si. Nosotros hicimos lo mismo.
B5A7
5

Su mejor opción es establecer disabled = true en los elementos de opción que desea deshabilitar, luego en CSS set

option:disabled {
    display: none;
}

De esa manera, incluso si el navegador no admite ocultar el elemento deshabilitado, aún no se puede seleccionar ... pero en los navegadores que sí lo admiten, se ocultarán.

eoleario
fuente
4

Eche un vistazo a esta pregunta y las respuestas:

Desactivar seleccionar opciones ...

Al mirar su código, es posible que deba citar el valor del atributo

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

de los selectores de atributos de jQuery

Las comillas son opcionales en la mayoría de los casos, pero deben usarse para evitar conflictos cuando el valor contiene caracteres como "]".

EDITAR:

Me acabo de dar cuenta de que está obteniendo el título del parámetro de función, en cuyo caso la sintaxis debería ser

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

En referencia a la sugerencia de redsquare, terminé haciendo esto:

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

y luego para revertir esto:

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

El problema es que Internet Explorer no parece admitir los métodos de ocultar y mostrar para las opciones seleccionadas. Quería ocultar todas las opciones de mi selección de ddlReasonCode que no tenían el tipo seleccionado actualmente como valor del atributo "attType".

Mientras que el encantador Chrome estaba bastante satisfecho con:

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

Esto es lo que requiere IE (niños, no intenten esto en 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);
                    }
                }
            });

Encontré esa idea de envoltura en http://ajax911.com/hide-options-selecbox-jquery/

Oranit Dar
fuente
3

Una vez probadas, las soluciones publicadas anteriormente por varios, incluido el caos, para ocultar elementos ahora funcionan en las últimas versiones de Firefox (66.0.4), Chrome (74.0.3729.169) y 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();

Para IE, esto no funciona, sin embargo, puede desactivar la opción

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

y luego forzar la selección de un valor diferente.

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

Tenga en cuenta que, para una opción deshabilitada, el valor del menú desplegable ahora será nulo, no el valor de la opción seleccionada si está deshabilitada.

Steven Poole
fuente
2

Parece que también tienes que actualizar el atributo "seleccionado". De lo contrario, la opción seleccionada actualmente puede continuar mostrándose, aunque probablemente desaparecerá cuando vaya a seleccionar una opción (eso es lo que hizo por mí): Intente hacer esto:

$('#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.
djoeberry
fuente
2

Estaba intentando ocultar opciones de una lista de selección en función de la opción seleccionada de otra lista de selección. Funcionaba en Firefox3, pero no en Internet Explorer 6. Aquí tengo algunas ideas y ahora tengo una solución, así que me gustaría compartir:

El código JavaScript

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>");
        });
    }
}

El 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>

Se comprobó que funcionaba en Firefox 3 e Internet Explorer 6.

Souvik
fuente
5
Según el W3C, el idatributo debe ser único: id = Este atributo asigna un nombre a un elemento. Este nombre debe ser único en un documento.
Jasper
1

Para evitar la concatenación de cadenas, puede usar jQuery.grep

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

Probablemente no sea tan elegante ni tan reutilizable como un complemento de jquery. pero otro enfoque es simplemente guardar elementos de opción y cambiarlos según sea necesario:

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);
            };



        };

haz esto para usar el objeto:

var filterObject = new SelectFilter();
filterObject.showFooBarOptions (); 
Squiblemente
fuente
1

Implementé una solución usando una función que filtra un cuadro combinado ( <select>) basado en atributos de datos personalizados. Esta solución admite:

  • Tener un <option>para mostrar cuándo el filtro dejaría la selección vacía.
  • Respeta los atributos seleccionados existentes.
  • <option> los elementos sin el atributo de filtro de datos no se modifican.

Probado con jQuery 2.1.4 y Firefox, Chrome, Safari e IE 10+.

Este es el HTML de ejemplo:

<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>

El código jQuery para el filtrado:

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());
  }
}

Para usarlo, simplemente llame a la función con el valor que desea mantener.

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

Entonces la selección resultante será:

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

Los elementos originales son almacenados por la función data (), por lo que las llamadas posteriores agregarán y eliminarán los elementos correctos.

Alberto Hormazabal
fuente
Esta es una gran solución reutilizable, que es la única que encontré que funciona en Safari. ¡Gracias!
Echilon
0

La respuesta señala que @no es válido para las iteraciones de jQuery más nuevas. Si bien eso es correcto, algunos IE más antiguos aún no ocultan elementos de opción. Para cualquiera que tenga que lidiar con la ocultación de elementos de opción en esas versiones afectadas, publiqué una solución aquí:

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

Básicamente, envuélvalo con un palmo y reemplácelo en el programa.

meder omuraliev
fuente
0

Cualquiera que se encuentre con esta pregunta también podría considerar el uso de Chosen , que amplía enormemente las capacidades de selects.

Charles Wood
fuente
0
$("option_you_want_to_hide").addClass('hidden')

Luego, en su css asegúrese de tener

.hidden{
    display:none;
}
clod986
fuente
0

Sé que esta pregunta ha sido respondida. Pero mi requisito fue ligeramente diferente. En lugar de valor, quería filtrar por texto. Así que modifiqué la respuesta de @William Herry así.

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/>');
   });
}

De esta manera, también puede usar el valor reemplazando contiene como este

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

Para la opción de ocultar en el uso seleccionado :

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

Donde option_node es HTMLOptionElement

PD: No uso JQuery, pero supongo que funcionará:

$('.my_select option[value="my_cool_value"]').hidden = true
DAVIDhaker
fuente
IE no admite ocultar en opciones seleccionadas
RitchieD
stackoverflow.com/questions/2031740/… PD: IE no es un navegador. IE - programa para descargar navegador! :)
DAVIDhaker
0

Encontré que era mejor eliminar el DOM por completo.

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

Compatible con varios navegadores. También funciona en IE11

Vishal
fuente
0
 $('#id').val($('#id option:eq(0)').hide());

opción: eq (0) -Ocultar la opción en el índice '0' en el cuadro de selección.

Kiran
fuente
-1

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

Hemant yadav
fuente
¡Agregue una descripción a su solución!
Philipp M