SW Core
SW Core / JavaScript / Validação de formulário

Validação de formulário JavaScript

Confere o formulário inteiro antes de enviar: se algo estiver errado, não envia, pinta o campo de vermelho, escreve o motivo embaixo e leva a pessoa até ele.

O que é

Você escreve as regras do jeito normal do HTML — required (obrigatório), type="email", minlength="8", min/max, pattern — e coloca sw-valid na tag <form>. Pronto: no lugar do balãozinho feio do navegador, cada campo errado fica vermelho com a mensagem embaixo, no visual do SW Core. Se a pessoa clicar em Enviar com erro, o envio é barrado e o cursor vai para o primeiro campo errado. A mensagem pode ser sua, escrita em data-sw-error.

Precisa do CSS e do JavaScript do SW Core. Ele desliga o balão do navegador e assume a conferência. Enquanto a pessoa preenche, cada campo é conferido quando ela sai dele (e, depois, a cada tecla, para o erro sumir assim que corrigir). No envio, confere todos. Campo errado ganha a classe is-err; campo certo e preenchido ganha is-ok — no próprio campo e também na caixa sw-fld em volta (é isso que deixa o rótulo flutuante vermelho/verde) e na <div sw-select>, quando for um Select (JS). A mensagem é criada sozinha dentro da caixa sw-fld, e o leitor de tela já anuncia o erro. A mensagem sai nesta ordem: a sua (data-sw-error), senão a do navegador, senão "Revise este campo.".

Quando usar

  • Formulário de contato, orçamento, cadastro: não deixar chegar mensagem sem e-mail ou sem telefone.
  • Checkout: conferir tudo de uma vez antes de ir para o pagamento.
  • Envio por AJAX (sem recarregar a página): o evento sw:valid-submit avisa que está tudo certo, e você envia com fetch.
  • Formulário curto que não deve "reclamar" enquanto a pessoa digita: sw-valid-live="false", confere só no envio.
  • Para regras que o HTML não tem (confirmar senha, formato próprio, erro vindo do servidor) e aviso campo a campo, veja a Validação inline (sw-matinp).

Comece aqui

  1. 1

    Coloque o SW Core na página: o CSS no <head> e o JavaScript antes de fechar o </body>.

    <link rel="stylesheet" href="swcore/swcore.min.css">
    <!-- … sua página … -->
    <script src="swcore/swcore.min.js"></script>
  2. 2

    Coloque sw-valid no <form> e as regras normais do HTML nos campos. Clique em Enviar com o campo vazio. (Nos exemplos desta página o envio é bloqueado para você continuar aqui.)

    <form sw-valid action="/contato" method="post">
      <div sw-fld>
        <label class="is-req" for="email">E-mail</label>
        <input sw-inp id="email" name="email" type="email" required
               data-sw-error="Informe um e-mail válido">
      </div>
      <button sw-btn="pri" type="submit">Enviar</button>
    </form>

Todas as variações

Cada quadro abaixo é o componente de verdade, rodando. O código embaixo é exatamente o que está no quadro: copie e cole.

1. Regras do HTML que ele entende

Cada quadro é um formulário com uma regra. Clique em Enviar vazio ou com algo errado. As mensagens destes quadros são do data-sw-error.

required — obrigatório <input sw-inp required data-sw-error="Conta pra gente seu nome">
type="email" — formato de e-mail <input sw-inp type="email" data-sw-error="E-mail incompleto">
type="url" — endereço de site <input sw-inp type="url" data-sw-error="Comece com https://">
minlength — mínimo de letras <input sw-inp type="password" minlength="8" data-sw-error="Pelo menos 8 caracteres">
min / max — faixa de número <input sw-inp type="number" min="1" max="8" data-sw-error="De 1 a 8 pessoas">
pattern — formato próprio <input sw-inp pattern="[0-9]{5}-?[0-9]{3}" data-sw-error="Formato: 00000-000">
required em lista (select) <select sw-inp required data-sw-error="Escolha um estado"> <option value="">Selecione…</option> <option>Pernambuco</option> </select>
required em caixa de marcar <div sw-fld> <label sw-chk> <input type="checkbox" required data-sw-error="Aceite para continuar"> Aceito os termos </label> </div>

2. De onde vem a mensagem

Com data-sw-error a mensagem é sua. Sem ele, aparece o texto do próprio navegador (no idioma do navegador de quem visita, e cada navegador escreve de um jeito).

Com data-sw-error — texto seu <input sw-inp type="tel" required data-sw-error="Precisamos do telefone para confirmar">
Sem data-sw-error — texto do navegador <input sw-inp type="tel" required>

3. Quando conferir (sw-valid-live)

Em cada quadro: clique no campo, digite uma letra e saia; depois apague e digite de novo.

"true" — ao sair e, depois, a cada tecla (padrão) <form sw-valid>…</form>
"blur" — só ao sair do campo <form sw-valid sw-valid-live="blur">…</form>
"false" — só quando clicar em Enviar <form sw-valid sw-valid-live="false">…</form>

Tabela de opções

PalavraO que fazExemplo
No <form>
sw-validLiga a conferência no formulário. Sem valor. Só funciona na tag <form>.<form sw-valid>
sw-valid-live="true"Padrão: confere ao sair de cada campo e, a partir daí, a cada tecla.<form sw-valid>
sw-valid-live="blur"Confere só ao sair do campo (e ao trocar opção de lista/caixa).<form sw-valid sw-valid-live="blur">
sw-valid-live="false"Não confere durante o preenchimento; só no envio.<form sw-valid sw-valid-live="false">
Regras (atributos normais do HTML, no campo)
requiredObrigatório (em input, select, textarea, checkbox e radio).<input required>
type="email" · "url" · "number"O tipo já é uma regra de formato.<input type="email">
minlength · maxlengthMínimo / máximo de caracteres.<input minlength="8">
min · max · stepFaixa e intervalo de número ou data.<input type="number" min="1" max="8">
patternFormato próprio (expressão regular).<input pattern="[0-9]{5}-?[0-9]{3}">
Mensagem
data-sw-error="…"No campo: a mensagem de erro. Sem ele, vale a do navegador; sem nenhuma, "Revise este campo.".<input required data-sw-error="Obrigatório">
O que ele coloca na página
is-err · is-okClasses no próprio campo, na caixa sw-fld em volta e na <div sw-select>: vermelho (errado) / verde (certo e preenchido). A caixa sw-fld fica vermelha se qualquer campo dela estiver errado.
<p class="sw-fld-msg">A mensagem, criada dentro da caixa sw-fld (ou do pai do campo), com id <id-do-campo>-error.
aria-invalid · aria-describedbyMarcam o campo como errado e ligam à mensagem, para o leitor de tela.
data-sw-valid-stateNo form: valid ou invalid. Dá para usar no seu CSS.form[data-sw-valid-state="valid"]

Receitas prontas — usos reais

Situações que aparecem em quase todo site. Copie a que servir.

Formulário de contato completo Ao vivo
<form sw-valid sw-frm action="/contato" method="post">
  <div sw-frm-row>
    <div sw-fld>
      <label class="is-req" for="nome">Nome</label>
      <input sw-inp id="nome" name="nome" required minlength="3"
             data-sw-error="Conta pra gente seu nome">
    </div>
    <div sw-fld>
      <label class="is-req" for="tel">WhatsApp</label>
      <input sw-inp id="tel" name="tel" type="tel" sw-mask="telefone" required minlength="14"
             data-sw-error="Número com DDD">
    </div>
  </div>
  <div sw-fld>
    <label class="is-req" for="email">E-mail</label>
    <input sw-inp id="email" name="email" type="email" required
           data-sw-error="Informe um e-mail válido">
  </div>
  <div sw-fld>
    <label for="msg">Mensagem</label>
    <textarea sw-inp id="msg" name="msg" maxlength="500"></textarea>
  </div>
  <div sw-fld>
    <label sw-chk>
      <input type="checkbox" name="autorizo" required data-sw-error="Precisamos da sua autorização">
      Autorizo o contato por WhatsApp
    </label>
  </div>
  <div sw-frm-act>
    <button sw-btn="ghost sec" type="reset">Limpar</button>  <!-- também limpa os erros -->
    <button sw-btn="pri" type="submit">Enviar</button>
  </div>
</form>
Enviar por AJAX quando estiver tudo certo Ao vivo

<form sw-valid sw-frm id="news">
  <div sw-fld>
    <label class="is-req" for="email">E-mail para a newsletter</label>
    <input sw-inp id="email" name="email" type="email" required
           data-sw-error="Informe um e-mail válido">
  </div>
  <div sw-frm-act><button sw-btn="pri" type="submit">Assinar</button></div>
</form>

<script>
  const form = document.getElementById('news');

  // tudo certo: cancele o envio normal e mande por fetch
  form.addEventListener('sw:valid-submit', async (e) => {
    e.preventDefault();
    await fetch('/newsletter', { method: 'POST', body: new FormData(form) });
    SW.Alert.ok('Inscrição feita!');
  });

  // algo errado: o envio já foi barrado e o cursor está no campo
  form.addEventListener('sw:valid-error', () => {
    SW.Alert.err('Confira os campos destacados');
  });
</script>
Conferir pelo código (botão "Próximo" de um formulário em etapas) Ao vivo
<form sw-valid sw-frm id="etapa1">
  <div sw-fld>
    <label class="is-req" for="cep">CEP</label>
    <input sw-inp id="cep" required pattern="[0-9]{5}-?[0-9]{3}" data-sw-error="Formato: 00000-000">
  </div>
  <div sw-frm-act>
    <button sw-btn="pri" type="button" id="proximo">Próximo</button>
  </div>
</form>

<script>
  document.getElementById('proximo').addEventListener('click', () => {
    if (SW.Valid.check('#etapa1')) {
      // tudo certo: mostre a próxima etapa
    }
  });
</script>

Eventos

sw:valid-error
No <form>: o envio foi barrado porque algum campo está errado. O cursor já foi para o primeiro campo errado.
sw:valid-submit
No <form>: tudo certo, o envio vai acontecer. Chame e.preventDefault() para cancelar o envio normal e enviar do seu jeito (fetch).

API (JavaScript)

SW.Valid.check('#form')
Confere o formulário agora, mostra os erros, leva o cursor ao primeiro e devolve true (tudo certo) ou false. Com { focus: false } no segundo parâmetro, não mexe no cursor.
SW.Valid.init(form)
Liga a conferência num formulário criado depois que a página carregou (normalmente não precisa: blocos novos são ligados sozinhos).

Precisa de quê

  • swcore.min.css e swcore.min.js.
  • Cada campo dentro de uma caixa <div sw-fld> — é nela que a mensagem entra.

Cuidados — erros comuns

  • sw-valid só funciona na tag <form>. Numa <div> não faz nada.
  • O botão de enviar precisa ser type="submit" dentro do form. Um botão type="button" não dispara a conferência (use SW.Valid.check() nele).
  • Campo com disabled é ignorado na conferência.
  • Sem data-sw-error, a mensagem muda de navegador para navegador e fica no idioma do visitante. Para um texto igual para todos, escreva o seu.
  • Deixe espaço entre os campos (use sw-frm): a mensagem aparece embaixo do campo sem empurrar nada.
  • maxlength não gera erro ao digitar: o navegador simplesmente não deixa passar do limite.

O que ele não faz

  • Só entende as regras do HTML. "Senha igual à outra", "CPF válido" ou "e-mail já cadastrado" precisam de sw-matinp ou do seu código.
  • É conferência no navegador. O servidor precisa conferir de novo, sempre.