HTML select: listas suspensas, seleção múltipla e valores enviados

HTML <select> é um controle de formulário para escolher entre opções definidas por option. Por padrão permite uma única escolha; multiple permite várias. O atributo name de select identifica o campo enviado, e o atributo value da opção selecionada determina seu valor.

Distinguir nomes de campos, rótulos visíveis e valores enviados

Associe o for de um elemento label ao id de um elemento select para associar uma descrição ao controle. O id identifica o elemento dentro do documento, enquanto name se torna a chave de dados enviada. O texto da opção visível pode diferir de value: escolher Desenvolvimento web pode enviar web. Se você omitir value, o texto da opção é usado como seu valor.

Em um controle comum de seleção única, omitir selected geralmente faz com que a primeira opção disponível seja a seleção inicial. Para exigir uma escolha explícita, dê à primeira opção um value vazio e adicione required, como abaixo. Uma instrução visível não satisfaz a seleção obrigatória quando seu valor está vazio.

Exemplo completo: seleções obrigatórias e múltiplas

Salve o código como select-demo.html e abra-o em um navegador. O JavaScript impede o envio e exibe os dados atuais do formulário na página. Este exercício não envia dados para um servidor real ou site externo.

<!doctype html>
<html lang="pt">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Verificar os valores de select</title>
  <style>
    body { max-width: 36rem; margin: 1rem auto; padding: 0 1rem; }
    label, select { display: block; margin-bottom: 0.5rem; }
    select, button { font: inherit; max-width: 100%; }
    pre { white-space: pre-wrap; overflow-wrap: anywhere; }
  </style>
</head>
<body>
  <h1>Verificar os valores selecionados</h1>
  <form id="demo">
    <label for="topic">Tema de interesse (obrigatório)</label>
    <select id="topic" name="topic" required>
      <option value="" selected>Escolha um tema</option>
      <optgroup label="Desenvolvimento">
        <option value="web">Desenvolvimento web</option>
        <option value="data">Processamento de dados</option>
      </optgroup>
    </select>
    <label for="skills">Tecnologias para aprender (seleção múltipla permitida)</label>
    <select id="skills" name="skills" multiple size="3">
      <option value="html" selected>HTML</option>
      <option value="css" selected>CSS</option>
      <option value="javascript">JavaScript</option>
    </select>
    <label for="locked">Campo desabilitado</label>
    <select id="locked" name="locked" disabled>
      <option value="sample">Não pode ser alterado</option>
    </select>
    <button type="submit">Mostrar valores</button>
    <button type="reset">Redefinir</button>
  </form>
  <pre id="result" aria-live="polite"></pre>
  <script>
    const form = document.getElementById('demo');
    const result = document.getElementById('result');
    form.addEventListener('submit', (event) => {
      event.preventDefault();
      const data = new FormData(form);
      result.textContent = JSON.stringify(Array.from(data.entries()), null, 2);
    });
    form.addEventListener('reset', () => { result.textContent = ''; });
  </script>
</body>
</html>
  1. Pressione Mostrar valores sem escolher um tópico. A validação de campo obrigatório do navegador impede o envio.
  2. Escolha Desenvolvimento web e pressione Mostrar valores. A saída contém topic com web, e duas entradas skills com html e css. O campo desabilitado locked é excluído.
  3. Altere a seleção de habilidades e verifique novamente. Cada opção selecionada produz outra entrada chamada skills. Se você desmarcar todas as opções, pode não haver entrada skills.
  4. Pressione Redefinir. O tópico retorna à opção de instrução vazia, as habilidades retornam para HTML e CSS, e a saída é limpa.

multiple e size são atributos diferentes

multiple permite valores múltiplos, enquanto size especifica o número de linhas visíveis. Aumentar size não habilita automaticamente a seleção múltipla. As combinações de teclado dependem do sistema operacional. Controles de desktop podem suportar Ctrl ou Command com um clique, ou Shift para seleção em intervalo; dispositivos móveis podem fornecer uma tela de seleção separada.

Ao ler várias seleções em JavaScript, select.value retorna apenas o primeiro valor selecionado. Itere sobre selectedOptions ou chame getAll('skills') em uma instância de FormData, por exemplo new FormData(form).getAll('skills'), para recuperar todos os valores. No servidor, siga as regras de análise do seu framework para campos repetidos com o mesmo nome.

Use disabled, required e selected com cuidado

disabled impede a interação e exclui o campo dos dados enviados. Um select não possui equivalente nativo para o atributo readonly de um elemento input, então adicionar readonly não o bloqueia. Desabilitar um controle no navegador também não substitui as verificações de autorização no servidor.

required, disabled, multiple e selected são atributos booleanos. Até mesmo selected="false" mantém o atributo presente, então a opção ainda pode ser tratada como inicialmente selecionada. Remova o atributo ou defina sua propriedade JavaScript correspondente como false para torná-lo falso. Um reset restaura as seleções iniciais declaradas no HTML; isso não necessariamente limpa todas as seleções.

autofocus pode focar o controle automaticamente, mas use-o apenas quando necessário, considerando a posição do leitor e o comportamento do teclado móvel. Controles nativos e pop-ups variam de acordo com o navegador e o sistema operacional, então manter as associações label e a interação padrão do teclado é útil para formulários comuns. A referência MDN de select e a referência MDN de option explicam as regras detalhadas.