Pular para o conteúdo
murad.guide

A Web Aberta

Capítulo 12

Formulários

5 min de leitura 886 palavras 2 gravuras

Este capítulo marca campos que a pessoa preenche. O Contato da Oficina Costeira, coletivo fictício de design em João Pessoa, demonstra validação do navegador. Nada é enviado a um servidor. O exemplo correspondente é 12-formularios, no pacote que acompanha o volume.

Este volume tem 52 capítulos. Ciclo: ler → copiar → mudar uma coisa → prever → recarregar → conferir.

O que você vai aprender

O form não grava ficha neste volume

form agrupa controles. action seria a URL que recebe os dados. method seria get ou post.

Neste volume não há processamento no servidor. O formulário é uma demonstração local. Por isso:

<form action="#" method="get" onsubmit="return false" autocomplete="off">

action indica o destino de um envio. O valor # sozinho não impede envio: em HTTP, um formulário GET pode colocar campos na URL e pedir a página ao servidor. Aqui, onsubmit="return false" é um pequeno apoio pronto que cancela esse envio depois da validação. Copie esse atributo também. Não há banco nem e-mail de verdade. Use apenas valores fictícios.

Erro comum: apontar action para um serviço desconhecido “só para ver”. O exercício não envia.

label aponta para id

Todo campo visível tem rótulo. O for do label copia o id do controle. Clicar no texto foca o campo. O leitor de tela anuncia o nome.

<label for="nome">Nome</label>
<input id="nome" name="nome" type="text" autocomplete="name">

name é o que viajaria no envio. Mesmo nesta demonstração, mantenha name para reconhecer a estrutura. Placeholder não substitui label. Placeholder some quando a pessoa digita.

Mude só o texto do label de “Nome” para “Nome completo”. Preveja o rótulo visível. Recarregue. Confira. O id continua nome.

Tipos de input

type="text" é o padrão. Outros tipos mudam teclado no celular e validação:

<label for="email">E-mail</label>
<input id="email" name="email" type="email" autocomplete="email" required>

O e-mail da Oficina Costeira de estudo pode ser nara@oficina.example. Domínio .example não entrega correio. Serve para testar o formato.

required, textarea, select

required impede o envio vazio. O navegador mostra aviso nativo. A referência pronta também mostra um retorno local, sem enviar campos.

<label for="mensagem">Mensagem</label>
<textarea id="mensagem" name="mensagem" rows="4" required></textarea>
<label for="assunto">Assunto</label>
<select id="assunto" name="assunto">
  <option value="oficina">Oficina</option>
  <option value="projeto">Projeto</option>
</select>
<button type="submit">Simular envio</button>

button type="submit" inicia a validação. O apoio pronto cancela o envio quando os campos são válidos. Texto do botão descreve a ação. Evite só “OK”.

Abra o exemplo. Deixe o e-mail vazio e acione o botão. Preveja o aviso do navegador. Não há carta saindo da máquina.

Resumo dos conceitos: label, required, action

fieldset, rádio e caixa

Rádios do mesmo grupo compartilham name. Só um fica marcado. Caixas (checkbox) são independentes.

<fieldset>
  <legend>Formato de resposta (demonstração)</legend>
  <p>
    <input type="radio" id="formato-email" name="formato" value="email" checked>
    <label for="formato-email">E-mail fictício</label>
  </p>
  <p>
    <input type="radio" id="formato-nenhum" name="formato" value="nenhum">
    <label for="formato-nenhum">Sem resposta</label>
  </p>
</fieldset>
<fieldset>
  <legend>Interesses (demonstração)</legend>
  <p>
    <input type="checkbox" id="interesse-cartaz" name="interesse" value="cartaz">
    <label for="interesse-cartaz">Cartaz</label>
  </p>
</fieldset>

legend nomeia o grupo. Sem fieldset, os rádios são um monte de botões soltos para o leitor de tela.

optgroup agrupa option em select longo. Na Oficina, dois assuntos bastam.

Página Contato completa

Skip-link, lang="pt-BR", menu com aria-current="page" em Contato, main id="conteudo", o form, rodapé avisando que nada é enviado.

<!DOCTYPE html>
<html lang="pt-BR">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Contato — Oficina Costeira</title>
  </head>
  <body>
    <a class="skip" href="#conteudo">Pular para o conteúdo</a>
    <header>
      <p><a href="index.html">Oficina Costeira</a></p>
      <nav aria-label="Principal">
        <ul>
          <li><a href="index.html">Início</a></li>
          <li><a href="contato.html" aria-current="page">Contato</a></li>
        </ul>
      </nav>
    </header>
    <main id="conteudo" tabindex="-1">
      <h1>Contato</h1>
      <p>Este formulário não envia nada. É só marcação e validação do navegador.</p>
      <form action="#" method="get" onsubmit="return false" autocomplete="off">
        <p>
          <label for="nome">Nome</label>
          <input id="nome" name="nome" type="text" required>
        </p>
        <p>
          <label for="email">E-mail</label>
          <input id="email" name="email" type="email" required>
        </p>
        <p>
          <button type="submit">Simular envio</button>
        </p>
      </form>
    </main>
  </body>
</html>

Arquivo no disco: a marcação. Página no navegador: avisos nativos. Teste em 127.0.0.1: o envio é cancelado e os campos não entram na URL. Publicação pública com ficha real não faz parte deste volume.

Resumo dos conceitos: action, required, label

Erro comum: label sem for, ou for="email" com id="e-mail". O clique no texto não foca. O leitor lê “edição” sem nome.

O que não fazer

Não peça CPF, cartão, senha de banco. Não ligue serviço de e-mail de terceiros no exercício. O exemplo completo usa autocomplete="off" para reduzir o preenchimento automático de dados reais. Os atributos autocomplete="name" e autocomplete="email" acima mostram os nomes usados em formulários reais; digite apenas valores fictícios aqui.

pattern com expressão regular fica para depois, se precisar. required e type="email" já ensinam validação.

Atividades

  1. Por que precisamos cancelar o envio, além de usar action="#"?
  2. O que quebra se for e id não forem iguais?
  3. Qual a diferença entre rádios com o mesmo name e caixas com o mesmo name?
  4. No exemplo, envie o form vazio e depois com e-mail sem @. O que o navegador fez em cada caso?

Respostas comentadas

  1. Porque # sozinho não cancela envio. O apoio pronto cancela o envio após a validação, para estudar marcação sem mandar campos a um servidor. A Oficina Costeira de estudo não tem backend. PHP está em outro curso.
  2. O rótulo deixa de associar. Clique no texto não foca. Tecnologia assistiva anuncia campo sem nome.
  3. Rádios com o mesmo name são uma escolha. Caixas com o mesmo name podem marcar várias; o envio real agruparia valores. Aqui o envio é simulado.
  4. Vazio com required: aviso de campo obrigatório. Sem @ em type="email": aviso de formato. A página não “cadastra” ninguém.

Referências

O arquivo completo

Referência do exemplo 12-formularios, reproduzida aqui para que você possa conferir sem sair da página.

assets/javascript/simulacao.js

const form=document.querySelector("#simulacao");if(form){form.querySelector("button[type=submit]").disabled=false;form.addEventListener("submit",event=>{event.preventDefault();document.querySelector("#retorno").textContent="Simulação concluída. Nada foi enviado ou guardado.";});}