Was ist der beste Weg, um einer Auswahl als JavaScript-Objekt mit jQuery Optionen hinzuzufügen?


1379

Was ist die beste Methode zum Hinzufügen von Optionen zu <select>einem JavaScript-Objekt mithilfe von jQuery?

Ich suche etwas, für das ich kein Plugin brauche, aber ich würde mich auch für die Plugins interessieren, die es gibt.

Das habe ich getan:

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

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

Eine saubere / einfache Lösung:

Dies ist eine bereinigte und vereinfachte Version von matdumsa :

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

Änderungen von matdumsa: (1) Das Close-Tag für die Option in append () wurde entfernt und (2) die Eigenschaften / Attribute wurden als zweiter Parameter von append () in eine Map verschoben.


4
Vielleicht hilfreich: texotela.co.uk/code/jquery/select (es war eine Hilfe für mich, nachdem ich auf diese Frage
gestoßen bin

2
Die oben aufgeführte bereinigte Version funktioniert nur in Jquery 1.4+. Für ältere Versionen verwenden Sie die in Matdumsas Antwort
Thedric Walker

{value: key} sollte {"value": key} sein, wie in matdumsas Antwort zu sehen.
Nick P

Ich glaube nicht, da valuees sich um eine Zeichenfolge handelt (und fest codiert ist), muss sie nicht in Anführungszeichen gesetzt werden.
Darryl Hein

1
Der Titel sollte stattdessen lauten: "Was ist der beste Weg, um einer Auswahl aus einem JSON-Objekt mit jQuery Optionen hinzuzufügen?
Dr. Fred

Antworten:


1383

Das Gleiche wie bei anderen Antworten auf jQuery-Weise:

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

99
Ich würde zunächst $("#mySelect")eine Variable zuweisen , andernfalls ist das Aufrufen $("#mySelect")jedes Mal innerhalb der Schleife sehr verschwenderisch, ebenso wie das Aktualisieren des DOM. Siehe Punkte 3 und 6 unter artzstudio.com/2009/04/jquery-performance-rules/…
Patrick

7
var mySelect = $("#mySelect") outside of the Nun, Sie könnten einfach jede Schleife machen. Das wäre viel effizienter. Siehe Carls Antwort unten
Patrick

17
Meine Empfehlung für einen besseren jQuery-Stil: $ ('# mySelect') .append ($ ("<option />") .val (key) .text (value));
FAjir

10
Angesichts der Beliebtheit dieser Antwort ist es erwähnenswert, dass Sie DOM-Updates in Schleifen vermeiden sollten. jsperf.com/jquery-append-array-vs-string
jthomas

6
Diese Antwort war irreführend , so sehr wegen der falschen intendation ... attrund textsind eigentlich Methoden der $('<option/>')-object
phil294

268
var output = [];

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

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

Auf diese Weise "berühren Sie das DOM" nur einmal.

Ich bin nicht sicher, ob die letzte Zeile in $ ('# mySelect'). Html (output.join ('')) konvertiert werden kann, da ich keine jQuery-Interna kenne (möglicherweise wird etwas in html () analysiert. Methode)


20
Ihre Methode ist offensichtlich die schnellere als die 'richtige' Antwort oben, da sie auch weniger jQuery verwendet.
Teej

4
die Zeile "$ ('# mySelect'). get (0) .innerHTML = output.join ('');" funktioniert in Chrome und FF3.x, aber nicht in IE7, soweit ich das beurteilen kann
Blu

19
Dies bricht ab, wenn das keyeinige Anführungszeichen hat oder >, <drin ist.
Nickf

3
Und wenn ich zwei Möglichkeiten habe, die ich nicht verlieren möchte. Wie kann ich diese neuen Optionswerte an die vorhandenen anhängen?
VansFannel

6
Eine kleine Verbesserung besteht darin, den Join anstelle des Pluszeichens zu verketten, wie folgt: output.push ('<option value = "', key, '">', value, '</ option>');
MM.

202

Dies ist etwas schneller und sauberer.

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>


3
Perfekt. Zum Hinzufügen können zusätzliche Attribute für die Auswahl hinzugefügt werden. $ .each (selectValues, function (id, value, text) {$ ('# mySelect'). append ($ ("<option />", {id: id value: value, text: text});} );
Idok

45
Ich denke, es ist eine bessere Idee, `$ ('# mySelect')` zwischenzuspeichern, so dass Sie nur einmal vor der Schleife nachschlagen. Derzeit wird im DOM nach dem Element für jede einzelne Option gesucht.
Sushanth -

@ Sushanth-- Wie groß ist der Performance-Hit, wenn das Set klein ist?
Karbass

3
@ckarbass - hängt davon ab, wie groß Ihr DOM ist. Potenziell großer und sehr geringer Aufwand, um es einer Variablen zuzuweisen, erheblich weniger als das Schreiben eines Kommentars in SO!
Nick H247

97

jQuery

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

Vanille JavaScript

var list = document.getElementById("selectList");
for(var i in items) {
  list.add(new Option(items[i].text, items[i].value));
}

4
Noch nie von dem OptionObjekt gehört. Ist das in allen Browsern eingebaut?
Darryl Hein

2
Ich habe es versucht new Option, aber festgestellt, dass es in IE6 und 7 nicht funktioniert hat. Ich habe keinen Grund dafür, aber viele der vollständigen jQuery-Optionen haben funktioniert.
Darryl Hein

Gute Möglichkeit, auch eine Auswahl hinzuzufügen. new Option('display', value, true)
Bootscodierer

@ Mark0978 eigentlich ist es new Option('display', value, true, true)( javascriptkit.com/jsref/select.shtml )
Carl Hörberg

38

Wenn Sie keine alten IE-Versionen unterstützen müssen, ist die Verwendung des OptionKonstruktors eindeutig der richtige Weg, eine lesbare und effiziente Lösung :

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

Es ist in der Funktionalität gleichwertig, aber sauberer als:

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

31

Dies sieht besser aus, bietet Lesbarkeit, ist jedoch langsamer als andere Methoden.

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

Wenn Sie Geschwindigkeit wünschen, ist dies der schnellste (getestete!) Weg, indem Sie ein Array und keine Zeichenfolgenverkettung verwenden und nur einen Append-Aufruf verwenden.

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

$('#selectBox').append(auxArr.join(''));

Bedeutet dies nicht, dass der "schnellste" Weg darin besteht, die verschiedenen Zeichenfolgenteile auch als einzelne Array-Elemente einzufügen, anstatt die konstituierenden Elemente jeder Option vor dem Einfügen in das Array zu verketten, da sie am Ende ohnehin alle zu einem zusammengefügt werden?
Bitoolean

22

Eine Verfeinerung der Antwort älterer @ joshperry :

Es scheint, dass einfaches .append auch wie erwartet funktioniert,

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

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

oder kürzer,

$("#mySelect").append(
  $.map(selectValues, (v,k) => $("<option>").val(k).text(v))
  // $.map(selectValues, (v,k) => new Option(v, k)) // using plain JS
);

könnten Sie alternativ verwenden $.weakmap, um zu GC
berücksichtigen

2
Bonuspunkte für Eleganz: Verwenden Sie das map()Konstrukt angemessen , kombiniert mit der Eigenschaft append(), eine Reihe von Objekten korrekt hinzuzufügen!
Jochem Schulenklopper

@joshperry Ich bin ein bisschen enttäuscht, da ich technische Korrekturen / Updates erwartet habe.
27.

20

Alle diese Antworten scheinen unnötig kompliziert zu sein. Alles was Sie brauchen ist:

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

Das ist völlig browserübergreifend kompatibel.


Sollte es sein new Option(value, key);? Die Parameterreihenfolge lautet Optionen (text_visible_part, value_behind_the_scenes).
Bob Stein

Ist Array Push nicht browserübergreifend kompatibel? Ist das nicht unnötig kompliziert, wenn Array-Push besser lesbar ist?
Bitoolean

18

Seien Sie gewarnt ... Ich verwende jQuery Mobile 1.0b2 mit PhoneGap 1.0.0 auf einem Android 2.2-Telefon (Cyanogen 7.0.1) (T-Mobile G2) und konnte die .append () -Methode überhaupt nicht zum Laufen bringen. Ich musste .html () wie folgt verwenden:

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

$('#selectMenu').html(options);

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

Ich habe ein paar Tests gemacht und das macht, glaube ich, den Job am schnellsten. : P.


1
.each ist im Vergleich zu anderen Methoden, um das gleiche Ergebnis zu erzielen, notorisch langsam. Dies ist, was ich dachte und würde diesen Ansatz empfehlen.
Allen Tellez

Es ist bedauerlich, dass 90% der Variationen hier $ .each () verwenden. Eine for () - Schleife bietet Ihnen viel mehr Kontroll- und Leistungsvorteile, auch wenn sie weniger kompakt ist.
HoldOffHunger

15

Es gibt einen Ansatz, der den Microsoft Templating-Ansatz verwendet , der derzeit zur Aufnahme in den jQuery-Kern vorgeschlagen wird. Die Verwendung der Vorlage bietet mehr Leistung, sodass sie für das einfachste Szenario möglicherweise nicht die beste Option ist. Weitere Informationen finden Sie in Scott Gu's Beitrag, in dem die Funktionen beschrieben werden.

Fügen Sie zunächst die Template-js-Datei hinzu, die bei github erhältlich ist .

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

Richten Sie als Nächstes eine Vorlage ein

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

Rufen Sie dann mit Ihren Daten die Methode .render () auf

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

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

Ich habe diesen Ansatz detaillierter gebloggt .


12

Ich habe so etwas gemacht und ein Dropdown-Element über Ajax geladen . Die obige Antwort ist ebenfalls akzeptabel, aber es ist immer gut, so wenig DOM-Änderungen wie möglich vorzunehmen, um eine bessere Leistung zu erzielen.

Anstatt jedes Element in einer Schleife hinzuzufügen, ist es besser, Elemente in einer Schleife zu sammeln und anzuhängen, sobald es abgeschlossen ist.

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

Fügen Sie es hinzu,

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

oder noch besser

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

$ ('# select_id'). html (items); hat genau so funktioniert, wie ich es wollte. Mit append werden die Elemente in allen onchange-Ereignissen weiter angehängt. Ich danke dir sehr.
Dipanwita Das

10

Der einfache Weg ist:

$('#SelectId').html("<option value='0'>select</option><option value='1'>Laguna</option>");

Ich habe meine Optionsliste bereits erstellt, daher war das Auffüllen des Auswahlfelds so einfach, wie Willard sagt.
Loony2nz

10

Die meisten anderen Antworten verwenden die eachFunktion, um über die zu iterierenselectValues . Dies erfordert, dass für jedes Element ein Anhang aufgerufen wird und ein Reflow ausgelöst wird, wenn jedes einzeln hinzugefügt wird.

Das Aktualisieren dieser Antwort auf eine idiomatischere Funktionsmethode (unter Verwendung moderner JS) kann so formuliert werden, dass sie appendnur einmal aufgerufen wird , wobei ein Array von optionElementen mit map und einem OptionElementkonstruktor erstellt wird.

Die Verwendung eines OptionDOM-Elements sollte den Aufwand für Funktionsaufrufe verringern, da das optionElement nach der Erstellung nicht aktualisiert werden muss und die Parsing-Logik von jQuery nicht ausgeführt werden muss.

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

Dies kann weiter vereinfacht werden, wenn Sie eine Factory Utility-Funktion erstellen, mit der ein Optionsobjekt neu erstellt wird:

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

Dann kann dies direkt bereitgestellt werden an map:

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

Vorherige Formulierung

Da appendkönnen auch Werte als variable Anzahl von Argumenten geben, können wir die Liste der vorab erstellen optionElemente abzubilden und hängen Sie sie als Argumente in einem einzigen Anruf unter Verwendung apply.

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

Es sieht so aus, als würde in späteren Versionen von jQuery appendauch ein Array-Argument akzeptiert und dies kann etwas vereinfacht werden:

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

10
function populateDropdown(select, data) {   
    select.html('');   
    $.each(data, function(id, option) {   
        select.append($('<option></option>').val(option.value).html(option.name));   
    });          
}   

Es funktioniert gut mit jQuery 1.4.1.

Ein vollständiger Artikel zur Verwendung dynamischer Listen mit ASP.NET MVC & jQuery finden Sie unter:

Dynamische Auswahllisten mit MVC und jQuery


8

Es gibt ein Sortierproblem mit dieser Lösung in Chrome (jQuery 1.7.1) (Chrome sortiert Objekteigenschaften nach Name / Nummer?). Um die Reihenfolge beizubehalten (ja, es ist Objektmissbrauch), habe ich Folgendes geändert:

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

dazu

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

und dann sieht das $ .each so aus:

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

8

Anstatt überall denselben Code zu wiederholen, würde ich vorschlagen, dass es wünschenswerter ist, eine eigene jQuery-Funktion zu schreiben, wie:

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

Um eine Option hinzuzufügen, gehen Sie wie folgt vor:

$('select').addOption('0', 'None');

Könnten Sie näher darauf eingehen?
Mo.

7

Sie können einfach mit dem folgenden Code über Ihr JSON-Array iterieren

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


7

Obwohl die vorherigen Antworten alle gültige Antworten sind, kann es ratsam sein, alle diese Antworten zuerst an ein documentFragmnet anzuhängen und dann das Dokumentfragment als Element nach ...

Sehen Sie John Resigs Gedanken zu diesem Thema ...

Etwas in der Art von:

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

7
  1. $.each ist langsamer als a for Schleife
  2. Jedes Mal ist eine DOM-Auswahl nicht die beste Vorgehensweise in einer Schleife $("#mySelect").append();

Die beste Lösung ist also die folgende

Wenn JSON-Daten respsind

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

benutze es als

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

6

Noch eine andere Art, es zu tun:

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

Ich sehe, was Sie hier getan haben ... Sie haben den Rat $('#mySelect')befolgt, die Antwort von @rocktheroad zwischenzuspeichern und dann zu überarbeiten ... was auch immer, dies ist die praktischere Lösung
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);
}

Dies manipuliert das DOM nur einmal, nachdem zuerst eine riesige Zeichenfolge erstellt wurde.


Sie können dies weiter optimieren und die Verwendung von jQuery insgesamt vermeiden, indem Sie $("#myselect").empty().append(opts);durchgetElementById('myselect').innerHtml = opts;
vahanpwns

6

Das habe ich mit zweidimensionalen Arrays gemacht: Die erste Spalte ist Item i, add to innerHTMLthe <option>. Die zweite Säule ist RECORD_ID i, addieren , valueder <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();
        }
    }

Sieht gut aus. Schade, dass jQuery nicht verwendet wird. Außerdem hatte ich zuvor Probleme mit der Methode select.options.add (). Ich kann mich nicht erinnern, welcher Browser und welches Problem genau vorliegt, aber ich habe mich entschlossen, einen Weg davon zu gehen und jQuery die Unterschiede zu überlassen.
Darryl Hein

Ich bin ein absoluter Neuling mit PHP und JQuerry, aber der obige Code funktioniert in allen Browsern. Das einzige Problem - es funktioniert nicht gut auf dem iPhone, ich habe eine Frage dazu gepostet, bisher kein Glück :( stackoverflow.com/questions/11364040/…
Salty


5

Ich fand, dass dies einfach ist und großartig funktioniert.

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

4

Das JSON-Format:

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

Und der jQuery-Code zum Auffüllen der Werte für den Dropdown-Erfolg von 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
}

3

Mit der Funktion $ .map () können Sie dies auf elegantere Weise tun:

$('#mySelect').html( $.map(selectValues, function(val, key){
    return '<option value="' + val + '">'+ key + '</option>';
}).join(''));

Das ist etwas kürzer, aber das einzige Problem besteht darin, die val- und key-Variablen zu verlassen, was die akzeptierte Antwort tut.
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>

2

Stellen Sie Ihre HTML-Auswahl-ID in die folgende Zeile ein. Hier mySelectwird als ID des Auswahlelements verwendet.

   var options = $("#mySelect");

Rufen Sie dann das Objekt ab, das in diesem Szenario die selectValues ​​ist, und setzen Sie es für jede Schleife auf die jquery. Der Wert und der Text der Objekte werden entsprechend verwendet und wie folgt an die Optionsauswahl angehängt.

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

Dies zeigt Text als Optionsliste an, wenn die Dropdown-Liste ausgewählt ist und sobald ein Text ausgewählt ist, wird der Wert des ausgewählten Textes verwendet.

Z.B.

"1": "Test 1", "2": "Test 2",

Dropdown-Liste,

Anzeigename: Test 1 -> Wert ist 1 Anzeigename: Test 2 -> Wert ist 2


Bitte beschreiben Sie ein wenig über die Lösung.
Vinay Prajapati

2

Um die Leistung zu verbessern, ist es besser, die Optionsliste separat zu erstellen und an die Auswahl der ID anzuhängen.

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/

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.