Wie verstecke ich eine <Option> in einem <Auswahl> -Menü mit CSS?

102

Ich habe festgestellt, dass Chrome es mir anscheinend nicht erlaubt, mich <option>in einem zu verstecken <select>. Firefox wird.

Ich muss die <option>s ausblenden, die einem Suchkriterium entsprechen. In den Chrome-Web-Tools kann ich sehen, dass sie display: none;von meinem JavaScript korrekt eingestellt wurden, aber sobald dann auf das <select>Menü geklickt wird, werden sie angezeigt.

Wie kann ich diese <option>s, die meinen Suchkriterien entsprechen, NICHT anzeigen lassen, wenn auf das Menü geklickt wird? Vielen Dank!

Jesse Atkinson
quelle
4
Anstatt sich zu verstecken und bei einer Suche anzuzeigen. Versuchen Sie, die Auswahl abhängig von der Suche zu
füllen
1
Ich stimme Henesnarfel zu. Wenn Sie bereits eine Suche oder eine Abfrage durchführen, sollten Sie in der Lage sein, nur die gewünschten zu füllen.
Michael Stramel
1
Dies funktioniert gut für mich in Chrome 16.0.912.77 m. Verstehe ich das Problem falsch?
mgibsonbr
3
@mgibsonbr Es funktioniert nicht browserübergreifend.
Jasper
2
@Henesnarfel Es kann gute Gründe geben, Optionen auszublenden. Zum Beispiel hatte ich eine Seite mit einem ausgewählten Listenfeld und Links zum Ausblenden oder Anzeigen von Elementen, die als inaktiv markiert waren. Kein Grund, mehrere Listen zu führen oder den Server nach einer neuen Liste abzufragen, wenn der Benutzer diese Option ändert.
Ryan P

Antworten:

69

Sie müssen zwei Methoden zum Ausblenden implementieren. display: nonefunktioniert für FF, aber nicht für Chrome oder IE. Die zweite Methode ist also, das <option>in ein <span>mit zu verpacken display: none. FF wird es nicht tun (technisch ungültiges HTML, gemäß der Spezifikation), aber Chrome und IE werden es tun und es wird die Option verbergen.

EDIT: Oh ja, ich habe dies bereits in jQuery implementiert:

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

EDIT 2: So würden Sie diese Funktion verwenden:

jQuery(selector).toggleOption(true); // show option
jQuery(selector).toggleOption(false); // hide option

BEARBEITEN 3: Zusätzliche Prüfung hinzugefügt, die von @ user1521986 vorgeschlagen wurde

Ryan P.
quelle
1
Diese verrückte Methode ist die einzige, die tatsächlich völlig browserübergreifend funktioniert hat und bei der kein Faux-Hidden-Select-Box-Hack erstellt wurde.
Jesse Atkinson
15
Sei vorsichtig damit. Es scheint zunächst großartig zu funktionieren, aber irgendwo auf der Strecke hört es auf. Hier ist eine kleine Demo: jsfiddle.net/Yb6sk/9
Bill Criswell
17
Obwohl diese Lösung das Element verbirgt, wird jeder Versuch, den Wert von <select>(mit jQuery's .val()) zu lesen, zurückgegeben null. Ich habe das gerade in Chrome 29 getestet, also Vorsicht, Googler!
Mark
9
Interessanter Hack, aber ich würde empfehlen, "technisch ungültiges HTML" nach Möglichkeit zu vermeiden.
Luke
3
Richtig, alle Browser haben unterschiedliche Implementierungen. Ein Grund, warum Browser die Standardspezifikationen nicht strikt implementieren können, ist, dass es zu viel Live-Code gibt, der nicht den Spezifikationen entspricht. IMO: Wenn es keine anderen Lösungen gibt, dann verwenden Sie auf jeden Fall einen Hack. Aber wenn Sie der Spezifikation folgen und Ihr Problem lösen können, warum würden Sie es nicht tun? Es hilft Ihrem Code, gut mit anderen zu spielen und die Spezifikation zu stärken.
Luke
79

Für HTML5 können Sie das Attribut 'hidden' verwenden.

<option hidden>Hidden option</option>

Es wird von IE <11 nicht unterstützt. Wenn Sie jedoch nur einige Elemente ausblenden müssen, ist es möglicherweise besser, das verborgene Attribut in Kombination mit deaktiviert festzulegen, als Elemente hinzuzufügen / zu entfernen oder nicht semantisch korrekte Konstruktionen auszuführen.

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

Referenz .

Lukas Jelinek
quelle
4
IE 11 unterstützt dies.
Iván Pérez
6
Dies ist die moderne Antwort. Im Idealfall stellen wir dies auch disabledso ein, dass Browser, die das globale HTML5- hiddenAttribut nicht unterstützen, eine visuelle Anzeige für den Benutzer haben.
Cloudworks
1
Wie verwenden Sie diese Technik mit CSS?
GetFree
7
Funktioniert nicht in Safari, Edge oder IE. Bug for Safari ist 10 Jahre alt. Bitte helfen Sie, indem Sie vorhandene Patches aktualisieren. Fehler im Edge Issue Tracker kann nicht gefunden werden.
Indolering
5
Eine Problemumgehung hierfür ist die Verwendung <option hidden disabled>, sodass es in allen guten Browsern ausgeblendet und in den anderen deaktiviert wird.
Ramon Balthazar
36

Ich würde vorschlagen , dass Sie nicht die Lösungen verwenden , die eine Verwendung <span>Wrapper , weil es nicht gültige HTML ist, die Probleme auf dem Weg führen könnte. Ich denke, die bevorzugte Lösung besteht darin, alle Optionen, die Sie ausblenden möchten, tatsächlich zu entfernen und bei Bedarf wiederherzustellen. Mit jQuery benötigen Sie nur diese drei Funktionen:

Die erste Funktion speichert den ursprünglichen Inhalt der Auswahl . Aus Sicherheitsgründen können Sie diese Funktion beim Laden der Seite aufrufen.

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

Diese nächste Funktion ruft die obige Funktion auf, um sicherzustellen, dass der ursprüngliche Inhalt gespeichert wurde, und entfernt dann einfach die Optionen aus dem DOM.

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

Die letzte Funktion kann immer dann verwendet werden, wenn Sie alle ursprünglichen Optionen "zurücksetzen" möchten.

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

Beachten Sie, dass alle diese Funktionen erwarten, dass Sie jQuery-Elemente übergeben. Beispielsweise:

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

Hier ist ein funktionierendes Beispiel: http://jsfiddle.net/9CYjy/23/

Luke
quelle
2
Zuverlässig und kein Hack. Gute Antwort!
Jeremy Cook
1
@DanBeaulieu In der vorherigen jsfiddle wurde eine Funktion falsch benannt. Ich habe den obigen Link repariert und aktualisiert. Danke, dass du das verstanden hast.
Luke
Ja, das war auch meine Wahl. Ich habe es tatsächlich geschafft, den Code etwas kleiner zu spielen, indem ich zuerst den Datenwert in eine Variable genommen habe. Wenn er nicht definiert ist, werden die Optionen gespeichert, andernfalls werden die Optionen wiederhergestellt. Mein Bedürfnis war spezifisch für solche.
Diynevala
1
Ich musste hinzufügen var value=$select.val(); $select.html(ogHTML); $select.val(value);, um den ausgewählten Wert auch nach der Wiederherstellung ausgewählt zu halten.
Diynevala
Der Zyklus der Auswahl der zu entfernenden und zu entfernenden Optionen funktionierte nur einmal. Danach hatte options.remove () keine Auswirkung mehr auf mich. Nachdem ich den Befehl restoreOptions ($ s) verschoben hatte, wurden einige Zeilen aufgerufen, sodass ich immer mit einem vollständigen, frischen Select-Objekt arbeitete. Es funktionierte.
Newclique
18

Die Antwort von Ryan P sollte geändert werden in:

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

Andernfalls wird es in zu viele Tags eingeschlossen

JeffT
quelle
5
Beachten Sie, dass gemäß den HTML-Spezifikationen ( w3.org/TR/html5/forms.html#the-select-element ) a <select>nur <option>oder <optgroup>oder skriptunterstützende Elemente enthalten sollte. Sie sollten daher die Verwendung ungültiger <span>Wrapper vermeiden .
Luke
9

Die toggleOption-Funktion ist nicht perfekt und hat in meiner Anwendung böse Fehler verursacht. jQuery wird mit .val () und .arraySerialize () verwechselt. Versuchen Sie, die Optionen 4 und 5 auszuwählen, um zu sehen, was ich meine:

<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>
Batiste Bieler
quelle
8

Ausgewählte Eingänge sind auf diese Weise schwierig. Wie wäre es stattdessen mit einer Deaktivierung? Dies funktioniert browserübergreifend:

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

Dadurch wird jedes andere <option>Element deaktiviert , Sie können jedoch auswählen, welches Element Sie möchten.

Hier ist eine Demo: http://jsfiddle.net/jYWrH/

Hinweis: Wenn Sie die deaktivierte Eigenschaft eines Elements entfernen möchten, können Sie sie verwenden .removeProp('disabled').

Aktualisieren

Sie können die <option>Elemente, die Sie ausblenden möchten, in einem versteckten Auswahlelement speichern :

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

Sie können die <option>Elemente dann wieder zum ursprünglichen Auswahlelement hinzufügen :

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

In diesen beiden Beispielen wird erwartet, dass das sichtbare Auswahlelement die ID von visibleund das versteckte Auswahlelement die ID von hat hidden.

Hier ist eine Demo: http://jsfiddle.net/jYWrH/1/

Beachten Sie, dass dies .on()in jQuery 1.7 neu ist und dass die Verwendung für diese Antwort dieselbe ist wie .bind(): http://api.jquery.com/on

Jaspis
quelle
7

Einfache Antwort: Sie können nicht. Formularelemente verfügen nur über sehr eingeschränkte Gestaltungsmöglichkeiten.

Die beste Alternative wäre disabled=true, die Option festzulegen (und möglicherweise eine graue Farbe, da dies nur der IE automatisch ausführt). Dadurch wird die Option nicht mehr angeklickt.

Wenn Sie können, können Sie das optionElement auch vollständig entfernen .

Niet the Dark Absol
quelle
6
// Simplest way

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

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

Da Sie JS bereits verwenden, können Sie ein verstecktes SELECT-Element auf der Seite erstellen und es für jedes Element, das Sie in dieser Liste ausblenden möchten, in die versteckte Liste verschieben. Auf diese Weise können sie leicht wiederhergestellt werden.

Ich kenne keine Möglichkeit, dies in reinem CSS zu tun ... Ich hätte gedacht, dass die Anzeige: Kein Trick hätte funktioniert.

Derreck Dean
quelle
2

!!! WARNUNG !!!

Ersetzen Sie das zweite "IF" durch "WHILE" oder funktioniert nicht!

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;" />' );
    }
};
Arraxas
quelle
2

Sie sollten sie aus dem <select>JavaScript entfernen . Dies ist der einzig garantierte Weg, um sie zum Verschwinden zu bringen.

Jordanien
quelle
1
Mit jQuery kann dies mit entfernen:$('options').remove();
Luke
2

Dieser scheint für mich in Chrom zu funktionieren

$("#selectid span option").unwrap();
$("#selectid option:not([filterattr=filtervalue])").wrap('<span/>');
verbannt
quelle
1
Bitte fügen Sie Ihrem Code das Codeformat hinzu, indem Sie entweder mit 4 Leerzeichen einrücken oder Ihren Code mit `einschließen.
Banane
1
Dieser Code ist großartig! es funktioniert auf neuesten Chrome, Firefox und IE 11, das ist gut genug für mich :)
Sijav
1
Vor meinem letzten Kommentar funktioniert dieses Ding auch auf IE 7! ff ff, das ist, was ich mir zuletzt ausgedacht habe, es behält irgendwie in IE und Chrome den Wert bei, der ausgewählt wurde, bevor Optionen ausgeblendet werden, und wenn ein anderer Wert nach dem Zurücksetzen des Optionsbrowsers nicht festgelegt wird, wird die Option festgelegt ausgewählt wie zuvor!
Sijav
0

Spät im Spiel, aber die meisten davon scheinen ziemlich kompliziert zu sein.

So habe ich es gemacht:

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 von Select-1:

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

Markup von Select-2:

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