jQuery: ¿Mejor práctica para completar el menú desplegable?

269

El ejemplo que veo publicado todo el tiempo parece subóptimo, porque involucra cadenas de concatenación, lo que parece no ser jQuery. Suele verse así:

$.getJSON("/Admin/GetFolderList/", function(result) {
    for (var i = 0; i < result.length; i++) {
        options += '<option value="' + result[i].ImageFolderID + '">' + result[i].Name + '</option>';
    }
});

¿Hay una mejor manera?

Jeff Putz
fuente

Respuestas:

448

Andreas Grech estaba bastante cerca ... en realidad this(tenga en cuenta la referencia en thislugar del elemento en el bucle):

var $dropdown = $("#dropdown");
$.each(result, function() {
    $dropdown.append($("<option />").val(this.ImageFolderID).text(this.Name));
});
Jeff Putz
fuente
55
La historia antigua aquí lo sé, pero para los googlers como yo que acaban de tropezar con esto ahora, ¿no sería aún más rápido si clonaras un <option/>elemento en lugar de crear cada uno?
tedders
2
No lo creo ... de cualquier manera va a instanciar un nuevo elemento.
Quillbreaker
9
¡Agradable! Aunque creo que el ejemplo podría ser más claro si el elemento se llamó "#dropdown" más o menos, ya que refleja mejor el elemento principal real de las opciones.
Anders
44
Creo que construir todas las opciones en la memoria (con una variable de cadena) primero y luego agregar esta cadena al control de selección principal debería ser más eficiente, porque esto causará solo una vez el diseño de la página
Wint
1
Lo siento si recibes notificaciones y no veo nada. Eliminé mis comentarios anteriores. Porque entendí la respuesta más después de leer mis comentarios :)
ivange
71
$.getJSON("/Admin/GetFolderList/", function(result) {
    var options = $("#options");
    //don't forget error handling!
    $.each(result, function(item) {
        options.append($("<option />").val(item.ImageFolderID).text(item.Name));
    });
});

Lo que estoy haciendo arriba es crear un nuevo <option>elemento y agregarlo a la optionslista (suponiendo que optionssea ​​la ID de un elemento desplegable.

PD: mi javascript está un poco oxidado, por lo que la sintaxis puede no ser perfecta

Andreas Grech
fuente
1
Eso está bastante cerca, y me llevó en la dirección correcta. Vea mi respuesta a continuación.
Jeff Putz
¡Dulce! realmente útil, he estado poblando mis menús desplegables durante mucho tiempo, y siempre no parecía profesional
Kyle
41

Claro: haga optionsuna serie de cadenas y utilícelas en .join('')lugar de hacerlo +=cada vez por el ciclo. Ligero aumento de rendimiento cuando se trata con un gran número de opciones ...

var options = [];
$.getJSON("/Admin/GetFolderList/", function(result) {
    for (var i = 0; i < result.length; i++) {
        options.push('<option value="',
          result[i].ImageFolderID, '">',
          result[i].Name, '</option>');
    }
    $("#theSelect").html(options.join(''));
});

Si. Todavía estoy trabajando con cuerdas todo el tiempo. Lo creas o no, esa es la forma más rápida de construir un fragmento DOM ... Ahora, si solo tienes unas pocas opciones, realmente no importará: usa la técnica que Dreas demuestra si te gusta el estilo. Pero tenga en cuenta que está invocando los i*2tiempos del analizador HTML interno del navegador , en lugar de solo una vez, y modificando el DOM cada vez a través del ciclo ... con una cantidad suficiente de opciones. terminarás pagándolo, especialmente en navegadores antiguos.

Nota: Como el juez señala, esto se vendrá abajo si ImageFolderIDy Nameno están codificados adecuadamente ...

Shog9
fuente
1
Debe codificar result[i].ImageFolderIDy result[i].Namecomo html-attribute-value y html-text respectivamente. No asumiría que provienen del servidor precodificado, ya que supondría que el servidor devuelve json, no jtard bastardo.
yfeldblum
@ Justicia: tienes razón, pero como el ejemplo de Jeff lo omitió, yo también lo hice. Sin embargo, agregaré una nota, gracias.
Shog9
1
Voté por la respuesta que dio @Ricibald porque, curiosamente, según esta prueba que encontré, resulta que la concatenación es más rápida que joinen prácticamente todos los navegadores.
weir
24

O tal vez:

var options = $("#options");
$.each(data, function() {
    options.append(new Option(this.text, this.value));
});
xinthink
fuente
66
var myOptions = {val1: 'texto1', val2: 'texto2'}; $ .each (myOptions, function (val, text) {$ ('# mySelect'). append (nueva Opción (text, val));});
The Demz
19

La forma más rápida es esta:

 $.getJSON("/Admin/GetFolderList/", function(result) {
        var optionsValues = '<select>';
        $.each(result, function(item) {
            optionsValues += '<option value="' + item.ImageFolderID + '">' + item.Name + '</option>';
        });
        optionsValues += '</select>';
        var options = $('#options');
        options.replaceWith(optionsValues);
    });

De acuerdo con este enlace, es la forma más rápida porque envuelve todo en un solo elemento al hacer cualquier tipo de inserción DOM.

Ricibald
fuente
sin embargo, con replaceWith reemplaza select in dom y pierde los eventos ya adjuntos a select, creo que sería mejor con options.html (optionsValue) si desea preservar eventos
Geomorillo
12

Encontré que esto funciona desde el sitio jquery

$.getJSON( "/Admin/GetFolderList/", function( data ) {
  var options = $("#dropdownID");
  $.each( data, function(key, val) {
    options.append(new Option(key, val));
  });
});
binshi
fuente
5

He leído que el uso de fragmentos de documentos es eficaz porque evita el reflujo de página en cada inserción de elemento DOM, también es compatible con todos los navegadores (incluso IE 6).

var fragment = document.createDocumentFragment();

$.each(result, function() {
  fragment.appendChild($("<option />").val(this.ImageFolderID).text(this.Name)[0]);
});

$("#options").append(fragment);

Leí por primera vez sobre esto en el curso de prácticas recomendadas de JavaScript de CodeSchool .

Aquí hay una comparación de diferentes enfoques , gracias al autor.

Dapeng Li
fuente
Este es definitivamente el camino rápido. Aún mejor: omita jQuery con todo esto:result.forEach(function(el){var option=document.createElement('option').option.textContent=el.name;option.value=el.ImageFolderID);fragment.appendChild(el);
dgo
5

Otro enfoque con ES6

fetch('https://restcountries.eu/rest/v1/all')
  .then((response) => {
    return response.json()
  })
  .then((countries) => {
    var options = document.getElementById('someSelect');
    countries.forEach((country) => {
      options.appendChild(new Option(country.name, country.name));
    });
  })
Israel Perales
fuente
2

Yo uso el plugin selectboxes jquery. Convierte tu ejemplo en:

$('#idofselect').ajaxAddOption('/Admin/GetFolderList/', {}, false);
Brian Yarger
fuente
2
$.get(str, function(data){ 
            var sary=data.split('|');
            document.getElementById("select1").options.length = 0;
            document.getElementById("select1").options[0] = new Option('Select a State');
            for(i=0;i<sary.length-1;i++){
                document.getElementById("select1").options[i+1] = new Option(sary[i]);
                document.getElementById("select1").options[i+1].value = sary[i];
            }
            });
sunil
fuente
1

Espero que ayude. Usualmente uso funciones en lugar de escribir todo el código cada vez.

    $("#action_selector").change(function () {

        ajaxObj = $.ajax({
            url: 'YourURL',
            type: 'POST', // You can use GET
            data: 'parameter1=value1',
            dataType: "json",
            context: this,                
            success: function (data) {
                json: data              
            },
            error: function (request) {
                $(".return-json").html("Some error!");
            }
        });

        json_obj = $.parseJSON(ajaxObj.responseText);            

        var options = $("#selector");
        options.empty();
        options.append(new Option("-- Select --", 0));
        $.each(ajx_obj, function () {
            options.append(new Option(this.text, this.value));
        });
    });
});
Pablo Rocha Villagra
fuente
1
function generateYears() {
                    $.ajax({
                        type: "GET",
                        url: "getYears.do",
                        data: "",
                        dataType: "json",
                        contentType: "application/json",
                        success: function(msg) {
                            populateYearsToSelectBox(msg);
                        }
                    });
}

function populateYearsToSelectBox(msg) {
  var options = $("#selectYear");
$.each(msg.dataCollecton, function(val, text) {
   options.append(
        $('<option></option>').val(text).html(text)
    );
});
}
Dulith De Costa
fuente
1

aquí hay un ejemplo que hice al cambiar obtengo hijos de la primera selección en la segunda selección

jQuery(document).ready(function($) {
$('.your_select').change(function() {
    $.ajaxSetup({
        headers:{'X-CSRF-TOKEN': $("meta[name='csrf-token']").attr('content')}
    });

    $.ajax({
        type:'POST',
        url: 'Link',
        data:{
          'id': $(this).val()
        },
        success:function(r){
          $.each(r, function(res) {
                console.log(r[res].Nom);
                 $('.select_to_populate').append($("<option />").val(r[res].id).text(r[res].Nom));
            });
        },error:function(r) {
          alert('Error');
        }
    });
});

});enter code here

Abdelghafour Ennahid
fuente
0

He estado usando jQuery y llamando a una función para completar los menús desplegables.

function loadDropDowns(name,value)
{
   var ddl = "#Categories";
   $(ddl).append('<option value="' + value + '">' + name + "</option>'");
}
Patricio
fuente
0
function LoadCategories() {
    var data = [];
    var url = '@Url.Action("GetCategories", "InternalTables")';
    $.getJSON(url, null, function (data) {
        data = $.map(data, function (item, a) {
            return "<option value=" + item.Value + ">" + item.Description + "</option>";
        });
        $("#ddlCategory").html('<option value="0">Select</option>');
        $("#ddlCategory").append(data.join(""));
    });
}
Deenathaiyalan Shanmugam
fuente
0

A continuación se muestra la forma de Jquery de llenar una lista desplegable cuyo ID es "FolderListDropDown"

$.getJSON("/Admin/GetFolderList/", function(result) {
    for (var i = 0; i < result.length; i++) {
        var elem = $("<option></option>");
        elem.attr("value", result[i].ImageFolderID);
        elem.text(result[i].Name);
        elem.appendTo($("select#FolderListDropDown"));
     }
});
Hang Yu
fuente