¿Cuál es la mejor manera de agregar opciones a un select from como un objeto JS con jQuery?


¿Cuál es el mejor método para agregar opciones a un <select> desde un objeto JavaScript usando jQuery?

Estoy buscando algo que no necesito un plugin para hacer, pero yo también estaría interesado en los plugins que están por ahí.

Esto es lo que hice:

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 solución limpia / simple:

Esta es una versión limpia y simplificada de de matdumsa:

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

Cambios de matdumsa: (1) se eliminó la etiqueta de cierre para la opción inside append() y (2) movieron las propiedades/atributos a un mapa como segundo parámetro de append().

Author: Darryl Hein, 2008-10-05

30 answers

Igual que otras respuestas, en forma de jQuery:

$.each(selectValues, function(key, value) {   
     $('#mySelect')
         .append($("<option></option>")
                    .attr("value",key)
                    .text(value)); 
});
 1237
Author: matdumsa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-11 15:24:03
var output = [];

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

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

De esta manera "tocas el DOM" solo una vez.

No estoy seguro de si la última línea se puede convertir en $('#mySelect').html(salida.join ( " )) porque no conozco el funcionamiento interno de jQuery (tal vez hace algo de análisis en el método html() )

 243
Author: gpilotino,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-27 15:34:24

Esto es un poco más rápido y más limpio.

$.each(selectValues, function(key, value) {
    $('#mySelect').append($("<option/>", {
        value: key,
        text: value
    }));
});
 182
Author: rocktheroad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-20 11:26:56

[2]} 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));
}
 81
Author: Carl Hörberg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-13 13:23:32

Usando El complemento Creador de elementos DOM (mi favorito):

$.create('option', {'value': 'val'}, 'myText').appendTo('#mySelect');

Usando el constructor Option (no estoy seguro sobre el soporte del navegador):

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

Usando document.createElement (evitando el trabajo extra analizando HTML con $("<option></option>")):

$('#mySelect').append($(document.createElement("option")).
                        attr("value","val").text("myText"));
 31
Author: Nickolay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-05 15:49:09

Esto se ve mejor, proporciona legibilidad, pero es más lento que otros métodos.

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

Si quieres velocidad, el más rápido (probado!) forma es esto, usando matriz, no concatenación de cadenas, y usando solo una llamada append.

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

$('#selectBox').append(auxArr.join(''));
 26
Author: m1sfit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-02 17:53:03

Todas estas respuestas parecen innecesariamente complicadas. Todo lo que necesitas es:

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

Que es completamente compatible con navegadores cruzados.

 18
Author: Animism,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-05 00:48:09

@ joshperry

Parece que simple .append también funciona como se espera,

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

    return $("<option>").val(k).text(v);
  })
);
 17
Author: Сухой27,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-17 11:29:16

Ser reenviado... Estoy usando jQuery Mobile 1. 0b2 con PhoneGap 1.0.0 en un teléfono Android 2.2 (Cyanogen 7.0.1) (T-Mobile G2) y no pude obtener el .append () método para trabajar en absoluto. Tuve que usar .html() como sigue:

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

$('#selectMenu').html(options);
 14
Author: Jack Holt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-19 07:42:29
 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('');

He hecho algunas pruebas y esto, creo, hace el trabajo más rápido. : P

 14
Author: Thorpe Obazee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-16 05:38:45

Hay un enfoque que utiliza el Microsoft Templating approach que está actualmente bajo propuesta para su inclusión en jQuery core. Hay más poder en el uso de plantillas, por lo que para el escenario más simple puede no ser la mejor opción. Para más detalles vea el post de Scott Gu describiendo las características.

Primero incluya el archivo js de plantillas, disponible en github.

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

Siguiente configuración de una plantilla

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

Luego con sus datos llame al .render() método

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

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

He blogueado este enfoque con más detalle.

 11
Author: Nick Josevski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-07-08 05:00:35

He hecho algo como esto, cargando un elemento desplegable a través de Ajax. La respuesta anterior también es aceptable, pero siempre es bueno tener la menor modificación de DOM como sea posible para un mejor rendimiento.

Así que en lugar de agregar cada elemento dentro de un bucle, es mejor recopilar elementos dentro de un bucle y agregarlos una vez que se haya completado.

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

Añádelo,

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

O aún mejor

$('#select_id').html(items);
 7
Author: Komang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-02 17:59:29

Una especie de compromiso entre las dos respuestas principales, en una "línea única":

$.fn.append.apply($('mySelect'),
    $.map(selectValues, function(val, idx) {
        return $("<option/>")
            .val(val.key)
            .text(val.value);
    })
);

Construye una matriz de elementos Option usando map y luego los agrega todos a Select a la vez usando apply para enviar cada Opción como un argumento separado en la función append.

 6
Author: joshperry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-01 20:22:07

La manera simple es:

$('#SelectId').html("<option value='0'>select</option><option value='1'>Laguna</option>");
 6
Author: willard macay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-17 01:02:37
function populateDropdown(select, data) {   
    select.html('');   
    $.each(data, function(id, option) {   
        select.append($('<option></option>').val(option.value).html(option.name));   
    });          
}   

Funciona bien con jQuery 1.4.1.

Para el artículo completo para el uso de listas dinámicas con ASP.NET Visita MVC y jQuery: http://www.codecapers.com/post/Dynamic-Select-Lists-with-MVC-and-jQuery.aspx

 5
Author: H Sampat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-05 11:56:17

Hay un problema de ordenación con esta solución en Chrome (jQuery 1.7.1) (Chrome ordena las propiedades de los objetos por nombre/número?) Así que para mantener el orden (sí, es objeto abusando), cambié esto:

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

A esto

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

Y luego el $.cada uno se verá como:

$.each(optionValues0, function(order, object) {
  key = object.id;
  value = object.value;
  $('#mySelect').append($('<option>', { value : key }).text(value));
}); 
 4
Author: Michail,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-21 09:27:00

Otra forma de hacerlo:

var options = [];    
$.each(selectValues, function(key, value) {
    options.push($("<option/>", {
        value: key,
        text: value
    }));
});
$('#mySelect').append(options);
 4
Author: DiverseAndRemote.com,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-25 21:59:06
if (data.length != 0) {
    var opts = "";
    for (i in data)
        opts += "<option value='"+data[i][value]+"'>"+data[i][text]+"</option>";

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

Esto manipula el DOM solo una vez después de la primera construcción de una cadena gigante.

 4
Author: Christian Roman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-02 17:16:31

Aunque las respuestas anteriores son todas respuestas válidas, podría ser aconsejable agregar todas estas a una documentFragmnet primero, luego agregar ese fragmento de documento como un elemento después...

Ver Los pensamientos de John Resig sobre el asunto...

Algo parecido a:

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);
 4
Author: Stuart.Sklinar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-27 15:40:49
  1. $.each es más lento que un bucle for
  2. Cada vez, una selección DOM no es la mejor práctica en loop $("#mySelect").append();

Así que la mejor solución es la siguiente

Si los datos JSON resp son

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

Utilícelo como

var option = "";
for (i=0; i<resp.length; i++) {
    option += "<option value='" + resp[i].id + "'>" + resp[i].name + "</option>";
}
$('#mySelect').html(option);
 4
Author: Salim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-27 15:46:54

En lugar de repetir el mismo código en todas partes, sugeriría que es más deseable escribir su propia función jQuery como:

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

Luego para agregar una opción simplemente haga lo siguiente:

$('select').addOption('0', 'None');
 4
Author: Matt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-27 15:48:42

Puede iterar sobre su matriz json con el siguiente código

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

 3
Author: kashif,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-08 19:16:25
 3
Author: lkahtz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-24 16:23:44

Encontré que esto es simple y funciona muy bien.

for (var i = 0; i < array.length; i++) {
    $('#clientsList').append($("<option></option>").text(array[i].ClientName).val(array[i].ID));
};
 2
Author: DW333,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-13 20:44:40

Eso es lo que hice con matrices bidimensionales: La primera columna es el elemento i, agregar a innerHTML de la <option>. La segunda columna es record_id i, añadir a la value de la <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();
        }
    }
    
 2
Author: Salty,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-27 15:39:52

El formato JSON:

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

Y el código jQuery para rellenar los valores en el menú desplegable en Ajax success:

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
}
 2
Author: M_J,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-27 15:50:07

Usando $.función map (), puede hacer esto de una manera más elegante:

$('#mySelect').html( $.map(selectValues, function(val, key){
    return '<option value="' + val + '">'+ key + '</option>';
}).join(''));
 1
Author: Dr Fred,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-27 15:50:39

Combino las dos mejores respuestas en una gran respuesta.

var outputConcatenation = [];

$.each(selectValues, function(i, item) {   
     outputConcatenation.push($("<option></option>").attr("value", item.key).attr("data-customdata", item.customdata).text(item.text).prop("outerHTML"));
});

$("#myselect").html(outputConcatenation.join(''));
 0
Author: Erick Asto Oblitas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-08 03:06:42
$.each(selectValues, function(key, value) {
    $('#mySelect').append($("<option/>", {
        value: key, text: value
    }));
});
 0
Author: Lokesh thakur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-31 06:26:54
<!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>
 0
Author: Satyendra Yadav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-29 16:03:33