Adicionando opções para selecionar com javascript

161

Quero que esse javascript crie opções de 12 a 100 em um select com id = "mainSelect", porque não quero criar todas as tags de opção manualmente. Você pode me dar algumas dicas? obrigado

function selectOptionCreate() {

  var age = 88;
  line = "";
  for (var i = 0; i < 90; i++) {
    line += "<option>";
    line += age + i;
    line += "</option>";
  }

  return line;
}
Jack o Estripador
fonte
14
A votação para reabrir, como o 'duplicado' vinculado, tem apenas respostas baseadas em jQuery, enquanto que essa requer (ou pelo menos implica a exigência de) JavaScript simples.
David diz que restabelece Monica
3
Ótima resposta aqui :mySelect.options[mySelect.options.length] = new Option('Text 1', 'Value1');
ruffin

Respostas:

254

Você pode conseguir isso com um forloop simples :

var min = 12,
    max = 100,
    select = document.getElementById('selectElementId');

for (var i = min; i<=max; i++){
    var opt = document.createElement('option');
    opt.value = i;
    opt.innerHTML = i;
    select.appendChild(opt);
}

Demonstração JS Fiddle .

A comparação JS Perf da resposta da minha e da Sime Vidas foi executada porque achei que a dele parecia um pouco mais compreensível / intuitiva do que a minha e fiquei imaginando como isso se traduziria em implementação. De acordo com o Chromium 14 / Ubuntu 11.04, a mina é um pouco mais rápida, mas é provável que outros navegadores / plataformas tenham resultados diferentes.


Editado em resposta ao comentário do OP:

[Como] aplico isso a mais de um elemento?

function populateSelect(target, min, max){
    if (!target){
        return false;
    }
    else {
        var min = min || 0,
            max = max || min + 100;

        select = document.getElementById(target);

        for (var i = min; i<=max; i++){
            var opt = document.createElement('option');
            opt.value = i;
            opt.innerHTML = i;
            select.appendChild(opt);
        }
    }
}
// calling the function with all three values:
populateSelect('selectElementId',12,100);

// calling the function with only the 'id' ('min' and 'max' are set to defaults):
populateSelect('anotherSelect');

// calling the function with the 'id' and the 'min' (the 'max' is set to default):
populateSelect('moreSelects', 50);

Demonstração JS Fiddle .

E, finalmente (depois de um atraso ...), uma abordagem estendendo o protótipo do HTMLSelectElementpara encadear a populate()função, como método, para o nó DOM:

HTMLSelectElement.prototype.populate = function (opts) {
    var settings = {};

    settings.min = 0;
    settings.max = settings.min + 100;

    for (var userOpt in opts) {
        if (opts.hasOwnProperty(userOpt)) {
            settings[userOpt] = opts[userOpt];
        }
    }

    for (var i = settings.min; i <= settings.max; i++) {
        this.appendChild(new Option(i, i));
    }
};

document.getElementById('selectElementId').populate({
    'min': 12,
    'max': 40
});

Demonstração JS Fiddle .

Referências:

David diz para restabelecer Monica
fonte
@Jack: concordou, e eu usei essa abordagem na última edição :)
David diz para repor Monica
Além disso, estender protótipos de host (embora tentador) é considerado uma má idéia .
RobG 30/03
Eu acho que isso deve ser atualizado para uso em innerTextvez de innerHTMLevitar vulnerabilidades de script entre sites. O que você acha @DavidThomas?
Abhi Beckert 14/03
20

Aqui está:

for ( i = 12; i <= 100; i += 1 ) {
    option = document.createElement( 'option' );
    option.value = option.text = i;
    select.add( option );
}

Demonstração ao vivo: http://jsfiddle.net/mwPb5/


Atualização: como você deseja reutilizar esse código, aqui está a função:

function initDropdownList( id, min, max ) {
    var select, i, option;

    select = document.getElementById( id );
    for ( i = min; i <= max; i += 1 ) {
        option = document.createElement( 'option' );
        option.value = option.text = i;
        select.add( option );
    }
}

Uso:

initDropdownList( 'mainSelect', 12, 100 );

Demonstração ao vivo: http://jsfiddle.net/mwPb5/1/

Šime Vidas
fonte
como faço para aplicar isso a mais de um elemento?
jacktheripper
9

A maneira mais concisa e intuitiva seria:

var selectElement = document.getElementById('ageselect');

for (var age = 12; age <= 100; age++) {
  selectElement.add(new Option(age));
}
Your age: <select id="ageselect"><option value="">Please select</option></select>

Você também pode diferenciar o nome e o valor ou adicionar itens no início da lista com parâmetros adicionais às funções usadas:
Elemento HTMLSelect .add (item [, before]);
nova opção (texto, valor, defaultSelected, selected);

do utilizador
fonte
8

Eu não recomendo fazer manipulações DOM dentro de um loop - que podem ficar caras em grandes conjuntos de dados. Em vez disso, eu faria algo assim:

var elMainSelect = document.getElementById('mainSelect');

function selectOptionsCreate() {
  var frag = document.createDocumentFragment(),
    elOption;
  for (var i=12; i<101; ++i) {
    elOption = frag.appendChild(document.createElement('option'));
    elOption.text = i;
  }
  elMainSelect.appendChild(frag);
}

Você pode ler mais sobre o DocumentFragment no MDN , mas aqui está a essência:

É usado como uma versão leve do Document para armazenar um segmento de uma estrutura de documento composta por nós, como um documento padrão. A principal diferença é que, como o fragmento do documento não faz parte da estrutura real do DOM, as alterações feitas no fragmento não afetam o documento, causam reflow ou incidem em qualquer impacto no desempenho que pode ocorrer quando as alterações são feitas.

thdoan
fonte
4

A única coisa que eu evitaria é realizar operações DOM em um loop para evitar repetições repetidas da página.

var firstSelect = document.getElementById('first select elements id'),
    secondSelect = document.getElementById('second select elements id'),
    optionsHTML = [],
    i = 12;

for (; i < 100; i += 1) {
  optionsHTML.push("<option value=\"Age" + i + "\">Age" + i + "</option>";
}

firstSelect.innerHTML = optionsHTML.join('\n');
secondSelect.innerHTML = optionsHTML.join('\n');

Edit: removeu a função para mostrar como você pode atribuir o html que você criou a outro elemento de seleção - evitando assim o loop desnecessário repetindo a chamada de função.

kinakuta
fonte
como faço para aplicar isso a mais de um elemento?
jacktheripper
Não tenho certeza se eu sigo - você deseja adicionar as mesmas opções a mais de um elemento de seleção?
Kinakuta
Sim, eu quero caixas com as mesmas opções
jacktheripper
Eu considerei isso em uma função que você pode chamar, onde apenas passa o ID do elemento de seleção ao qual deseja anexar as opções.
Kinakuta
2
É para isso que serve o documentFragment. Você pode modificar facilmente a resposta aceita para que as opções sejam anexadas ao documentFragment primeiro, impedindo várias renderizações.
Sam Braslavskiy
1

Quando você cria um novo Optionobjeto, há dois parâmetros a serem passados: o primeiro é o texto que você deseja que apareça na lista e o segundo o valor a ser atribuído à opção.

var myNewOption = new Option("TheText", "TheValue");

Você simplesmente atribui esse Optionobjeto a um elemento vazio da matriz, por exemplo:

document.theForm.theSelectObject.options[0] = myNewOption;
mohan mu
fonte
0

Nenhuma das soluções acima funcionou para mim. Anexar método não deu erro quando tentei, mas não resolveu o meu problema. No final, resolvi meu problema com a propriedade de dados select2. Eu usei json e peguei o array e, em seguida, forneço no elemento select2 initialize. Para mais detalhes, você pode ver minha resposta no post abaixo.

https://stackoverflow.com/a/41297283/4928277

Engin Aydogdu
fonte
0

Muitas vezes você tem uma matriz de registros relacionados, acho fácil e bastante declarativo preencher selectdessa maneira:

selectEl.innerHTML = array.map(c => '<option value="'+c.id+'">'+c.name+'</option>').join('');

Isso substituirá as opções existentes.
Você pode usar selectEl.insertAdjacentHTML('afterbegin', str);para adicioná-los ao topo.
E selectEl.insertAdjacentHTML('beforeend', str);para adicioná-los ao final da lista.

Sintaxe compatível com IE11:

array.map(function (c) { return '<option value="'+c.id+'">'+c.name+'</option>'; }).join('');
do utilizador
fonte