SWCore
SWCore / Componentes / Validação inline (matinp)

Validação inline (matinp) Componentes

Confere cada campo assim que a pessoa sai dele e já mostra "certo" ou "errado" com a mensagem — sem esperar o envio do formulário.

O que é

É a conferência campo a campo: a pessoa digita o e-mail, passa para o próximo campo e, se estiver faltando o "@", o campo fica vermelho na hora com "E-mail inválido.". Você liga isso colocando sw-matinp no <input> e escreve as regras como atributos: sw-matinp-req (obrigatório), sw-matinp-email, sw-matinp-minlen="8"… Pode juntar várias regras no mesmo campo. Cada regra tem uma mensagem pronta em português, que você pode trocar. De quebra, ele formata telefone, CPF, CEP e outros enquanto a pessoa digita.

Precisa do CSS e do JavaScript do SWCore. Por padrão a conferência acontece quando a pessoa sai do campo. Depois que um campo deu erro, ele passa a conferir a cada tecla, para o vermelho sumir assim que a pessoa corrigir. Com erro, a caixa sw-fld ganha a classe is-err e a mensagem aparece embaixo; certo, ganha is-ok (verde). As regras são testadas sempre nesta ordem: obrigatório, e-mail, site, mínimo de letras, máximo de letras, valor mínimo, valor máximo, igual a outro campo, formato próprio — e só a primeira que falhar aparece.

Quando usar

  • Cadastro e checkout: avisar do erro no campo, na hora, em vez de só no fim.
  • Confirmar senha ou e-mail: "precisa ser igual ao outro campo" — sw-matinp-match.
  • Telefone, CPF, CEP: formatar enquanto digita e conferir no mesmo campo — sw-matinp-mask.
  • Erro que só o servidor sabe ("CPF já cadastrado"): mostrar no campo certo, pelo JavaScript.
  • Para travar o envio e conferir o formulário inteiro de uma vez, use junto (ou no lugar) a Validação de formulário (sw-valid).

Comece aqui

  1. 1

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

    <link rel="stylesheet" href="https://swcore.sanweb.com.br/dist/2.1.0/swcore.min.css">
    <!-- … sua página … -->
    <script src="https://swcore.sanweb.com.br/dist/2.1.0/swcore.min.js"></script>
  2. 2

    Monte o campo normalmente (com sw-fld) e acrescente sw-matinp + as regras no input. Clique no campo e saia sem preencher.

    <div sw-fld="float">
      <input sw-inp id="email" type="email" placeholder=" "
             sw-matinp sw-matinp-req sw-matinp-email>
      <label for="email">Seu e-mail</label>
    </div>

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

Clique em cada campo, digite algo errado (ou nada) e saia dele. Sem sw-matinp-req, o campo vazio passa: as outras regras só conferem quando há algo escrito.

req — obrigatório <div sw-fld><label for="mat-r1">Nome</label><input sw-inp id="mat-r1" sw-matinp sw-matinp-req></div>
email — formato de e-mail <div sw-fld> <label for="mat-r2">E-mail</label> <input sw-inp id="mat-r2" type="email" sw-matinp sw-matinp-email> </div>
url — endereço com http(s):// <div sw-fld><label for="mat-r3">Seu site</label><input sw-inp id="mat-r3" sw-matinp sw-matinp-url></div>
minlen — mínimo de letras <div sw-fld> <label for="mat-r4">Senha (8+)</label> <input sw-inp id="mat-r4" type="password" sw-matinp sw-matinp-minlen="8"> </div>
maxlen — máximo de letras <div sw-fld> <label for="mat-r5">Apelido (até 12)</label> <input sw-inp id="mat-r5" sw-matinp sw-matinp-maxlen="12"> </div>
min / max — faixa de valor <div sw-fld> <label for="mat-r6">Pessoas (1 a 10)</label> <input sw-inp id="mat-r6" type="number" sw-matinp sw-matinp-min="1" sw-matinp-max="10"> </div>
match — igual a outro campo <div sw-fld> <label for="mat-r7a">Senha</label> <input sw-inp id="mat-r7a" type="password"> </div> <div sw-fld> <label for="mat-r7b">Repita a senha</label> <input sw-inp id="mat-r7b" type="password" sw-matinp sw-matinp-match="#mat-r7a"> </div>
regex — formato próprio <div sw-fld> <label for="mat-r8">Placa (ABC1D23)</label> <input sw-inp id="mat-r8" sw-matinp sw-matinp-regex="^[A-Z]{3}[0-9][A-Z0-9][0-9]{2}$"> </div>

2. Mensagens com as suas palavras

Cada regra tem um sw-matinp-msg-… para trocar o texto padrão. As mensagens padrão aparecem na tabela de opções.

msg-req <div sw-fld> <label for="mat-m1">Nome</label> <input sw-inp id="mat-m1" sw-matinp sw-matinp-req sw-matinp-msg-req="Como podemos te chamar?"> </div>
msg-email <div sw-fld> <label for="mat-m2">E-mail</label> <input sw-inp id="mat-m2" sw-matinp sw-matinp-email sw-matinp-msg-email="Faltou o @ ou o .com"> </div>
msg-minlen <div sw-fld> <label for="mat-m3">Senha</label> <input sw-inp id="mat-m3" type="password" sw-matinp sw-matinp-minlen="8" sw-matinp-msg-minlen="Use 8 letras ou mais"> </div>
msg-regex <div sw-fld> <label for="mat-m4">Cupom</label> <input sw-inp id="mat-m4" sw-matinp sw-matinp-regex="^[A-Z]{3}[0-9]{2}$" sw-matinp-msg-regex="Formato: ABC10"> </div>

3. Quando conferir

Digite uma letra em cada campo: o do meio reclama na hora; os outros só quando você sai do campo (ou confirma).

blur — ao sair do campo (padrão) <div sw-fld><label for="mat-q1">Ao sair</label><input sw-inp id="mat-q1" sw-matinp sw-matinp-minlen="4"></div>
input — a cada tecla <div sw-fld> <label for="mat-q2">A cada tecla</label> <input sw-inp id="mat-q2" sw-matinp sw-matinp-minlen="4" sw-matinp-validate="input"> </div>
change — ao confirmar a mudança <div sw-fld> <label for="mat-q3">Ao confirmar</label> <input sw-inp id="mat-q3" sw-matinp sw-matinp-minlen="4" sw-matinp-validate="change"> </div>

4. Máscara embutida (formata enquanto digita)

sw-matinp-mask formata o campo a cada tecla. São 7 formatos. Digite só os números.

telefone — (00) 0000-0000 ou (00) 00000-0000 <div sw-fld> <label for="mat-k1">Telefone</label> <input sw-inp id="mat-k1" inputmode="numeric" sw-matinp sw-matinp-mask="telefone"> </div>
cpf — 000.000.000-00 <div sw-fld> <label for="mat-k2">CPF</label> <input sw-inp id="mat-k2" inputmode="numeric" sw-matinp sw-matinp-mask="cpf"> </div>
cnpj — 00.000.000/0000-00 <div sw-fld> <label for="mat-k3">CNPJ</label> <input sw-inp id="mat-k3" inputmode="numeric" sw-matinp sw-matinp-mask="cnpj"> </div>
cep — 00000-000 <div sw-fld> <label for="mat-k4">CEP</label> <input sw-inp id="mat-k4" inputmode="numeric" sw-matinp sw-matinp-mask="cep"> </div>
data — 00/00/0000 <div sw-fld> <label for="mat-k5">Nascimento</label> <input sw-inp id="mat-k5" inputmode="numeric" sw-matinp sw-matinp-mask="data"> </div>
hora — 00:00 <div sw-fld> <label for="mat-k6">Horário</label> <input sw-inp id="mat-k6" inputmode="numeric" sw-matinp sw-matinp-mask="hora"> </div>
cartao — 0000 0000 0000 0000 <div sw-fld> <label for="mat-k7">Cartão</label> <input sw-inp id="mat-k7" inputmode="numeric" sw-matinp sw-matinp-mask="cartao"> </div>
Máscara + regra juntas <div sw-fld> <label for="mat-k8">Celular</label> <input sw-inp id="mat-k8" inputmode="numeric" sw-matinp sw-matinp-mask="telefone" sw-matinp-req sw-matinp-minlen="15" sw-matinp-msg-minlen="Celular com DDD e 9 dígitos"> </div>

5. Rótulo e ajuda escritos no próprio input

No rótulo flutuante, sw-matinp-label cria o <label> sozinho (se não houver um). sw-matinp-hint cria o texto de ajuda embaixo, que se esconde enquanto há erro.

sw-matinp-label (com sw-fld="float") <div sw-fld="float"><input sw-inp id="mat-l1" sw-matinp sw-matinp-req sw-matinp-label="Nome da empresa"></div>
sw-matinp-hint — ajuda embaixo <div sw-fld> <label for="mat-l2">Usuário</label> <input sw-inp id="mat-l2" sw-matinp sw-matinp-req sw-matinp-minlen="4" sw-matinp-hint="Só letras e números, sem espaço."> </div>

Tabela de opções

PalavraO que fazExemplo
Ligar
sw-matinpNo input: liga a conferência. Sem valor.<input sw-inp sw-matinp …>
Regras (atributos no input)
sw-matinp-reqObrigatório. Mensagem padrão: "Campo obrigatório."sw-matinp-req
sw-matinp-emailPrecisa ter formato de e-mail (algo@algo.algo). Padrão: "E-mail inválido."sw-matinp-email
sw-matinp-urlPrecisa começar com http:// ou https://. Padrão: "URL inválida."sw-matinp-url
sw-matinp-minlen="n"Mínimo de n caracteres. Padrão: "Mínimo n caracteres."sw-matinp-minlen="8"
sw-matinp-maxlen="n"Máximo de n caracteres. Padrão: "Máximo n caracteres."sw-matinp-maxlen="60"
sw-matinp-min="n"Valor numérico mínimo. Padrão: "Valor mínimo: n."sw-matinp-min="1"
sw-matinp-max="n"Valor numérico máximo. Padrão: "Valor máximo: n."sw-matinp-max="99"
sw-matinp-match="#id"Precisa ser igual ao campo daquele id. Padrão: "Os valores não coincidem."sw-matinp-match="#senha"
sw-matinp-regex="…"Precisa bater com a expressão regular. Padrão: "Formato inválido."sw-matinp-regex="^[0-9]{5}$"
Mensagens próprias
sw-matinp-msg-reqTroca a mensagem de req.sw-matinp-msg-req="Conta seu nome"
sw-matinp-msg-email · -msg-urlTrocam as mensagens de e-mail e de site.sw-matinp-msg-email="Confira o e-mail"
sw-matinp-msg-minlen · -msg-maxlenTrocam as mensagens de tamanho.sw-matinp-msg-minlen="Muito curto"
sw-matinp-msg-min · -msg-maxTrocam as mensagens de valor.sw-matinp-msg-max="No máximo 10"
sw-matinp-msg-match · -msg-regexTrocam as mensagens de igualdade e de formato.sw-matinp-msg-match="As senhas não batem"
Quando conferir — sw-matinp-validate
blurAo sair do campo; depois de um erro, também a cada tecla. É o padrão.sw-matinp-validate="blur"
inputA cada tecla, desde o começo.sw-matinp-validate="input"
changeQuando o valor é confirmado (sair do campo depois de mudar).sw-matinp-validate="change"
Máscara — sw-matinp-mask
telefone(00) 0000-0000 até 10 dígitos; (00) 00000-0000 com 11.sw-matinp-mask="telefone"
cpf000.000.000-00sw-matinp-mask="cpf"
cnpj00.000.000/0000-00sw-matinp-mask="cnpj"
cep00000-000sw-matinp-mask="cep"
data00/00/0000sw-matinp-mask="data"
hora00:00sw-matinp-mask="hora"
cartao0000 0000 0000 0000sw-matinp-mask="cartao"
Extras
sw-matinp-label="…"Cria o <label> logo depois do input, se a caixa não tiver um. Pensado para sw-fld="float".sw-matinp-label="Nome"
sw-matinp-hint="…"Cria (ou preenche) o texto de ajuda sw-fld-hint. Some enquanto há erro.sw-matinp-hint="Como no documento"
Classes que ele coloca na caixa sw-fld
is-errCom erro: campo vermelho e mensagem em sw-fld-msg.
is-okConferido e preenchido: campo verde.

Receitas prontas — usos reais

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

Cadastro: nome, e-mail, celular e senha com confirmação Ao vivo
<form sw-frm action="/cadastro" method="post">
  <div sw-fld="float">
    <input sw-inp id="nome" name="nome" placeholder=" "
           sw-matinp sw-matinp-req sw-matinp-minlen="3">
    <label for="nome">Nome completo</label>
  </div>
  <div sw-frm-row>
    <div sw-fld="float">
      <input sw-inp id="email" name="email" type="email" placeholder=" "
             sw-matinp sw-matinp-req sw-matinp-email>
      <label for="email">E-mail</label>
    </div>
    <div sw-fld="float">
      <input sw-inp id="cel" name="cel" inputmode="numeric" placeholder=" "
             sw-matinp sw-matinp-req sw-matinp-mask="telefone">
      <label for="cel">Celular</label>
    </div>
  </div>
  <div sw-frm-row>
    <div sw-fld="float">
      <input sw-inp id="senha" name="senha" type="password" placeholder=" "
             sw-matinp sw-matinp-req sw-matinp-minlen="8" sw-matinp-hint="8 caracteres ou mais">
      <label for="senha">Senha</label>
    </div>
    <div sw-fld="float">
      <input sw-inp id="senha2" type="password" placeholder=" "
             sw-matinp sw-matinp-req sw-matinp-match="#senha"
             sw-matinp-msg-match="As senhas não são iguais">
      <label for="senha2">Repita a senha</label>
    </div>
  </div>
  <div sw-frm-act><button sw-btn="pri" type="submit">Criar conta</button></div>
</form>
Erro que veio do servidor ("CPF já cadastrado") Ao vivo
<div sw-fld>
  <label for="cpf">CPF</label>
  <input sw-inp id="cpf" inputmode="numeric" sw-matinp sw-matinp-mask="cpf">
</div>

<script>
  const cpf = document.getElementById('cpf');
  fetch('/api/cpf-existe?cpf=' + cpf.value)
    .then((r) => r.json())
    .then((res) => {
      if (res.existe) cpf._swMatinp.setError('Este CPF já está cadastrado');
      else cpf._swMatinp.clearError();
    });
</script>
Regra nova sua: só números pares Ao vivo
<div sw-fld>
  <label for="qtd">Quantidade (só pares)</label>
  <input sw-inp id="qtd" type="number" sw-matinp sw-matinp-par>
</div>

<script>
  // a função recebe (valor, parâmetro, campo) e devolve
  // true quando está certo, ou o TEXTO do erro quando está errado
  SW.Matinp.addRule('par', (valor) =>
    !valor || Number(valor) % 2 === 0 || 'Use um número par.'
  );
</script>
Liberar o botão só quando o campo estiver certo Ao vivo
<div sw-fld>
  <label for="news">E-mail para a newsletter</label>
  <input sw-inp id="news" type="email"
         sw-matinp sw-matinp-req sw-matinp-email sw-matinp-validate="input">
</div>
<button sw-btn="pri" id="assinar" disabled>Quero receber</button>

<script>
  const campo = document.getElementById('news');
  const botao = document.getElementById('assinar');
  campo.addEventListener('sw:matinp:valid',   () => { botao.disabled = false; });
  campo.addEventListener('sw:matinp:invalid', () => { botao.disabled = true; });
</script>

Eventos

sw:matinp:valid
O campo passou em todas as regras e não está vazio. Traz e.detail.value.
sw:matinp:invalid
O campo reprovou. Traz e.detail.value e e.detail.error (o texto do erro).
sw:matinp:change
O valor mudou: a cada tecla (no modo padrão e em input) ou a cada formatação da máscara. Traz e.detail.value.

API (JavaScript)

SW.Matinp.addRule('nome', fn)
Cria uma regra nova, usada como sw-matinp-nome="parâmetro". A função recebe (valor, parâmetro, campo) e devolve true (certo) ou o texto do erro. Ela é testada depois das regras prontas.
campo._swMatinp.validate()
Confere o campo agora. Devolve true ou false.
campo._swMatinp.setError('texto')
Mostra um erro seu no campo (ex.: vindo do servidor).
campo._swMatinp.clearError()
Tira o erro mostrado.
campo._swMatinp.getValue()
Lê o valor do campo.
campo._swMatinp.setValue(v)
Escreve o valor e já confere.
campo._swMatinp.reset()
Limpa o campo e volta ao normal (nem vermelho nem verde).

Precisa de quê

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

Cuidados — erros comuns

  • A função de addRule tem que devolver o texto do erro quando falha. Se devolver false, o campo passa como certo.
  • A ordem dos atributos não muda nada: as regras são sempre testadas na ordem fixa (obrigatório, e-mail, site, mínimo, máximo, valor mínimo, valor máximo, igual, formato, e depois as suas).
  • Sem sw-matinp-req, um campo vazio é considerado certo — as outras regras só valem quando há algo escrito.
  • sw-matinp-url exige o começo http:// ou https://. "meusite.com.br" sozinho dá erro.
  • Não use sw-matinp-mask e sw-mask no mesmo campo: os dois formatam e brigam. Escolha um.
  • O sw-matinp-label cria o rótulo depois do input — certo para sw-fld="float". Na caixa comum, escreva o <label> você mesmo, em cima.
  • Em min/max e no minlen com máscara, conta o texto como está na tela (com parênteses, pontos e traço).

O que ele não faz

  • Confere um campo por vez, quando a pessoa mexe nele. Ele não impede o envio do formulário: para isso use Validação de formulário (sw-valid).
  • A máscara embutida tem 7 formatos (não tem dinheiro nem formato próprio). Para esses, use o componente Máscara.
  • Não confere se o CPF/CNPJ é verdadeiro (dígito verificador) — só o formato. Dá para criar isso com addRule.
  • É conferência no navegador, para ajudar quem preenche. O servidor precisa conferir de novo, sempre.