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?

Jeff Putz
fonte

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));
});
Jeff Putz
fonte
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

Andreas Grech
fonte
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 ...

Shog9
fonte
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));
});
xinthink
fonte
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.

Ricibald
fonte
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));
  });
});
binshi
fonte
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.

Dapeng Li
fonte
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));
    });
  })
Israel Perales
fonte
2

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

$('#idofselect').ajaxAddOption('/Admin/GetFolderList/', {}, false);
Brian Yarger
fonte
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];
            }
            });
tomar sol
fonte
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));
        });
    });
});
Pablo Rocha Villagra
fonte
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
fonte
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

Abdelghafour Ennahid
fonte
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>'");
}
Patrick
fonte
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
fonte
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"));
     }
});
Hang Yu
fonte