Masquer les options dans une liste de sélection à l'aide de jQuery


98

J'ai un objet avec des paires d'options clé / valeur que je souhaite masquer / supprimer d'une liste de sélection. Aucun des sélecteurs d'options suivants ne fonctionne. Qu'est-ce que je rate?

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

12
êtes-vous sûr que la réponse acceptée fonctionne x-browser;) Je détesterais quelqu'un d'autre pour trouver ce q & a via google et partir avec la mauvaise impression!
redsquare

@redsquare - c'est exactement pourquoi j'ai posté un lien vers une autre question sur le masquage des éléments d'option dans un select ne pas être cross browser :)
Russ Cam


J'ai trouvé que vous devez également désélectionner l'élément sélectionné s'il est caché après l'appel de hide () dans Chrome 57.0
omarjebari

Réponses:


127

Pour ce que ça vaut, la deuxième forme (avec le @) n'existe pas dans jQuery 1.3. Le premier ne fonctionne pas car vous vous attendez apparemment à une interpolation variable. Essaye ça:

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

Notez que cela se cassera probablement de diverses manières hideuses s'il titlecontient des métacaractères de sélection jQuery.


50
Le masquage des options n'est pas compatible avec plusieurs navigateurs.
mpen

1
Mettre des guillemets simples résoudra la plupart des problèmes de méta-caractères jquery
Peterjwest


Ce concept m'a aidé pour une autre solution. Merci
Ajay Kumar

En vous lassant de masquer <options /> aussi souvent, cela ne mettra pas à jour la valeur sélectionnée. Vous devrez sélectionner une nouvelle option après qu'elle soit masquée. Si vous travaillez dans optgroup, il est difficile de parcourir le DOM.
Solvitieg le

80

Vous ne pouvez pas faire ce x-browser. Si je me souviens, c'est à dire a des problèmes. La chose la plus simple à faire est de conserver une copie clonée de la sélection avant de supprimer des éléments, cela vous permet de supprimer facilement, puis de rajouter les éléments manquants.


2
récupérer les options ne sera pas un problème car cela fait partie d'une liste déroulante dépendante avec des appels ajax au serveur pour mettre à jour les options à chaque modification. Mais est-ce un cas de hide () qui ne fonctionne pas dans IE?
hitfactory

En effet ie ne les cachera pas. Je ne suis pas sûr de ie8 mais certainement l'une des saveurs ie ne fonctionne pas
redsquare

L'exemple de lien pastebin ne cache pas non plus l'option dans Chrome
slolife

5
Voici une réponse qui fonctionne sur plusieurs navigateurs - avec un exemple ici - j'ai testé dans IE6-9, Chrome et FF
Tr1stan

Veuillez voir ma réponse ci-dessous, fonctionnant dans IE, FF, Chrome et Safari. C'est l'option la plus flexible (permettant des valeurs différentes du texte affiché).
Sablefoste

53

J'ai trouvé un meilleur moyen, et c'est très simple:

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

Pour afficher à nouveau, trouvez simplement cette option (pas span) et $("option_you_want_to_show").unwrap().

Il a été testé sur Chrome et Firefox.


3
Vous êtes un génie absolu! Une seule ligne magique de navigateur croisé.
manudea

Cool. Gère assez bien le problème de navigateur croisé.
Subrat Pattnaik

J'ai voté pour celui-ci mais il gâche s'il n'est pas mis en œuvre correctement: par exemple, vous ne pouvez pas l'utiliser $("select").val("0").trigger("change"). La solution plus
simple

2
Vous perdez trop de contrôle en utilisant la fonction wrap / unwrap. il est facile de dérouler accidentellement des éléments qui n'ont pas déjà été enveloppés, ce qui les supprime de leur élément parent. En outre, cela peut gâcher les sélecteurs css. Utiliser show / hide est préférable, mais vous devez toujours vous rappeler de désélectionner tout élément sélectionné avec: $ ('selector-for-dropdown'). Val ('');
omarjebari

1
J'ai aimé la solution wrap / uwnrap. Il suffit de s'assurer que nous ne doublons pas ceux qui sont déjà emballés. Idée similaire avec celles non emballées.
Anon

47

Voici mon spin, probablement un peu plus rapide en raison des méthodes DOM natives

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

14

Cela fonctionne dans Firefox 3.0, mais pas dans MSIE 8, ni dans Opera 9.62:

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

Mais plutôt cacher une option, on peut simplement la désactiver:

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

La première des deux lignes ci-dessus est pour Firefox et passe le focus à la 2ème option (en supposant qu'elle a une valeur = "2"). Si nous l'omettons, l'option est désactivée, mais affiche toujours l'option «activé» avant de la déposer. Par conséquent, nous passons le focus à une autre option pour éviter cela.


12

Cela PEUT être fait sur plusieurs navigateurs; il faut juste une programmation personnalisée. Veuillez consulter mon violon sur http://jsfiddle.net/sablefoste/YVMzt/6/ . Il a été testé pour fonctionner dans Chrome, Firefox, Internet Explorer et Safari.

En bref, j'ai un champ caché #optionstore, qui stocke le tableau de manière séquentielle (car vous ne pouvez pas avoir de tableaux associatifs en JavaScript). Ensuite, lorsque vous modifiez la catégorie, il analyse les options existantes (uniquement pour la première fois), les écrit #optionstore, efface tout et ne remet que celles associées à la catégorie.

REMARQUE: j'ai créé ceci pour autoriser différentes valeurs d'option du texte affiché à l'utilisateur, donc il est très flexible.

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

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

Pouvez-vous expliquer l'utilisation de la variable resultgood? Nous avons supprimé son utilisation car lorsque l'utilisateur a une liste filtrée et que l'utilisateur entre un caractère qui signifie qu'il n'y a aucun élément à afficher, une liste vide n'est pas réellement affichée - le code continue de lister les éléments qui correspondent au terme de recherche sans le caractère supplémentaire. Notre cas d'utilisation diffère légèrement de l'exemple - nous utilisons un champ de saisie pour accepter l'entrée d'un terme de recherche.
B5A7

Le resultgoodest simplement une vérification pour voir si un élément a optionlistingété ajouté. si c'était le cas, la liste de <option>s est renvoyée. Sinon, rien n'est retourné, ce que vous voudriez si vous incluiez accidentellement une classe qui n'était pas réellement là (dans cet exemple, disons, sub-Food6). Pour renvoyer un blanc dans une liste déroulante, remplacez la ligne de déclaration au début de la fonction par var optionlisting="<option value=''></option>";.
Sablefoste

Au fait, si je devais écrire ceci aujourd'hui, je n'utiliserais probablement pas la classe comme support d'information, mais plutôt l' dataattribut; c'est plus sémantiquement correct.
Sablefoste

Oui. Nous avons fait de même.
B5A7

5

Votre meilleur pari est de définir disabled = true sur les éléments d'option que vous souhaitez désactiver, puis dans l'ensemble CSS

option:disabled {
    display: none;
}

De cette façon, même si le navigateur ne prend pas en charge le masquage de l'élément désactivé, il ne peut toujours pas être sélectionné .. mais sur les navigateurs qui le prennent en charge, ils seront masqués.


4

Jetez un œil à cette question et les réponses -

Désactiver les options de sélection ...

En regardant votre code, vous devrez peut-être citer la valeur d'attribut

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

à partir des sélecteurs d'attributs jQuery

Les guillemets sont facultatifs dans la plupart des cas, mais doivent être utilisés pour éviter les conflits lorsque la valeur contient des caractères tels que "]"

ÉDITER:

Je viens de réaliser que vous obtenez le titre du paramètre de fonction, auquel cas la syntaxe devrait être

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

4

En référence à la suggestion de redsquare, j'ai fini par faire ceci:

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

puis pour inverser cela:

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

3

Le problème est qu'Internet Explorer ne semble pas prendre en charge les méthodes de masquage et d'affichage des options de sélection. Je voulais masquer toutes les options de ma sélection ddlReasonCode qui n'avaient pas le type actuellement sélectionné comme valeur de l'attribut "attType".

Alors que le charmant Chrome était assez satisfait de:

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

Voici ce qu'IE exigeait (les enfants, n'essayez pas ceci chez 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);
                    }
                }
            });

J'ai trouvé cette idée d'emballage sur http://ajax911.com/hide-options-selecbox-jquery/


3

Après avoir testé, les solutions postées ci-dessus par divers, y compris le chaos, pour masquer des éléments fonctionnent désormais dans les dernières versions de Firefox (66.0.4), Chrome (74.0.3729.169) et 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();

Pour IE, cela ne fonctionne pas, mais vous pouvez désactiver l'option

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

puis forcez la sélection d'une valeur différente.

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

Notez que pour une option désactivée, la valeur de la liste déroulante sera désormais nulle, et non la valeur de l'option sélectionnée si elle est désactivée.


2

Il semble que vous deviez également mettre à jour l'attribut "sélectionné". Sinon, l'option actuellement sélectionnée peut continuer à s'afficher - bien qu'elle disparaisse probablement lorsque vous allez réellement sélectionner une option (c'est ce qu'elle a fait pour moi): Essayez de faire ceci:

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

2

J'essayais de masquer les options d'une liste de sélection en fonction de l'option sélectionnée d'une autre liste de sélection. Cela fonctionnait dans Firefox3, mais pas dans Internet Explorer 6. J'ai quelques idées ici et j'ai une solution maintenant, alors j'aimerais partager:

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

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

Il a été vérifié comme fonctionnant dans Firefox 3 et Internet Explorer 6.


5
Selon le W3C, l' idattribut doit être unique: id = Cet attribut attribue un nom à un élément. Ce nom doit être unique dans un document.
Jasper

1

Pour éviter la concaténation de chaînes, vous pouvez utiliser jQuery.grep

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

1

Probablement pas aussi élégant ou réutilisable qu'un plugin jquery. mais une autre approche consiste simplement à enregistrer les éléments d'option et à les échanger si nécessaire:

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



        };

faites ceci pour utiliser l'objet:

var filterObject = new SelectFilter();
filterObject.showFooBarOptions (); 

1

J'ai implémenté une solution en utilisant une fonction qui filtre une combobox ( <select>) basée sur des attributs de données personnalisés. Cette solution prend en charge:

  • Avoir un <option>pour montrer quand le filtre laisserait la sélection vide.
  • Respecte les attributs sélectionnés existants.
  • <option> les éléments sans l'attribut data-filter ne sont pas modifiés.

Testé avec jQuery 2.1.4 et Firefox, Chrome, Safari et IE 10+.

Voici l'exemple 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>

Le code jQuery pour le filtrage:

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

Pour l'utiliser, il vous suffit d'appeler la fonction avec la valeur que vous souhaitez conserver.

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

Ensuite, la sélection résultante sera:

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

Les éléments d'origine sont stockés par la fonction data (), donc les appels suivants ajouteront et supprimeront les éléments corrects.


C'est une excellente solution réutilisable, qui est la seule que j'ai trouvée qui fonctionne sur Safari. Merci!
Echilon

0

La réponse indique que ce @n'est pas valide pour les nouvelles itérations jQuery. Bien que ce soit correct, certains IE plus anciens ne cachent toujours pas les éléments d'options. Pour tous ceux qui doivent gérer le masquage des éléments d'option dans les versions concernées, j'ai publié une solution de contournement ici:

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

En gros, enveloppez-le simplement avec une portée et remplacez-le lors du spectacle.


0

Quiconque tombe sur cette question pourrait également envisager l'utilisation de Chosen , qui étend considérablement les capacités des sélections.


0
$("option_you_want_to_hide").addClass('hidden')

Ensuite, dans votre css, assurez-vous d'avoir

.hidden{
    display:none;
}

0

Je sais que cette question a reçu une réponse. Mais mon exigence était légèrement différente. Au lieu de valeur, je voulais filtrer par texte. J'ai donc modifié la réponse de @William Herry comme ça.

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 cette façon, vous pouvez également utiliser la valeur en remplaçant contient comme ceci

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

0

Pour l' option de masquage dans sélectionnez l' utilisation:

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

option_node est HTMLOptionElement

PS: je n'utilise pas JQuery, mais je suppose que cela fonctionnera:

$('.my_select option[value="my_cool_value"]').hidden = true

IE ne prend pas en charge le masquage sur certaines options
RitchieD

stackoverflow.com/questions/2031740/… PS: IE n'est pas un navigateur. IE - programme pour télécharger le navigateur! :)
DAVIDhaker

0

J'ai trouvé préférable de supprimer complètement le DOM.

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

Compatible avec tous les navigateurs. Fonctionne aussi sur IE11


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

option: option eq (0) -hide à l'index '0' dans la boîte de sélection.



-1

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


Veuillez ajouter une description à votre solution!
Philipp M
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.