Adicionar ou retirar OPTIONS de um SELECT

Pela falta de tempo resolvi mudar um pouco, criando um série de posts mais curtos, tipo "dicas" e vou iniciar mostrando como manipular elementos SELECT dinamicamente.

O elemento SELECT é problemático com o atributo innerHTML, mas com uma funçãozinha simples podemos matar esse problema. A função apenas insere uma nova OPTION num SELECT usando o método add(), que é nativo do elemento SELECT. A nova opção será colocada no final, como a última OPTION. Embora a implementação do método seja um pouco diferente de um navegador para outro (novidade…), nossa função é crossbrowser. Veja:

function addOption(selec, val, tex) {
var opt = document.createElement('option');
opt.value = val;
opt.text = tex;
  try { selec.add(opt, null); } // NS/FF
  catch(e) { selec.add(opt); } // IE
}

A partir dessa função podemos recriar um SELECT de forma a inserir ou retirar OPTIONS e a lógica é simples. Vamos desmembrar o SELECT, colocando suas OPTIONS num array, modificamos o array e remontamos o SELECT. Partindo dessa lógica, seguem as funções addOptionAt(), que insere uma OPTION em uma determinada posição (não no final) e removeOption(), que dispensa comentários…

function removeOption(selec, ind) {
ind = /^\d+$/.test(ind) ? Number(ind) : false;
  if(typeof ind != 'number') return;
var opts = [];
  for(var i = 0; i < selec.options.length; i++) {
    if(i != ind) opts.push({"val": selec.options[i].value, "tex": selec.options[i].innerHTML});
  }
selec.innerHTML = "";
  for(var i = 0; i < opts.length; i++)
    addOption(selec, opts[i].val, opts[i].tex);
}

function addOptionAt(selec, val, tex, ind) {
ind = /^\d+$/.test(ind) ? Number(ind) : 0;
var opts = [];
  for(var i = 0; i < selec.options.length; i++) {
    if(i == ind) opts.push({"val": val, "tex": tex});
  opts.push({"val": selec.options[i].value, "tex": selec.options[i].innerHTML});
  }
selec.innerHTML = ""; // isso é bem discutível... (veja abeixo)
  for(var i = 0; i < opts.length; i++)
    addOption(selec, opts[i].val, opts[i].tex);
}

Antes de recolocar as OPTIONS no SELECT, é preciso "esvaziá-lo", mas o método que utilizei realmente não é o mais indicado... você deve estar pensando: "pô, esse cara começa dizendo que os selects tem problemas com o innerHTML, aí vai e usa aquilo que condenou...". E é isso aí, mas porque funciona - comprovado de forma empírica - mas não é seguro. Veja outras alternativas para limpar um SELECT.

//isso
  for(var i = 0; i < selec.options.length; i++) selec.options[i] = null;
// ou isso 
  while(selec.options[0]) selec.remove(0); 

O parâmetro selec, presente em todas as funções, espera um elemento SELECT como objeto, mas poderíamos acrescentar uma linha para poder enviar o objeto ou apenas o ID - o que tornaria nossa função um pouco mais prática. Veja:

function addOption(selec, val, tex) {
selec = typeof(selec) == "string" ? document.getElementById(selec) : selec;
var opt = document.createElement('option');
opt.value = val;
opt.text = tex;
  try { selec.add(opt, null); } // NS/FF
  catch(e) { selec.add(opt); } // IE
}

Os outros parâmetros estão claros, eu acho. val é o atributo VALUE, tex é o texto visível da OPTION e ind é o índice da OPTION que queremos adicionar/retirar do array selec.options.

É isso aí. E spero que seja útil.

4 ideias sobre “Adicionar ou retirar OPTIONS de um SELECT

  1. Pingback: Pensamento Web » Uma classe em JS para manipular elementos SELECT

  2. Amigo, muito boas suas dicas!

    Só fazendo uma correção, esse código
    for(var i = 0; i < selec.options.length; i++) selec.options[i] = null;

    tem um errinho, o correto seria
    for(var i = 0; i < selec.options.length; ) selec.options[i] = null;

    TEM QUE TIRAR O i++

    Motivo: No primeiro loop, vc remove o elemento zero, e ao fazer isso todos os outros elementos “sobem” no select. Se vc fizer i++ e pegar o elemento 1, vc vai apagar o terceiro elemento no segundo loop, não o segundo.

    Como ao tirar o i++ vc sempre pega o elemento 0, assim vc vai removendo os options um a um, sempre removendo o primeiro elemento, até que o length seja 0.

    Vlw!!

    Os outros códigos eu não olhei, pq eu só precisei desse.

  3. bruno valeu pela dica mesmo copiando os exemplos do cara nao deu certo
    ai vi esta linha (while(selec.options[0]) selec.remove(0);) e pensei ai so remove o primeiro mas quandovc falou que removendoo 0 os outros sobem tudo fez sentido vlw ae

Deixe um Comentário

O seu endereço de email não será publicado Campos obrigatórios são marcados *

*

Você pode usar estas tags e atributos de HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>