Formulários: Select, Textarea e Validação Nativa
No nó anterior, vimos inputs e botões. Agora vamos para campos mais ricos — onde tem mais coisa para escolher ou escrever — e a validação nativa do HTML, que é poderosa e subutilizada.
<select> — listas de opções
<label for="estado">Estado</label>
<select id="estado" name="estado" required>
<option value="">Selecione…</option>
<option value="AC">Acre</option>
<option value="AL">Alagoas</option>
<option value="AP">Amapá</option>
<option value="BA">Bahia</option>
<!-- ... -->
</select>
<select>é a caixa de seleção (o "dropdown").<option value="...">é cada item. Ovalueé o que vai no envio; o texto entre as tags é o que o usuário vê.- O truque da primeira opção com
value=""é comum: dá ao usuário uma escolha neutra que falha norequired.
Para seleção múltipla:
<label for="linguas">Línguas que você fala</label>
<select id="linguas" name="linguas" multiple size="4">
<option value="pt">Português</option>
<option value="en">Inglês</option>
<option value="es">Espanhol</option>
<option value="fr">Francês</option>
</select>
size="4" mostra 4 opções de uma vez; sem size, vira um dropdown
clássico (uma de cada vez). Com multiple, o usuário segura Ctrl/Cmd
pra escolher várias.
Para agrupar opções:
<select name="comida">
<optgroup label="Frutas">
<option value="maca">Maçã</option>
<option value="banana">Banana</option>
</optgroup>
<optgroup label="Verduras">
<option value="alface">Alface</option>
<option value="tomate">Tomate</option>
</optgroup>
</select>
<datalist> — input com sugestões
É um meio-termo entre <input> e <select>: o usuário pode digitar
qualquer coisa, mas tem sugestões para escolher.
<label for="navegador">Navegador favorito</label>
<input type="text" id="navegador" name="navegador" list="navegadores">
<datalist id="navegadores">
<option value="Chrome">
<option value="Firefox">
<option value="Safari">
<option value="Edge">
<option value="Brave">
</datalist>
O list="navegadores" no input conecta ao <datalist id="navegadores">.
<textarea> — texto longo
Para mais de uma linha:
<label for="mensagem">Mensagem</label>
<textarea id="mensagem" name="mensagem" rows="6" cols="50"
placeholder="Escreva aqui…" required minlength="20"></textarea>
rowsecolssão dimensões iniciais (em linhas e colunas de caractere). O usuário pode redimensionar e o CSS pode sobrescrever.- Diferente do
<input>,<textarea>tem tag de fechamento: o conteúdo entre elas é o valor inicial.
Validação nativa — o navegador faz o trabalho
O HTML tem atributos que dizem ao navegador: "esse campo tem essas regras". O navegador bloqueia o envio e mostra uma mensagem de erro se algo não bater. Não precisa de JavaScript para o básico.
<form>
<label for="email">E-mail</label>
<input type="email" id="email" name="email" required>
<label for="idade">Idade</label>
<input type="number" id="idade" name="idade" min="18" max="120" required>
<label for="usuario">Usuário (3 a 15 caracteres)</label>
<input type="text" id="usuario" name="usuario"
pattern="[a-z0-9_]{3,15}" required
title="3 a 15 letras minúsculas, números ou underline">
<label for="senha">Senha (mínimo 8 caracteres)</label>
<input type="password" id="senha" name="senha" minlength="8" required>
<label for="site">Site pessoal</label>
<input type="url" id="site" name="site"
placeholder="https://exemplo.com">
<button type="submit">Cadastrar</button>
</form>
Atributos de validação:
required— campo obrigatório.minlength/maxlength— comprimento de texto mínimo e máximo.min/max— valor mínimo e máximo (number, date, range).step— incremento permitido (ex:step="0.01"para moeda).pattern="regex"— uma expressão regular que o valor deve casar. Use para formatos específicos.type— valida formato (email, url, tel, number).
Você também pode escrever validação customizada em JavaScript para coisas mais complexas (ex: "a senha não pode ser igual ao nome de usuário"). Mas a validação nativa já cobre 80% dos casos — use-a.
Mensagens de erro personalizadas
Por padrão, o navegador tem mensagens em inglês e genéricas. Você pode
customizar com setCustomValidity em JavaScript:
const email = document.getElementById("email");
email.addEventListener("input", () => {
if (email.validity.typeMismatch) {
email.setCustomValidity("Por favor, insira um e-mail válido.");
} else {
email.setCustomValidity("");
}
});
Ou, mais moderno, com CSS :invalid + seletor de mensagem customizada.
novalidate — desligar a validação nativa
<form novalidate>
<!-- ... -->
</form>
Útil quando você quer toda validação em JavaScript (ex: validação server-side que depende de uma chamada de API). Cuidado: isso delega 100% ao JS — se o JS falhar, o form envia sem validar.
formaction, formmethod, formnovalidate em botões
Um único form pode ter múltiplos botões de envio com destinos diferentes:
<form action="/rascunho" method="post">
<!-- ... campos ... -->
<button type="submit">Salvar como rascunho</button>
<button type="submit" formaction="/publicar">Publicar</button>
</form>
O segundo botão envia para /publicar em vez de /rascunho. Útil para
"salvar vs publicar", "preview vs enviar", etc.
<select>é o dropdown. Use<option>para itens,<optgroup>para agrupar.<datalist>dá sugestões a um<input>sem limitar.<textarea>é texto de várias linhas.- Validação nativa com
required,pattern,min,max,type— sem JS, navegador mostra o erro. patternaceita regex para formatos específicos.- Não desabilite a validação nativa sem boa razão.
Dica: a validação nativa é gratuita e acessível (o navegador anuncia os erros pra leitores de tela). Use-a. Só vá pra JavaScript quando precisar de regras mais complexas.
No próximo nó, vamos falar de HTML semântico — as tags que descrevem o papel de cada parte da página.