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?

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

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


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


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

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.


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

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.


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

2

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

$('#idofselect').ajaxAddOption('/Admin/GetFolderList/', {}, false);

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

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

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

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


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

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

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"));
     }
});
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.