jQuery: práticas recomendadas para preencher o menu suspenso?


269

O exemplo que vejo postado o tempo todo parece subótimo, porque envolve concatenar seqüências de caracteres, o que parece não ser o jQuery. Geralmente é assim:

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

Existe uma maneira melhor?

Respostas:


448

Andreas Grech estava bem perto ... na verdade this(observe a referência ao thisinvés do item no loop):

var $dropdown = $("#dropdown");
$.each(result, function() {
    $dropdown.append($("<option />").val(this.ImageFolderID).text(this.Name));
});

5
A história antiga aqui eu sei, mas para os googlers como eu, que acabaram de tropeçar nisso agora, não seria ainda mais rápido se você clonasse um <option/>elemento em vez de criar cada um?
virador

2
Acho que não ... de qualquer forma, isso vai instanciar um novo item.
quillbreaker

9
Agradável! Embora eu ache que o exemplo possa ser mais claro se o elemento tiver sido nomeado "#dropdown" ou mais, pois reflete melhor o elemento pai real das opções.
Anders

4
Eu acho que a construção de todas as opções na memória (com uma variável de cadeia) em primeiro lugar e, em seguida, anexar esta cadeia para selecionar controle pai deve ser mais eficiente, pois isso fará com que apenas uma vez layout de página
Wint

1
Desculpe se receber notificações e não ver nada. Eu apaguei meus comentários anteriores. Porque eu entendi a resposta mais depois de ler meus próprios comentários :)
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));
    });
});

O que estou fazendo acima é criar um novo <option>elemento e adicioná-lo à optionslista (supondo que optionsseja o ID de um elemento suspenso.

PS Meu javascript está um pouco enferrujado, portanto a sintaxe pode não ser perfeita


1
Isso é bem próximo e me colocou na direção certa. Veja minha resposta abaixo.
9134 Jeff Putz

Doce! realmente útil, eu fui preenchendo meus menus suspensos por um longo tempo, e ele sempre parecia não profissional
Kyle

41

Claro - crie optionsuma série de strings e use, em .join('')vez de +=todas as vezes, o loop. Leve aumento no desempenho ao lidar com um grande número de opções ...

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

Sim. Eu ainda estou trabalhando com cordas o tempo todo. Acredite ou não, essa é a maneira mais rápida de criar um fragmento DOM ... Agora, se você tiver apenas algumas opções, isso realmente não importa - use a técnica que Dreas demonstra se você gosta do estilo. Mas lembre-se de que você está invocando os i*2tempos internos do analisador de HTML do navegador , em vez de apenas uma vez, e modificando o DOM toda vez através do loop ... com um número suficiente de opções. você acabará pagando por isso, principalmente em navegadores mais antigos.

Nota: Como o juiz aponta, isso vai desmoronar se ImageFolderIDe Namenão são codificados corretamente ...


1
Você deve codificar result[i].ImageFolderIDe result[i].Namecomo html-attribute-value e html-text respectivamente. Eu não assumiria que eles vêm do servidor pré-codificado, pois eu assumiria que o servidor retorna json, não bastardized json.
Yfeldblum 02/05/2009

@ Justice: você está certo, mas desde que o exemplo de Jeff o omitiu, eu também. Irá adicionar uma nota, obrigado.
214 Shog9

1
Votei na resposta que @Ricibald deu porque, estranhamente, com base neste teste que me deparei, a concatenação é mais rápida do que joinem praticamente todos os navegadores.
Weir

24

Ou talvez:

var options = $("#options");
$.each(data, function() {
    options.append(new Option(this.text, this.value));
});

6
var myOptions = {val1: 'texto1', val2: 'texto2'}; $ .each (myOptions, função (val, texto) {$ ('# mySelect'). append (nova opção (texto, val));});
O Demz

19

A maneira mais rápida é 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 acordo com este link, é o caminho mais rápido, porque você agrupa tudo em um único elemento ao fazer qualquer tipo de inserção DOM.


porém com replaceWith substituir a escolha em dom um perder os eventos já ligados ao seleccionar eu acho que seria melhor com options.html (optionsValue), se você quiser preservar eventos
Geomorillo

12

Eu achei que isso estava funcionando no site jquery

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

5

Eu li que o uso de fragmentos de documentos é de alto desempenho, pois evita o refluxo da página a cada inserção do elemento DOM, também é bem suportado por todos os navegadores (até o IE 6).

var fragment = document.createDocumentFragment();

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

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

Li pela primeira vez sobre isso no curso de práticas recomendadas de JavaScript da CodeSchool .

Aqui está uma comparação de diferentes abordagens , graças ao autor.


Este é definitivamente o caminho mais rápido. Ainda melhor - ignore o jQuery com tudo isso junto:result.forEach(function(el){var option=document.createElement('option').option.textContent=el.name;option.value=el.ImageFolderID);fragment.appendChild(el);
dgo 14/01/19

5

Outra abordagem com o 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

Eu uso o plugin jquery selectboxes . Transforma o seu exemplo em:

$('#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 ajude. Eu costumo usar funções, em vez disso, escrevo todo o código sempre.

    $("#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

aqui está um exemplo que eu fiz na mudança eu recebo filhos do primeiro select no segundo select

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

Eu tenho usado jQuery e chamando uma função para preencher drop downs.

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

Abaixo está a maneira Jquery de preencher uma lista suspensa cujo ID é "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"));
     }
});
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.