¿Cuál es la mejor manera de agregar opciones a una selección de un objeto JavaScript con jQuery?

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

Estoy buscando algo para lo que no necesito un complemento, pero también me interesarían los complementos que existen.

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 limpia y simplificada versión de matdumsa:

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

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

preguntado Oct 04 '08, 18:10

tal vez de ayuda: texotela.co.uk/code/jquery/select (fue una ayuda para mí después de que me topé con esta pregunta) -

La versión limpia listada arriba solo funciona en Jquery 1.4+. Para versiones anteriores, use el de la respuesta de matdumsa:

{valor: clave} debe ser {"valor": clave} como se ve en la respuesta de matdumsa. -

No lo creo desde value es una cadena (y codificada de forma rígida) que no necesita ser entre comillas. -

En su lugar, el título debería ser "¿Cuál es la mejor manera de agregar opciones a una selección de un objeto JSON con jQuery? -

30 Respuestas

Lo mismo que otras respuestas, de una manera jQuery:

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

Respondido el 01 de junio de 20 a las 15:06

Primero que nada asignaría $("#mySelect") a una var, de lo contrario llamando $("#mySelect") cada vez que se está dentro del bucle es un desperdicio, al igual que actualizar el DOM. Vea los puntos # 3 y # 6 en artzstudio.com/2009/04/jquery-rendimiento-reglas/… - Patrick

bueno, podrías hacer var mySelect = $("#mySelect") outside of the cada` bucle. Eso sería mucho más eficiente. Vea la respuesta de Carl a continuación: Patrick

Mi recomendación para un mejor estilo de jQuery: $ ('# mySelect') .append ($ (" ") .val (clave) .text (valor)); - a11r

Con la popularidad de esta respuesta, vale la pena mencionar que debe evitar las actualizaciones DOM en bucles. jsperf.com/jquery-append-array-vs-cadena - jtomas

esta respuesta fue tan engañosa debido a la intención equivocada ... attr y text son en realidad métodos del $('<option/>')-objeto - phil294

var output = [];

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

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

De esta manera, "toca el DOM" solo una vez.

No estoy seguro de si la última línea se puede convertir en $ ('# mySelect'). Html (output.join ('')) porque no conozco los aspectos internos de jQuery (tal vez haga un análisis en el html () método)

Respondido el 27 de diciembre de 17 a las 15:12

Su método es obviamente el más rápido que la respuesta 'correcta' anterior, ya que también usa menos jQuery. - Teej

la línea "$ ('# mySelect'). get (0) .innerHTML = output.join ('');" funciona en Chrome y FF3.x pero no en IE7 por lo que puedo decir - blu

Esto se rompe si el key tiene algunas citas o >, < en eso. - apodo

Y, si tengo dos opciones que no quiero perder. ¿Cómo puedo agregar estos nuevos valores de opciones a los existentes? - Furgonetas Fannel

Una pequeña mejora es concatenar usando la combinación en lugar del signo más, así: output.push (' ', valor, ' '); - MM.

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

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>

respondido 05 mar '19, 08:03

Perfecto. Para agregarlo, se podrían agregar atributos adicionales para la selección. $ .each (selectValues, function (id, value, text) {$ ('# mySelect'). append ($ (" ", {id: id valor: valor, texto: texto}));}); - idok

Piensa que será una mejor idea almacenar en caché `$ ('# mySelect')`, de modo que solo busque una vez antes del bucle. Actualmente está buscando en el DOM el elemento para cada opción. - Sushanth -

@ Sushanth-- ¿Qué impacto tiene este rendimiento si el set es pequeño? - karbass

@ckarbass: depende de qué tan grande sea tu DOM. Potencialmente grande y muy poco esfuerzo para asignarlo a una variable, ¡considerablemente menos que escribir un comentario en SO! - Nick H247

jQuery

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

JavaScript vainilla

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

contestado el 13 de mayo de 18 a las 14:05

Nunca escuché del Option objeto antes. ¿Está integrado en todos los navegadores? - darryl hein

Intenté usar new Option, pero descubrí que no funcionaba en IE6 y 7. No tengo una razón por la cual, pero muchas de las opciones completas de jQuery funcionaron. - darryl hein

Buena forma de agregar selección también. new Option('display', value, true) - codificador de barco

@ Mark0978 en realidad es new Option('display', value, true, true) (javascriptkit.com/jsref/select.shtml) - carl horberg

@ CarlHörberg que funcionó muy bien para mí, ¡muy simple! ¡Gracias! - jose bullough

Si no tiene que admitir versiones antiguas de IE, utilice el Option constructor es claramente el camino a seguir, una solución legible y eficiente:

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

Es equivalente en funcionalidad a, pero más limpio que:

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

Respondido el 11 de Septiembre de 19 a las 14: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 desea velocidad, la forma más rápida (¡probada!) Es esta, usando matriz, no concatenación de cadenas, y usando solo una llamada de adición.

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

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

contestado el 02 de mayo de 11 a las 18:05

¿No significa esto que la forma "más rápida" sería insertando las diversas partes de la cadena como elementos individuales de la matriz también, en lugar de concatenar las que constituyen cada opción antes de insertarlas en la matriz, ya que todas se unirán como una al final de todos modos? - bitooleano

Un refinamiento de lo viejo La respuesta de @joshperry:

Parece tan simple .adjuntar también funciona como se esperaba,

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

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

o más corto,

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

Respondido el 23 de diciembre de 19 a las 07:12

¿Podrías usar alternativamente? $.weakmap para permitir GC - Chef_Código

Puntos extra por elegancia: usar apropiadamente el map() construir, combinado con la propiedad de append() para agregar una matriz de objetos correctamente! - Jochem Schulenklopper

@joshperry Estoy un poco decepcionado porque esperaba una corrección / actualización técnica. - mpapec

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

Eso es completamente compatible con todos los navegadores.

respondido 05 nov., 15:00

Deberia ser new Option(value, key); ? los orden de los parámetros es Opciones (text_visible_part, value_behind_the_scenes). - bob stein

¿No es Array push compatible con todos los navegadores? Entonces, ¿no es esto innecesariamente complicado, cuando Array push es más legible? - bitooleano

Tenga cuidado ... 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 hacer que el método .append () funcione 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);

respondido 19 nov., 16:07

 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 creo que esta es la que hace el trabajo más rápido. :PAG

Respondido 16 Jul 17, 06:07

.cada uno es notoriamente lento en comparación con otras formas de lograr el mismo resultado. Esto es lo que estaba pensando y recomendaría este enfoque. - Allen Téllez

Es lamentable que el 90% de las variaciones aquí usen $ .each (). Un bucle for () puede brindarle mucho más control y beneficios de rendimiento, incluso si es menos compacto. - Retener el hambre

Hay un enfoque que utiliza el Enfoque de plantilla de Microsoft que está actualmente bajo propuesta para su inclusión en el núcleo de jQuery. Hay más poder en el uso de plantillas, por lo que para el escenario más simple puede que no sea la mejor opción. Para obtener más detalles, consulte la publicación de Scott Gu que describe las características.

Primero incluya el archivo js de plantilla, disponible en gitHub.

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

A continuación, configure una plantilla

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

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

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

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

He escribió en su blog este enfoque con más detalle.

Respondido 08 Jul 10, 06:07

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 posible para un mejor rendimiento.

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

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

Anexarlo,

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

o mejor

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

contestado el 02 de mayo de 11 a las 18:05

$ ('# select_id'). html (elementos); Funcionó exactamente como quería. Al usar agregar, sigue agregando los elementos en todos los eventos de cambio. Muchas gracias. - Dipanwita Das

La forma sencilla es:

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

Respondido 17 Jul 17, 02:07

Ya he creado mi lista de opciones, por lo que completar el campo de selección fue tan fácil como dice Willard. - Loony2nz

La mayoría de las otras respuestas usan el each función para iterar sobre el selectValues. Esto requiere que se llame a append para cada elemento y se active un reflujo cuando cada uno se agrega individualmente.

La actualización de esta respuesta a un método funcional más idiomático (utilizando JS moderno) se puede formar para llamar append solo una vez, con una variedad de option elementos creados usando mapa y una Option constructor de elementos.

Usando año Option El elemento DOM debería reducir la sobrecarga de llamadas a funciones ya que el option El elemento no necesita actualizarse después de la creación y la lógica de análisis de jQuery no necesita ejecutarse.

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

Esto se puede simplificar aún más si crea una función de utilidad de fábrica que creará un nuevo objeto de opción:

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

Entonces esto se puede proporcionar directamente a map:

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

Formulación previa

Porque append también permite pasar valores como un número variable de argumentos, podemos crear previamente la lista de option elementos mapa y anexarlos como argumentos en una sola llamada usando apply.

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

Parece que en versiones posteriores de jQuery, append también acepta un argumento de matriz y esto se puede simplificar un poco:

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

Respondido el 22 de diciembre de 19 a las 20:12

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 obtener un artículo completo sobre el uso de listas dinámicas con ASP.NET MVC y jQuery, visite:

Listas de selección dinámica con MVC y jQuery

Respondido el 19 de enero de 20 a las 07:01

Hay un problema de clasificación con esta solución en Chrome (jQuery 1.7.1) (¿Chrome clasifica las propiedades del objeto por nombre / número?) Entonces, para mantener el orden (sí, es un abuso de objetos), cambié esto:

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

a este

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

y luego el $ .each se verá así:

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

Respondido el 21 de Septiembre de 12 a las 10:09

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

Respondido el 27 de diciembre de 17 a las 15:12

¿Podría darme más detalles? - Misuri

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

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

Respondido el 08 de Septiembre de 10 a las 20:09

  1. $.each es más lento que un for loops
  2. Cada vez, una selección de DOM no es la mejor práctica en bucle $("#mySelect").append();

Entonces la mejor solución es la siguiente

Si los datos JSON resp is

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

usarlo como

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

Respondido el 27 de diciembre de 17 a las 15:12

Otra forma más de hacerlo:

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

Respondido 25 Abr '13, 22:04

Veo lo que hiciste aquí ... Seguiste el consejo de guardar en caché $('#mySelect') luego refactorizó la respuesta de @rocktheroad ... lo que sea, esta es la solución más práctica: Chef_Código

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 construir por primera vez una cadena gigante.

Respondido 02 Oct 13, 18:10

puede optimizar esto aún más y evitar el uso de jQuery por completo reemplazando $("#myselect").empty().append(opts); con getElementById('myselect').innerHtml = opts; - vahanpwns

Eso es lo que hice con matrices bidimensionales: la primera columna es el elemento i, agregar a innerHTML de los <option>. La segunda columna es record_id i, agregue al value de los <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();
        }
    }
    

Respondido el 27 de diciembre de 17 a las 15:12

Se ve bien. Lástima que no esté usando jQuery. Además, he tenido problemas antes con el método select.options.add (). No puedo recordar qué navegador y el problema exacto, pero decidí dejar de lado y dejar que jQuery se ocupara de las diferencias. - darryl hein

Soy un novato total con PHP y JQuerry, pero el código anterior funciona en todos los navegadores. el único problema: no funciona bien en iPhone, publiqué una pregunta al respecto, no tuve suerte hasta ahora :( stackoverflow.com/questions/11364040/… - LazyZebra

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

Vea Pensamientos de John Resig al respecto...

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

Respondido el 27 de diciembre de 17 a las 15:12

Se puede encontrar un complemento de jQuery aquí: Autocompletar cuadros de selección con jQuery y AJAX.

Respondido el 19 de enero de 20 a las 08:01

Descubrí 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));
};

respondido 13 nov., 12:20

El formato JSON:

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

Y el código jQuery para completar los valores del menú desplegable en el éxito de 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
}

Respondido el 27 de diciembre de 17 a las 15:12

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

Respondido el 27 de diciembre de 17 a las 15:12

Eso es un poco más corto, pero el único problema es lidiar con el escape de las variables val y clave, lo que hace la respuesta aceptada. - darryl hein

<!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>

respondido 29 mar '18, 17:03

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

Respondido 08 Oct 15, 04:10

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

Respondido 31 Oct 17, 06:10

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.