Qual è il modo migliore per aggiungere opzioni a una selezione come oggetto JavaScript con jQuery?


1380

Qual è il metodo migliore per aggiungere opzioni a <select>da un oggetto JavaScript usando jQuery?

Sto cercando qualcosa che non ho bisogno di un plugin da fare, ma sarei anche interessato ai plugin che sono là fuori.

Questo è quello che ho fatto:

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

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

Una soluzione pulita / semplice:

Questa è una versione pulita e semplificata di matdumsa :

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

Modifiche da matdumsa: (1) ha rimosso il tag di chiusura per l'opzione all'interno di append () e (2) ha spostato le proprietà / attributi in una mappa come secondo parametro di append ().


4
forse di aiuto: texotela.co.uk/code/jquery/select (mi è stato di aiuto dopo
essermi

2
La versione pulita sopra elencata funziona solo in Jquery 1.4+. Per le versioni precedenti usa quella nella risposta di
matdumsa

{valore: chiave} dovrebbe essere {"valore": chiave} come si vede nella risposta di matdumsa.
Nick P,

Non ci credo, dato che valueè una stringa (e hard coded) non ha bisogno di essere quotata.
Darryl Hein,

1
Il titolo dovrebbe essere invece "Qual è il modo migliore per aggiungere opzioni a una selezione da un oggetto JSON con jQuery?
Dr Fred

Risposte:


1384

Come le altre risposte, in modo jQuery:

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

99
Prima di tutto assegnerei $("#mySelect")a un var, altrimenti chiamare $("#mySelect")ogni volta all'interno del ciclo è molto dispendioso, così come l'aggiornamento del DOM. Vedi i punti 3 e 6 su artzstudio.com/2009/04/jquery-performance-rules/…
Patrick,

7
bene, potresti semplicemente fare var mySelect = $("#mySelect") outside of the ogni ciclo. Sarebbe molto più efficiente. Vedi la risposta di Carl in basso
Patrick,

17
La mia raccomandazione per un migliore stile jQuery: $ ('# mySelect') .append ($ ("<opzione />") .val (chiave) .text (valore));
FAjir,

10
Con la popolarità di questa risposta vale la pena ricordare che dovresti evitare gli aggiornamenti DOM nei loop. jsperf.com/jquery-append-array-vs-string
jthomas

6
La risposta è stata tanto fuorviante a causa del intendation sbagliato ... attre textsono in realtà i metodi della $('<option/>')-oggetto
phil294

268
var output = [];

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

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

In questo modo "tocchi il DOM" solo una volta.

Non sono sicuro che l'ultima riga possa essere convertita in $ ('# mySelect'). Html (output.join ('')) perché non conosco gli interni di jQuery (forse fa un po 'di analisi in html () metodo)


20
Il metodo è ovviamente il più veloce della risposta "corretta" di cui sopra, poiché utilizza anche meno jQuery.
Teej,

4
la riga "$ ('# mySelect'). get (0) .innerHTML = output.join ('');" funziona in Chrome e FF3.x ma non in IE7 per quanto posso dire
blu

19
Questo si interrompe se keycontiene alcune virgolette o >, <al suo interno.
Nickf

3
E, se ho due opzioni che non voglio perdere. Come posso aggiungere questi nuovi valori di opzioni a quelli esistenti?
VansFannel,

6
Un piccolo miglioramento è quello di concatenare utilizzando il join anziché il segno più, in questo modo: output.push ('<option value = "', key, '">', value, '</option>');
MM.

202

Questo è leggermente più veloce e più pulito.

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
Perfetto. Per aggiungerlo, è possibile aggiungere ulteriori attributi per la selezione. $ .each (selectValues, function (id, value, text) {$ ('# mySelect'). append ($ ("<option />", {id: id value: value, text: text}));} );
Idok

45
Pensa che sarà una buona idea memorizzare nella cache `$ ('# mySelect')`, in modo da cercare una sola volta prima del ciclo. Attualmente sta cercando nel DOM l'elemento per ogni singola opzione.
Sushanth -

@ Sushanth-- quanto è grande un colpo di performance se il set è piccolo?
ckarbass,

3
@ckarbass - dipende da quanto è grande il tuo DOM. Sforzo potenzialmente grande e molto piccolo per assegnarlo a una variabile, considerevolmente meno che scrivere un commento in SO!
Nick H247,

97

jQuery

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

Vanilla JavaScript

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

4
Mai sentito parlare Optiondell'oggetto prima. È integrato in tutti i browser?
Darryl Hein,

2
Ho provato ad usare new Option, ma ho scoperto che non funzionava in IE6 e 7. Non ho un motivo, ma molte delle opzioni jQuery complete funzionavano.
Darryl Hein,

Bel modo di aggiungere anche la selezione. new Option('display', value, true)
Boatcoder

@ Mark0978 in realtà è new Option('display', value, true, true)( javascriptkit.com/jsref/select.shtml )
Carl Hörberg

38

Se non devi supportare vecchie versioni di IE, usare il Optioncostruttore è chiaramente la strada da percorrere, una soluzione leggibile ed efficiente :

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

È equivalente in funzionalità a, ma più pulito di:

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

31

Sembra più bello, offre leggibilità, ma è più lento di altri metodi.

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

Se vuoi la velocità, il modo più veloce (testato!) È questo, usando l'array, non la concatenazione di stringhe e usando solo una chiamata di accodamento.

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

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

Questo non significa che il modo "più veloce" sarebbe quello di inserire anche le varie parti di stringa come singoli elementi dell'array, invece di concatenare quelle costituenti di ogni opzione prima di inserirle nell'array, dal momento che verranno comunque unite come una alla fine?
Bitoolean,

22

Un perfezionamento della risposta di @ joshperry più vecchi :

Sembra che .append normale funzioni anche come previsto,

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

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

o più corto,

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

potresti utilizzare in alternativa $.weakmapper consentireGC
Chef_Code

2
Punti bonus per l'eleganza: usare appropriatamente il map()costrutto, combinato con la proprietà di append()aggiungere correttamente una serie di oggetti!
Jochem Schulenklopper,

@joshperry Sono un po 'deluso perché mi aspettavo correzioni / aggiornamenti tecnici.
Сухой27,

20

Tutte queste risposte sembrano inutilmente complicate. Tutto ciò che serve è:

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

Questo è completamente compatibile con più browser.


Dovrebbe essere new Option(value, key);? L' ordine dei parametri è Opzioni (text_visible_part, value_behind_the_scenes).
Bob Stein,

L'array push non è compatibile con più browser? Quindi, questo non è inutilmente complicato, quando il push dell'array è più leggibile?
Bitoolean,

18

Non dimenticate ... Sto usando jQuery Mobile 1.0b2 con PhoneGap 1.0.0 su un telefono Android 2.2 (Cyanogen 7.0.1) (T-Mobile G2) e non riesco a far funzionare il metodo .append (). Ho dovuto usare .html () come segue:

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

Ho fatto alcuni test e questo, credo, fa il lavoro più velocemente. : P


1
.each è notoriamente lento rispetto ad altri modi per ottenere lo stesso risultato. Questo è quello che stavo pensando e consiglierei questo approccio.
Allen Tellez,

È un peccato che il 90% delle varianti qui usi $ .each (). Un ciclo for () può darti molto più controllo e vantaggi in termini di prestazioni, anche se è meno compatto.
HoldOffHunger,

15

Esiste un approccio che utilizza l'approccio Microsoft Templating attualmente in fase di proposta per l'inclusione nel core jQuery. C'è più potere nell'uso del modello, quindi per lo scenario più semplice potrebbe non essere l'opzione migliore. Per ulteriori dettagli, consultare il post di Scott Gu che illustra le funzionalità.

Per prima cosa includi il file js di template, disponibile da github .

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

Successivamente imposta un modello

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

Quindi con i tuoi dati chiama il metodo .render ()

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

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

Ho bloggato questo approccio in modo più dettagliato.


12

Ho fatto qualcosa del genere, caricando un oggetto a discesa tramite Ajax . Anche la risposta sopra è accettabile, ma è sempre bene avere il minor numero di modifiche DOM possibile per prestazioni migliori.

Quindi, piuttosto che aggiungere ogni elemento all'interno di un ciclo, è meglio raccogliere gli elementi all'interno di un ciclo e aggiungerlo una volta completato.

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

Aggiungilo,

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

o anche meglio

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

$ ( '# select_id') HTML (voci).; ha funzionato esattamente come volevo. usando append continua ad aggiungere gli articoli in tutti gli eventi onchange. Grazie mille.
Dipanwita Das,

10

Il modo semplice è:

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

Ho già creato il mio elenco di opzioni, quindi compilare il campo di selezione è stato facile come dice Willard.
Loony2nz,

10

La maggior parte delle altre risposte utilizza la eachfunzione per scorrere su selectValues. Ciò richiede che append sia richiamato per ogni elemento e un riflusso viene attivato quando ciascuno viene aggiunto singolarmente.

L'aggiornamento di questa risposta a un metodo funzionale più idiomatico (usando il moderno JS) può essere formato per chiamare appenduna sola volta, con una matrice di optionelementi creati usando map e un Optioncostruttore di elementi.

L'uso di un Optionelemento DOM dovrebbe ridurre l'overhead delle chiamate di funzione poiché optionnon è necessario aggiornare l' elemento dopo la creazione e non è necessario eseguire la logica di analisi di jQuery.

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

Questo può essere ulteriormente semplificato se si crea una funzione di utilità di fabbrica che ripristinerà un oggetto opzione:

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

Quindi questo può essere fornito direttamente a map:

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

Formulazione precedente

Poiché appendconsente anche il passaggio di valori come numero variabile di argomenti, è possibile precreare l'elenco di optionelementi mappa e accodarli come argomenti in una singola chiamata utilizzando apply.

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

Sembra che nelle versioni successive di jQuery, appendaccetti anche un argomento array e questo può essere in qualche modo semplificato:

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

Funziona bene con jQuery 1.4.1.

Per l'articolo completo sull'uso degli elenchi dinamici con ASP.NET MVC e visita jQuery:

Elenchi di selezione dinamica con MVC e jQuery


8

C'è un problema di ordinamento con questa soluzione in Chrome (jQuery 1.7.1) (Chrome ordina le proprietà degli oggetti in base al nome / numero?) Quindi per mantenere l'ordine (sì, si tratta di abusare degli oggetti), ho cambiato questo:

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

a questo

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

e quindi $ .each sarà simile a:

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

8

Invece di ripetere lo stesso codice ovunque, suggerirei che è più desiderabile scrivere la tua funzione jQuery come:

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

Quindi per aggiungere un'opzione basta fare quanto segue:

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

Potresti elaborare?
Mo.

7

Puoi semplicemente scorrere il tuo json array con il seguente codice

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


7

Sebbene le risposte precedenti siano tutte risposte valide, potrebbe essere consigliabile aggiungere prima tutte queste a un documentFragmnet, quindi aggiungere quel frammento di documento come elemento dopo ...

Guarda i pensieri di John Resig sull'argomento ...

Qualcosa sulla falsariga di:

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 è più lento di a for ciclo
  2. Ogni volta, una selezione DOM non è la migliore pratica in loop $("#mySelect").append();

Quindi la soluzione migliore è la seguente

Se i dati JSON respsono

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

usalo come

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

6

Ancora un altro modo di farlo:

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

Vedo quello che hai fatto qui ... Hai preso il consiglio di memorizzare nella cache, $('#mySelect')quindi hai refactored la risposta @rocktheroad ... comunque, questa è la soluzione più pratica
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);
}

Questo manipola il DOM solo una volta dopo aver creato una stringa gigante.


puoi ottimizzarlo ulteriormente ed evitare del tutto l'uso di jQuery sostituendolo $("#myselect").empty().append(opts);congetElementById('myselect').innerHtml = opts;
vahanpwns,

6

Questo è quello che ho fatto con gli array bidimensionali: La prima colonna è articolo ho, aggiungo innerHTMLdel <option>. La seconda colonna è record_id i, aggiungere alla valuedel <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();
        }
    }

Sembra buono. Peccato che non stia usando jQuery. Inoltre, ho già avuto problemi con il metodo select.options.add (). Non riesco a ricordare quale browser e il problema esatto, ma ho deciso di allontanarmi da esso e lasciare che jQuery gestisca le differenze.
Darryl Hein,

im un totale noob con PHP e JQuerry, ma il codice sopra funziona in tutti i browser. l'unico problema - non funziona bene su iPhone, ho pubblicato una domanda al riguardo, finora nessuna fortuna :( stackoverflow.com/questions/11364040/…
Salato


5

Ho scoperto che questo è semplice e funziona benissimo.

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

4

Il formato JSON:

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

E il codice jQuery per popolare i valori per il successo di Dropdown su 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

Usando la funzione $ .map (), puoi farlo in un modo più elegante:

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

È un po 'più breve, ma l'unico problema riguarda la fuga dalla val e dai key varar che la risposta accettata fa.
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

Imposta il tuo ID di selezione HTML nella seguente riga di seguito. Qui mySelectviene utilizzato come ID dell'elemento select.

   var options = $("#mySelect");

quindi ottiene l'oggetto che è selectValues ​​in questo scenario e lo imposta su jquery per ciascun ciclo. Utilizzerà il valore e il testo degli oggetti di conseguenza e lo aggiungerà alle selezioni delle opzioni come segue.

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

Questo visualizzerà il testo come elenco di opzioni quando viene selezionato l'elenco a discesa e una volta selezionato un testo verrà utilizzato il valore del testo selezionato.

Per esempio.

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

Cadere in picchiata,

nome visualizzato: test 1 -> il valore è 1 nome visualizzato: test 2 -> il valore è 2


descrivi un po 'la soluzione.
Vinay Prajapati,

2

In realtà, per ottenere prestazioni migliori, è meglio fare un elenco di opzioni separatamente e aggiungere per selezionare 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/

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.