Nascondi le opzioni in un elenco di selezione utilizzando jQuery


98

Ho un oggetto con coppie chiave / valore di opzioni che voglio nascondere / rimuovere da un elenco di selezione. Nessuno dei seguenti selettori di opzioni funziona. Cosa mi sto perdendo?

$.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
sei sicuro che la risposta accettata funzioni x-browser;) Odierei chiunque altro trovasse queste domande e risposte tramite google e se ne andasse con l'impressione sbagliata!
redsquare

@redsquare - questo è esattamente il motivo per cui ho pubblicato un collegamento a un'altra domanda su come nascondere gli elementi delle opzioni in una selezione che non è cross browser :)
Russ Cam


Ho scoperto che devi anche deselezionare l'elemento selezionato se è nascosto dopo che hide () è stato chiamato in Chrome 57.0
omarjebari

Risposte:


127

Per quello che vale, la seconda forma (con il @) non esiste in jQuery 1.3. Il primo non funziona perché apparentemente ti aspetti un'interpolazione variabile. Prova questo:

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

Nota che questo probabilmente si interromperà in vari modi orribili se titlecontiene i metacaratteri del selettore jQuery.


50
Le opzioni nascoste non sono compatibili con più browser.
mpen

1
Mettere le virgolette singole risolverà la maggior parte dei problemi di metacaratteri jquery
peterjwest


Questo concetto mi ha aiutato per un'altra soluzione. Grazie
Ajay Kumar

Stanco quando nascondi <opzioni /> poiché spesso questo non aggiornerà il valore selezionato. Dovrai selezionare una nuova opzione dopo che è stata nascosta. Se stai lavorando in optgroup diventa complicato attraversare il DOM.
Solvitieg

80

Non puoi fare questo x-browser. Se ricordo, cioè ha problemi. La cosa più semplice da fare è conservare una copia clonata della selezione prima di rimuovere gli elementi, questo ti consente di rimuovere facilmente e quindi aggiungere nuovamente gli elementi mancanti.


2
il ripristino delle opzioni non sarà un problema in quanto fa parte di un menu a discesa dipendente con chiamate ajax al server per aggiornare le opzioni ogni volta che la modifica. Ma è un caso in cui hide () non funziona in IE?
hitfactory

In effetti cioè non li nasconde. Non sono sicuro di ie8 ma certamente uno dei sapori di ie non funziona
redsquare

L'esempio del link pastebin non nasconde l'opzione neanche in Chrome
slolife

5
Ecco una risposta che funziona su tutti i browser - con un esempio qui - Ho testato in IE6-9, Chrome e FF
Tr1stan

Si prega di vedere la mia risposta di seguito, lavorando in IE, FF, Chrome e Safari. È l'opzione più flessibile (consentendo valori diversi dal testo visualizzato).
Sablefoste

53

Ho trovato un modo migliore ed è molto semplice:

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

Per mostrarlo di nuovo, trova semplicemente quell'opzione (non span) e $("option_you_want_to_show").unwrap().

È stato testato su Chrome e Firefox.


3
Sei un genio assoluto! Solo una riga per la magia del browser.
manudea

Freddo. Gestisce abbastanza bene il problema del browser incrociato.
Subrat Pattnaik

Ho votato positivamente questo ma rovina se non viene implementato correttamente: ad esempio non puoi usare $("select").val("0").trigger("change"). La soluzione più semplice è questa
clod986

2
Perdi troppo controllo usando avvolgi / scarta. è facile scartare accidentalmente elementi che non sono già stati avvolti, quindi rimuovendoli dal loro elemento genitore. Inoltre può rovinare i selettori CSS. Usare mostra / nascondi è meglio anche se devi ricordarti di deselezionare anche qualsiasi elemento selezionato con: $ ('selector-for-dropdown'). Val ('');
omarjebari

1
Mi è piaciuta la soluzione wrap / uwnrap. Devi solo assicurarti di non avvolgere due volte quelli già avvolti. Idea simile con quelle da scartare.
anon

47

Ecco il mio giro, probabilmente un po 'più veloce a causa dei metodi DOM nativi

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

Funziona in Firefox 3.0, ma non in MSIE 8, né in Opera 9.62:

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

Ma piuttosto nascondendo un'opzione, si può semplicemente disabilitarla:

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

La prima delle due righe sopra è per Firefox e passa lo stato attivo alla seconda opzione (supponendo che abbia valore = "2"). Se lo omettiamo, l'opzione è disabilitata, ma mostra ancora l'opzione "abilitata" prima di rilasciarla. Quindi, passiamo l'attenzione a un'altra opzione per evitarlo.


12

Può essere fatto cross browser; ci vuole solo un po 'di programmazione personalizzata. Si prega di vedere il mio violino su http://jsfiddle.net/sablefoste/YVMzt/6/ . È stato testato per funzionare in Chrome, Firefox, Internet Explorer e Safari.

In breve, ho un campo nascosto #optionstore, che memorizza l'array in sequenza (poiché non puoi avere array associativi in ​​JavaScript). Quindi, quando si modifica la categoria, analizza le opzioni esistenti (solo la prima volta) in cui le scrive #optionstore, cancella tutto e rimette a posto solo quelle associate alla categoria.

NOTA: l'ho creato per consentire valori di opzione diversi dal testo visualizzato all'utente, quindi è altamente flessibile.

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

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

Potresti spiegare l'uso della variabile resultgood? Abbiamo rimosso il suo utilizzo perché quando l'utente ha un elenco filtrato e l'utente inserisce un carattere che significa che non ci sono elementi da visualizzare, un elenco vuoto non viene effettivamente visualizzato - il codice continua a elencare gli elementi che corrispondono al termine di ricerca senza il carattere extra. Il nostro caso d'uso differisce leggermente dall'esempio: utilizziamo un campo di input per accettare l'inserimento di un termine di ricerca.
B5A7

Il resultgoodè semplicemente un controllo per vedere se qualcuno optionlistingè stato aggiunto. se lo era, <option>viene restituito l'elenco dei messaggi di posta elettronica. In caso contrario, non viene restituito nulla, che è ciò che vorresti se includessi accidentalmente una classe che non era effettivamente presente (in questo esempio, ad esempio, sub-Cibo6). Per restituire uno spazio vuoto in un elenco a discesa, modificare la riga della dichiarazione all'inizio della funzione in var optionlisting="<option value=''></option>";.
Sablefoste

A proposito, se dovessi scrivere questo oggi, probabilmente non userei class come vettore di informazioni, ma piuttosto l' dataattributo; è semanticamente più corretto.
Sablefoste

Sì. Abbiamo fatto lo stesso.
B5A7

5

La soluzione migliore è impostare disabled = true sugli elementi delle opzioni che desideri disabilitare, quindi in CSS set

option:disabled {
    display: none;
}

In questo modo, anche se il browser non supporta l'occultamento dell'elemento disabilitato, non può comunque essere selezionato .. ma nei browser che lo supportano, saranno nascosti.


4

Dai un'occhiata a questa domanda e alle risposte -

Disabilita le opzioni di selezione ...

Guardando il codice, potrebbe essere necessario citare il valore dell'attributo

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

dai selettori di attributi jQuery

Le virgolette sono facoltative nella maggior parte dei casi, ma dovrebbero essere utilizzate per evitare conflitti quando il valore contiene caratteri come "]"

MODIFICARE:

Mi sono appena reso conto che stai ottenendo il titolo dal parametro della funzione, nel qual caso la sintassi dovrebbe essere

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

4

In riferimento al suggerimento di redsquare, ho finito per fare questo:

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

e poi per invertire questo:

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

3

Il problema è che Internet Explorer non sembra supportare i metodi nascondi e mostra per selezionare le opzioni. Volevo nascondere tutte le opzioni del mio ddlReasonCode select che non aveva il tipo attualmente selezionato come valore dell'attributo "attType".

Mentre l'adorabile Chrome era abbastanza soddisfatto di:

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

Questo è ciò che richiede IE (ragazzi, non provateci su 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);
                    }
                }
            });

Ho trovato questa idea avvolgente su http://ajax911.com/hide-options-selecbox-jquery/


3

Dopo aver testato, le soluzioni pubblicate sopra da vari, incluso il caos, per nascondere elementi ora funzionano nelle ultime versioni di Firefox (66.0.4), Chrome (74.0.3729.169) ed 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();

Per IE, questo non funziona, tuttavia puoi disabilitare l'opzione

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

e quindi forzare la selezione di un valore diverso.

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

Nota, per un'opzione disabilitata, la val del menu a discesa sarà ora nulla, non il valore dell'opzione selezionata se è disabilitata.


2

Sembra che tu debba aggiornare anche l'attributo "selected". Altrimenti l'opzione attualmente selezionata potrebbe continuare a essere visualizzata, anche se probabilmente scomparirà quando andrai effettivamente a selezionare un'opzione (questo è quello che ha fatto per me): Prova a fare questo:

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

Stavo cercando di nascondere le opzioni da un elenco di selezione basato sull'opzione selezionata da un altro elenco di selezione. Funzionava in Firefox3, ma non in Internet Explorer 6. Ho alcune idee qui e ho una soluzione ora, quindi vorrei condividere:

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

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

È stato verificato che funziona in Firefox 3 e Internet Explorer 6.


5
Secondo il W3C l' idattributo dovrebbe essere unico: id = Questo attributo assegna un nome a un elemento. Questo nome deve essere univoco in un documento.
Jasper

1

Per evitare la concatenazione di stringhe puoi usare jQuery.grep

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

1

Probabilmente non così elegante o riutilizzabile come un plugin jquery. ma un altro approccio consiste nel salvare semplicemente gli elementi delle opzioni e sostituirli come richiesto:

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



        };

fai questo per utilizzare l'oggetto:

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

1

Ho implementato una soluzione utilizzando una funzione che filtra una casella combinata ( <select>) in base agli attributi dei dati personalizzati. Questa soluzione supporta:

  • Avere un <option>da mostrare quando il filtro lascerebbe vuota la selezione.
  • Rispetta gli attributi selezionati esistenti.
  • <option> gli elementi senza l'attributo data-filter vengono lasciati inalterati.

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

Questo è l'HTML di esempio:

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

Il codice jQuery per il filtraggio:

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

Per usarlo, basta chiamare la funzione con il valore che si desidera mantenere.

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

Quindi la selezione risultante sarà:

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

Gli elementi originali sono memorizzati dalla funzione data (), quindi le chiamate successive aggiungeranno e rimuoveranno gli elementi corretti.


Questa è un'ottima soluzione riutilizzabile, che è l'unica che ho trovato che funziona su Safari. Grazie!
Echilon

0

La risposta sottolinea che @non è valido per le iterazioni jQuery più recenti. Sebbene sia corretto, alcuni IE meno recenti non nascondono ancora gli elementi delle opzioni. Per chiunque abbia a che fare con gli elementi di opzione nascosti in quelle versioni interessate, ho pubblicato una soluzione alternativa qui:

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

Fondamentalmente basta avvolgerlo con una campata e sostituirlo in mostra.


0

Chiunque si imbatta in questa domanda potrebbe anche prendere in considerazione l'uso di Chosen , che espande notevolmente le capacità di selects.


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

Quindi, nel tuo css assicurati di avere

.hidden{
    display:none;
}

0

So che questa domanda ha avuto risposta. Ma la mia esigenza era leggermente diversa. Invece di valore ho voluto filtrare per testo. Quindi ho modificato la risposta di @William Herry in questo modo.

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

In questo modo puoi usare value anche sostituendo contiene in questo modo

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

0

Per l' opzione Nascondi in selezionare usa:

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

Dove option_node è HTMLOptionElement

PS: non uso JQuery, ma suppongo che funzionerà:

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

IE non supporta la funzione Nascondi su opzioni selezionate
RitchieD

stackoverflow.com/questions/2031740/… PS: IE non è un browser. IE - programma per il download del browser! :)
DAVIDhaker

0

Ho trovato meglio rimuovere completamente il DOM.

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

Compatibile con tutti i browser. Funziona anche su IE11


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

opzione: eq (0) -hide opzione all'indice "0" nella casella di selezione.



-1

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


Aggiungi una descrizione alla tua soluzione!
Philipp M
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.