jQuery / Selector / :selected — Sélectionner les options choisies d’un select

jQuery :selected cible les option actuellement choisies dans un select. $("#fruit option:selected") récupère les éléments ; $("#fruit").val() lit directement la valeur. L’attribut HTML selected et l’état modifié par l’utilisateur peuvent différer.

Éléments, valeurs et libellés

La référence :selected concerne les options, pas les cases à cocher ni les radios. Limitez la recherche au select ou formulaire voulu pour éviter de mélanger d’autres contrôles.

.text() donne le libellé, .val() la valeur. Sur plusieurs option, .val() lit seulement la première et .text() concatène les textes. Pour toutes les valeurs multiples, utilisez .val() sur le select ; pour des informations par élément, map ou une boucle.

L’exemple distingue un fruit et plusieurs sujets, avec JavaScript comme libellé et js comme identifiant. Des options et un optgroup désactivés montrent la différence entre sélection et valeurs admissibles à l’envoi.

Exemple complet simple et multiple

Enregistrez et ouvrez selected-demo.html en UTF-8. Internet charge jQuery complet 4.0.0, sans serveur ni compilation. Windows Edge avec 4.0.0 et 3.7.1 a vérifié état initial, clavier, options désactivées, sélection vide et Reset.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Read selected options and submitted values</title>
  <script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
  <style>
    body { font: 16px/1.6 sans-serif; max-width: 740px; margin: 20px; }
    label { display: block; margin-top: 12px; }
    select, button { font: inherit; max-width: 100%; margin: 6px 0; }
    #topics { display: block; min-width: 230px; }
    pre { white-space: pre-wrap; overflow-wrap: anywhere; }
  </style>
</head>
<body>
  <form id="chooser">
    <label for="fruit">Fruit (single)</label>
    <select id="fruit" name="fruit"><option value="apple">Apple</option><option value="banana">Banana</option></select>
    <label for="topics">Topics (multiple)</label>
    <select id="topics" name="topics" multiple size="6">
      <option value="js" selected>JavaScript</option>
      <option value="css">CSS</option>
      <option value="html" selected disabled>HTML (disabled)</option>
      <optgroup label="Unavailable group" disabled><option value="legacy" selected>Legacy</option></optgroup>
    </select>
    <button type="button" id="set">Set Banana and CSS</button>
    <button type="button" id="clear">Clear topics</button>
    <button type="button" id="restore">Reset</button>
  </form>
  <pre id="result" aria-live="polite"></pre>
  <script>
    jQuery(function ($) {
      const $fruit = $("#fruit"), $topics = $("#topics"), form = document.querySelector("#chooser");
      let changes = 0;
      function values($options) { return $options.map(function () { return this.value; }).get(); }
      function render() {
        const $selected = $topics.find("option").filter(":selected");
        const data = new URLSearchParams(new FormData(form));
        $("#result").text("single=" + $fruit.val() + "\nsingleText=" + $fruit.find("option:selected").text() +
          "\nselectedOptions=" + JSON.stringify(values($selected)) + "\nvalues=" + JSON.stringify($topics.val()) +
          "\nselectedAttribute=" + JSON.stringify(values($topics.find("option[selected]"))) +
          "\nform=" + data.toString() + "\nchanges=" + changes);
      }
      $fruit.add($topics).on("change", function () { changes++; render(); });
      $("#set").on("click", function () {
        $fruit.val("banana").trigger("change"); $topics.val(["css"]).trigger("change");
      });
      $("#clear").on("click", function () { $topics.val([]).trigger("change"); });
      $("#restore").on("click", function () { form.reset(); changes = 0; render(); });
      render();
    });
  </script>
</body>
</html>

Fruit n’a aucun attribut selected, mais son premier élément Apple est choisi. Trois sujets sont sélectionnés ; seul js est admissible à l’envoi.

single=apple
singleText=Apple
selectedOptions=["js","html","legacy"]
values=["js"]
selectedAttribute=["js","html","legacy"]
form=fruit=apple&topics=js
changes=0
  1. Banana modifie single et singleText, y compris par change au clavier.
  2. Set Banana and CSS donne selectedOptions et values ["css"], tandis que selectedAttribute reste ["js","html","legacy"].
  3. Clear topics donne deux tableaux vides ; form ne contient plus que fruit.
  4. Reset restaure aussi les sélections HTML et Legacy désactivées.
  5. La sélection multiple manuelle utilise les touches du système/navigateur. Les boutons assurent des conditions de comparaison constantes.

selectedOptions énumère les valeurs DOM choisies, values est .val() du select, selectedAttribute les attributs présents. form représente FormData en requête URL, sans envoi. changes compte les traitements ; Set émet un événement pour chaque contrôle, donc deux.

État actuel et attribut par défaut

option.selected et :selected décrivent l’état courant. [selected] teste la présence de l’attribut ; defaultSelected décrit le choix par défaut. Un changement utilisateur ne réécrit pas cette valeur de la même manière. N’utilisez pas [selected] pour l’état courant.

.val(["css"]) modifie l’état courant et .val([]) vide le multiple. Le setter .val() n’émet pas change, d’où le déclenchement explicite. Sans événement ou render, le rapport peut rester ancien malgré le changement réel.

Depuis jQuery 3, un multiple sans choix renvoie []. Une collection option vide donne undefined avec .val(). Un select simple sans choix après une valeur inconnue donne null. Ce ne sont pas tous des textes vides.

Reset appelle form.reset() puis render. Modifier les attributs par défaut changerait aussi la destination de restauration. Ici ils restent et seules les valeurs courantes changent.

Désactivation, :checked et utilisation

Les options désactivées, notamment sous optgroup désactivé, peuvent rester sélectionnées mais sont exclues de .val() du select et de FormData. Le nombre sélectionné n’est pas le nombre envoyé : trois contre un au départ. Examinez aussi name absent ou select désactivé.

:checked couvre options, cases à cocher et radios. Limité à option:checked il donne ici les mêmes options ; une recherche globale peut mélanger les types.

:selected est une extension jQuery, invalide directement dans document.querySelectorAll() natif. L’exemple sélectionne par CSS puis filtre :selected. En natif, envisagez select.selectedOptions ou option:checked bien limité.

Appliquez couleurs et filtres une fois au départ puis aux changements. Prévoyez un rafraîchissement pour les affectations programmées, affichez les textes avec .text() plutôt que du HTML concaténé et vérifiez identifiants et règles métier côté serveur.