Quelle est la meilleure façon d'ajouter des options à une sélection en tant qu'objet JavaScript avec jQuery?

1380

Quelle est la meilleure méthode pour ajouter des options à un <select>objet JavaScript à l'aide de jQuery?

Je cherche quelque chose pour lequel je n'ai pas besoin d'un plugin, mais je serais également intéressé par les plugins qui existent.

C'est ce que j'ai fait:

selectValues = { "1": "test 1", "2": "test 2" };

for (key in selectValues) {
  if (typeof (selectValues[key] == 'string') {
    $('#mySelect').append('<option value="' + key + '">' + selectValues[key] + '</option>');
  }
}

Une solution propre / simple:

Ceci est une version nettoyée et simplifiée de matdumsa :

$.each(selectValues, function(key, value) {
     $('#mySelect')
          .append($('<option>', { value : key })
          .text(value));
});

Modifications par rapport à matdumsa: (1) a supprimé la balise close pour l'option à l'intérieur de append () et (2) a déplacé les propriétés / attributs dans une carte comme deuxième paramètre de append ().

Darryl Hein
la source
4
peut-être de l'aide: texotela.co.uk/code/jquery/select (c'était une aide pour moi après que je suis tombé sur cette question)
ManBugra
2
La version nettoyée répertoriée ci-dessus ne fonctionne que dans Jquery 1.4+. Pour les versions plus anciennes, utilisez celle de la réponse de
matdumsa
{value: key} devrait être {"value": key} comme on le voit dans la réponse de matdumsa.
Nick P
Je ne le crois pas, car valueétant une chaîne (et codée en dur), elle n'a pas besoin d'être citée.
Darryl Hein
1
Le titre devrait être à la place "Quelle est la meilleure façon d'ajouter des options à une sélection à partir d'un objet JSON avec jQuery?
Dr Fred

Réponses:

1384

Identique aux autres réponses, de manière jQuery:

$.each(selectValues, function(key, value) {   
     $('#mySelect')
         .append($("<option></option>")
                    .attr("value", key)
                    .text(value)); 
});
matdumsa
la source
99
Je voudrais tout d'abord attribuer $("#mySelect")à un var, sinon appeler à $("#mySelect")chaque fois dans la boucle est très inutile, tout comme la mise à jour du DOM. Voir les points # 3 et # 6 sur artzstudio.com/2009/04/jquery-performance-rules/…
Patrick
7
vous pouvez simplement faire var mySelect = $("#mySelect") outside of the chaque boucle. Ce serait beaucoup plus efficace. Voir la réponse de Carl ci
Patrick
17
Ma recommandation pour un meilleur style jQuery: $ ('# mySelect') .append ($ ("<option />") .val (key) .text (value));
FAjir
10
Avec la popularité de cette réponse, il convient de mentionner que vous devez éviter les mises à jour DOM dans les boucles. jsperf.com/jquery-append-array-vs-string
jthomas
6
cette réponse était tellement trompeuse à cause de la mauvaise intention ... attret textsont en fait des méthodes de l' $('<option/>')objet
phil294
268
var output = [];

$.each(selectValues, function(key, value)
{
  output.push('<option value="'+ key +'">'+ value +'</option>');
});

$('#mySelect').html(output.join(''));

De cette façon, vous "touchez le DOM" une seule fois.

Je ne sais pas si la dernière ligne peut être convertie en $ ('# mySelect'). Html (output.join ('')) parce que je ne connais pas les internes de jQuery (peut-être qu'il fait un peu d'analyse dans le html () méthode)

gpilotino
la source
20
Votre méthode est évidemment la plus rapide que la «bonne» réponse ci-dessus car elle utilise aussi moins jQuery.
Teej
4
la ligne "$ ('# mySelect'). get (0) .innerHTML = output.join ('');" fonctionne dans Chrome et FF3.x mais pas dans IE7 pour autant que je sache
blu
19
Cela casse si l' keya contient des guillemets >, <.
nickf
3
Et, si j'ai deux options que je ne veux pas perdre. Comment puis-je ajouter ces nouvelles valeurs d'options à celles existantes?
VansFannel
6
Une petite amélioration consiste à concaténer en utilisant la jointure plutôt que le signe plus, comme ceci: output.push ('<option value = "', key, '">', value, '</option>');
MM.
202

C'est un peu plus rapide et plus propre.

var selectValues = {
  "1": "test 1",
  "2": "test 2"
};
var $mySelect = $('#mySelect');
//
$.each(selectValues, function(key, value) {
  var $option = $("<option/>", {
    value: key,
    text: value
  });
  $mySelect.append($option);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<select id="mySelect"></select>

rocktheroad
la source
3
Parfait. Pour y ajouter, des attributs supplémentaires pour la sélection pourraient être ajoutés. $ .each (selectValues, function (id, value, text) {$ ('# mySelect'). append ($ ("<option />", {id: id value: value, text: text}));} );
idok
45
Il pense que ce sera une meilleure idée de mettre en cache `$ ('# mySelect')`, de sorte que vous ne cherchiez qu'une seule fois avant la boucle. Actuellement, il recherche l'élément DOM pour chaque option.
Sushanth -
@ Sushanth-- quelle est la taille d'un hit de performance si l'ensemble est petit?
ckarbass
3
@ckarbass - dépend de la taille de votre DOM. Potentiellement grand et très peu d'effort pour l'assigner à une variable, considérablement moins que d'écrire un commentaire dans SO!
Nick H247
97

jQuery

var list = $("#selectList");
$.each(items, function(index, item) {
  list.append(new Option(item.text, item.value));
});

JavaScript vanille

var list = document.getElementById("selectList");
for(var i in items) {
  list.add(new Option(items[i].text, items[i].value));
}
Carl Hörberg
la source
4
Jamais entendu parler de l' Optionobjet auparavant. Est-ce intégré à tous les navigateurs?
Darryl Hein
2
J'ai essayé d'utiliser new Option, mais j'ai constaté que cela ne fonctionnait pas dans IE6 et 7. Je n'ai pas de raison, mais la plupart des options jQuery complètes ont fonctionné.
Darryl Hein
Belle façon d'ajouter également une sélection. new Option('display', value, true)
Boatcoder
@ Mark0978 en fait c'est new Option('display', value, true, true)( javascriptkit.com/jsref/select.shtml )
Carl Hörberg
38

Si vous n'avez pas à prendre en charge les anciennes versions d'IE, l'utilisation du Optionconstructeur est clairement la voie à suivre, une solution lisible et efficace :

$(new Option('myText', 'val')).appendTo('#mySelect');

Sa fonctionnalité est équivalente à, mais plus propre que:

$("<option></option>").attr("value", "val").text("myText")).appendTo('#mySelect');
Nickolay
la source
31

Cela semble plus agréable, offre une lisibilité, mais est plus lent que les autres méthodes.

$.each(selectData, function(i, option)
{
    $("<option/>").val(option.id).text(option.title).appendTo("#selectBox");
});

Si vous voulez de la vitesse, la méthode la plus rapide (testée!) Est celle-ci, en utilisant un tableau, pas une concaténation de chaînes, et en utilisant un seul appel d'ajout.

auxArr = [];
$.each(selectData, function(i, option)
{
    auxArr[i] = "<option value='" + option.id + "'>" + option.title + "</option>";
});

$('#selectBox').append(auxArr.join(''));
m1sfit
la source
Cela ne signifie-t-il pas que le moyen "le plus rapide" serait également d'insérer les différentes parties de chaîne en tant qu'éléments de tableau individuels, au lieu de concaténer les éléments constitutifs de chaque option avant de les insérer dans le tableau, car ils seront tous joints de la même façon à la fin?
bitoolean
22

Un raffinement des plus anciens réponse de @ joshperry :

Il semble que plaine. Append fonctionne également comme prévu,

$("#mySelect").append(
  $.map(selectValues, function(v,k){

    return $("<option>").val(k).text(v);
  })
);

ou plus court,

$("#mySelect").append(
  $.map(selectValues, (v,k) => $("<option>").val(k).text(v))
  // $.map(selectValues, (v,k) => new Option(v, k)) // using plain JS
);
Сухой27
la source
pourriez-vous utiliser alternativement $.weakmappour permettreGC
Chef_Code
2
Points bonus pour l'élégance: utiliser de manière appropriée la map()construction, combinée avec la propriété d' append()ajouter correctement un tableau d'objets!
Jochem Schulenklopper
@joshperry Je suis un peu déçu car je m'attendais à une correction / mise à jour technique.
Сухой27
20

Toutes ces réponses semblent inutilement compliquées. Tout ce dont tu as besoin c'est:

var options = $('#mySelect').get(0).options;
$.each(selectValues, function(key, value) {
        options[options.length] = new Option(value, key);
});

C'est complètement compatible avec tous les navigateurs.

Animisme
la source
Devrait-il en être ainsi new Option(value, key);? L' ordre des paramètres est Options (text_visible_part, value_behind_the_scenes).
Bob Stein,
Array push n'est-il pas compatible avec plusieurs navigateurs? Alors, n'est-ce pas inutilement compliqué, lorsque la poussée de tableau est plus lisible?
bitoolean
18

Soyez prévenu ... J'utilise jQuery Mobile 1.0b2 avec PhoneGap 1.0.0 sur un téléphone Android 2.2 (Cyanogen 7.0.1) (T-Mobile G2) et je n'ai pas pu faire fonctionner la méthode .append (). J'ai dû utiliser .html () comme suit:

var options;
$.each(data, function(index, object) {
    options += '<option value="' + object.id + '">' + object.stop + '</option>';
});

$('#selectMenu').html(options);
Jack Holt
la source
18
 var output = [];
 var length = data.length;
 for(var i = 0; i < length; i++)
 {
    output[i++] = '<option value="' + data[i].start + '">' + data[i].start + '</option>';
 }

 $('#choose_schedule').get(0).innerHTML = output.join('');

J'ai fait quelques tests et cela, je crois, fait le travail le plus rapidement. : P

Teej
la source
1
. Chacun est notoirement lent par rapport à d'autres façons d'obtenir le même résultat. C'est ce que je pensais et recommanderais cette approche.
Allen Tellez
Il est regrettable que 90% des variations ici utilisent $ .each (). Une boucle for () peut vous donner beaucoup plus de contrôle et de performances, même si elle est moins compacte.
HoldOffHunger
15

Il existe une approche utilisant l'approche Microsoft Templating qui est actuellement proposée pour inclusion dans le noyau jQuery. Il y a plus de puissance dans l'utilisation des modèles, donc pour le scénario le plus simple, ce n'est peut-être pas la meilleure option. Pour plus de détails, consultez l'article de Scott Gu décrivant les fonctionnalités.

Commencez par inclure le fichier js de modèles, disponible sur github .

<script src="Scripts/jquery.tmpl.js" type="text/javascript" />

Configurer ensuite un modèle

<script id="templateOptionItem" type="text/html">
    <option value=\'{{= Value}}\'>{{= Text}}</option>
</script>

Ensuite, avec vos données, appelez la méthode .render ()

var someData = [
    { Text: "one", Value: "1" },
    { Text: "two", Value: "2" },
    { Text: "three", Value: "3"}];

$("#templateOptionItem").render(someData).appendTo("#mySelect");

J'ai blogué cette approche plus en détail.

Nick Josevski
la source
12

J'ai créé quelque chose comme ça, en chargeant un élément de liste déroulante via Ajax . La réponse ci-dessus est également acceptable, mais il est toujours bon d'avoir le moins de modifications DOM possible pour de meilleures performances.

Ainsi, plutôt que d'ajouter chaque élément dans une boucle, il est préférable de collecter les éléments dans une boucle et de les ajouter une fois qu'elle est terminée.

$(data).each(function(){
    ... Collect items
})

Ajoutez-le,

$('#select_id').append(items); 

ou encore mieux

$('#select_id').html(items);
Komang
la source
$ ('# select_id'). html (items); a fonctionné exactement comme je le voulais.en utilisant append, il continue d'ajouter les éléments dans tous les événements onchange. Merci beaucoup.
Dipanwita Das
10

La manière la plus simple est:

$('#SelectId').html("<option value='0'>select</option><option value='1'>Laguna</option>");
willard macay
la source
J'ai déjà construit ma liste d'options, donc remplir le champ de sélection était aussi simple que Willard le dit.
Loony2nz
10

La plupart des autres réponses utilisent la eachfonction pour parcourir le selectValues. Cela nécessite que append soit appelé pour chaque élément et une redistribution est déclenchée lorsque chacun est ajouté individuellement.

La mise à jour de cette réponse à une méthode fonctionnelle plus idiomatique (en utilisant JS moderne) peut être formée pour appeler appendune seule fois, avec un tableau d' optionéléments créés en utilisant la carte et unOption constructeur d'élément.

L'utilisation d'un Optionélément DOM devrait réduire la surcharge des appels de fonction car l' optionélément n'a pas besoin d'être mis à jour après la création et la logique d'analyse de jQuery n'a pas besoin de s'exécuter.

$('mySelect').append($.map(selectValues, (k, v) => new Option(k, v)))

Cela peut être simplifié davantage si vous créez une fonction utilitaire d'usine qui va créer un objet option:

const newoption = (...args) => new Option(...args)

Ensuite, cela peut être fourni directement à map:

$('mySelect').append($.map(selectValues, newoption))

Formulation précédente

Parce que appendpermet également passer des valeurs comme un nombre variable d'arguments, nous pouvons créer au préalable la liste des optionéléments carte et les ajouter comme arguments dans un seul appel à l'aide apply.

$.fn.append.apply($('mySelect'), $.map(selectValues, (k, v) => $("<option/>").val(k).text(v)));

Il ressemble à cela dans les versions ultérieures de jQuery, appendaccepte également un argument de tableau et cela peut être quelque peu simplifié:

$('mySelect').append($.map(selectValues, (k, v) => $("<option/>").val(k).text(v)))
joshperry
la source
10
function populateDropdown(select, data) {   
    select.html('');   
    $.each(data, function(id, option) {   
        select.append($('<option></option>').val(option.value).html(option.name));   
    });          
}   

Cela fonctionne bien avec jQuery 1.4.1.

Pour un article complet sur l'utilisation des listes dynamiques avec ASP.NET MVC et jQuery, visitez:

Listes de sélection dynamique avec MVC et jQuery

H Sampat
la source
8

Il y a un problème de tri avec cette solution dans Chrome (jQuery 1.7.1) (Chrome trie les propriétés des objets par nom / numéro?) Donc, pour garder l'ordre (oui, c'est un abus d'objet), j'ai changé ceci:

optionValues0 = {"4321": "option 1", "1234": "option 2"};

pour ça

optionValues0 = {"1": {id: "4321", value: "option 1"}, "2": {id: "1234", value: "option 2"}};

puis le $ .each ressemblera à:

$.each(optionValues0, function(order, object) {
  key = object.id;
  value = object.value;
  $('#mySelect').append($('<option>', { value : key }).text(value));
}); 
Michail
la source
8

Plutôt que de répéter le même code partout, je suggère qu'il est plus souhaitable d'écrire votre propre fonction jQuery comme:

jQuery.fn.addOption = function (key, value) {
    $(this).append($('<option>', { value: key }).text(value));
};

Ensuite, pour ajouter une option, procédez comme suit:

$('select').addOption('0', 'None');
Mat
la source
Pourriez-vous élaborer?
Mo.17
7

Vous pouvez simplement parcourir votre tableau json avec le code suivant

$('<option/>').attr("value","someValue").text("Option1").appendTo("#my-select-id");

kashif
la source
7

Bien que les réponses précédentes soient toutes des réponses valides - il peut être conseillé de les ajouter à un documentFragmnet d'abord, puis d'ajouter ce fragment de document en tant qu'élément après ...

Voir les réflexions de John Resig sur la question ...

Quelque chose dans le sens de:

var frag = document.createDocumentFragment();

for(item in data.Events)
{
    var option = document.createElement("option");

    option.setAttribute("value", data.Events[item].Key);
    option.innerText = data.Events[item].Value;

    frag.appendChild(option);
}
eventDrop.empty();
eventDrop.append(frag);
Stuart.Sklinar
la source
7
  1. $.each est plus lent qu'un for boucle
  2. A chaque fois, une sélection DOM n'est pas la meilleure pratique en boucle $("#mySelect").append();

La meilleure solution est donc la suivante

Si les données JSON respsont

[
    {"id":"0001", "name":"Mr. P"},
    {"id":"0003", "name":"Mr. Q"},
    {"id":"0054", "name":"Mr. R"},
    {"id":"0061", "name":"Mr. S"}
]

l'utiliser comme

var option = "";
for (i=0; i<resp.length; i++) {
    option += "<option value='" + resp[i].id + "'>" + resp[i].name + "</option>";
}
$('#mySelect').html(option);
MaxEcho
la source
6

Encore une autre façon de procéder:

var options = [];    
$.each(selectValues, function(key, value) {
    options.push($("<option/>", {
        value: key,
        text: value
    }));
});
$('#mySelect').append(options);
DiverseAndRemote.com
la source
Je vois ce que vous avez fait ici ... Vous avez pris le conseil de mettre en cache $('#mySelect')puis refactorisé la réponse @rocktheroad ... peu importe, c'est la solution la plus pratique
Chef_Code
6
if (data.length != 0) {
    var opts = "";
    for (i in data)
        opts += "<option value='"+data[i][value]+"'>"+data[i][text]+"</option>";

    $("#myselect").empty().append(opts);
}

Cela ne manipule le DOM qu'une seule fois après la première construction d'une chaîne géante.

Christian Roman
la source
vous pouvez optimiser cela davantage et éviter complètement l'utilisation de jQuery en remplaçant $("#myselect").empty().append(opts);pargetElementById('myselect').innerHtml = opts;
vahanpwns
6

C'est ce que j'ai fait avec les tableaux bidimensionnels: la première colonne est l'élément i, ajoutez innerHTML-le à <option>. La deuxième colonne est RECORD_ID i, ajouter à valuela <option>:

  1. PHP

    $items = $dal->get_new_items(); // Gets data from the database
    $items_arr = array();
    $i = 0;
    foreach ($items as $item)
    {
        $first_name = $item->first_name;
        $last_name = $item->last_name;
        $date = $item->date;
        $show = $first_name . " " . $last_name . ", " . $date;
        $request_id = $request->request_id;
        $items_arr[0][$i] = $show;
        $items_arr[1][$i] = $request_id;
        $i++;
    }
    
    echo json_encode($items_arr);
  2. JavaScript / Ajax

            function ddl_items() {
                if (window.XMLHttpRequest) {
                    // Code for Internet Explorer 7+, Firefox, Chrome, Opera, and Safari
                    xmlhttp=new XMLHttpRequest();
                }
                else{
                    // Code for Internet Explorer 6 and Internet Explorer 5
                    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
                }
    
                xmlhttp.onreadystatechange=function() {
                if (xmlhttp.readyState==4 && xmlhttp.status==200) {
                    var arr = JSON.parse(xmlhttp.responseText);
                    var lstbx = document.getElementById('my_listbox');
    
                    for (var i=0; i<arr.length; i++) {
                        var option = new Option(arr[0][i], arr[1][i]);
                        lstbx.options.add(option);
                    }
                }
            };
    
            xmlhttp.open("GET", "Code/get_items.php?dummy_time=" + new Date().getTime() + "", true);
            xmlhttp.send();
        }
    }
Salé
la source
Cela semble bon. Dommage qu'il n'utilise pas jQuery. De plus, j'ai déjà rencontré des problèmes avec la méthode select.options.add (). Je ne me souviens pas du navigateur et du problème exact, mais j'ai décidé de m'en éloigner et de laisser jQuery gérer les différences.
Darryl Hein
im un noob total avec PHP et JQuerry, mais le code ci-dessus fonctionne dans tous les navigateurs. le seul problème - ça ne fonctionne pas bien sur iPhone, j'ai posté une question à ce sujet, pas de chance jusqu'à présent :( stackoverflow.com/questions/11364040/…
Salty
5

J'ai trouvé que c'est simple et fonctionne très bien.

for (var i = 0; i < array.length; i++) {
    $('#clientsList').append($("<option></option>").text(array[i].ClientName).val(array[i].ID));
};
DW333
la source
4

Le format JSON:

[{
    "org_name": "Asset Management"
}, {
    "org_name": "Debt Equity Foreign services"
}, {
    "org_name": "Credit Services"
}]

Et le code jQuery pour remplir les valeurs pour le succès Dropdown on Ajax:

success: function(json) {
    var options = [];
    $('#org_category').html('');  // Set the Dropdown as Blank before new Data
    options.push('<option>-- Select Category --</option>');
    $.each(JSON.parse(json), function(i, item) {
        options.push($('<option/>',
        {
           value: item.org_name, text: item.org_name
        }));
    });
    $('#org_category').append(options);  // Set the Values to Dropdown
}
MJ
la source
3

En utilisant la fonction $ .map (), vous pouvez le faire de manière plus élégante:

$('#mySelect').html( $.map(selectValues, function(val, key){
    return '<option value="' + val + '">'+ key + '</option>';
}).join(''));
Dr Fred
la source
C'est un peu plus court, mais le seul problème consiste à échapper au val et aux variables clés, ce que fait la réponse acceptée.
Darryl Hein
2
<!DOCTYPE html>
<html lang="en">
<head>
  <title>append selectbox using jquery</title>
  <meta charset="utf-8">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

  <script type="text/javascript">
    function setprice(){
        var selectValues = { "1": "test 1", "2": "test 2" };
        $.each(selectValues, function(key, value) {   
     $('#mySelect')
         .append($("<option></option>")
                    .attr("value",key)
                    .text(value)); 
});

    }
  </script>
</head>
<body onload="setprice();">


      <select class="form-control" id="mySelect">
    <option>1</option>
    <option>2</option>
    <option>3</option>
    <option>4</option>
  </select>


</body>
</html>
Satyendra Yadav
la source
2

Définissez votre identifiant de sélection HTML dans la ligne suivante ci-dessous. Ici mySelectest utilisé comme id de l'élément de sélection.

   var options = $("#mySelect");

puis récupérez l'objet correspondant aux selectValues ​​dans ce scénario et définissez-le sur jquery pour chaque boucle. Il utilisera la valeur et le texte des objets en conséquence et les ajoutera aux sélections d'options comme suit.

$.each(selectValues, function(val, text) {
            options.append(
             $('<option></option>').val(val).html(text)
          );
      });

Cela affichera le texte comme liste d'options lorsque la liste déroulante est sélectionnée et une fois le texte sélectionné, la valeur du texte sélectionné sera utilisée.

Par exemple.

"1": "test 1", "2": "test 2",

Menu déroulant,

nom d'affichage: test 1 -> la valeur est 1 nom d'affichage: test 2 -> la valeur est 2

Dulith De Costa
la source
veuillez décrire un peu la solution.
Vinay Prajapati
2

En fait, pour obtenir des performances améliorées, il est préférable de faire la liste d'options séparément et de l'ajouter pour sélectionner l'id.

var options = [];
$.each(selectValues, function(key, value) {
    options.push ($('<option>', { value : key })
          .text(value));
});
 $('#mySelect').append(options);

http://learn.jquery.com/performance/append-outside-loop/

shohan
la source