Neste artigo, examinamos os campos de formulário HTML e as opções de validação oferecidas pelo HTML5. Também veremos como essas opções podem ser aprimoradas através do uso do CSS e JavaScript.
O que é Validação por Restrições?
Cada campo de formulário tem um propósito. E esse propósito é frequentemente governado por restrições — ou as regras que regem o que deve e não deve ser inserido em cada campo de formulário. Por exemplo, um campo email
exigirá um endereço de email válido; um campo senha
pode exigir certos tipos de caracteres e ter um número mínimo de caracteres necessários; e um campo de texto pode ter um limite no número de caracteres que podem ser inseridos.
Navegadores modernos têm a capacidade de verificar se essas restrições estão sendo observadas pelos usuários e podem alertá-los quando essas regras são violadas. Isso é conhecido como validação por restrições.
Validação no Cliente vs. Validação no Servidor
A maioria do código JavaScript escrito nos primeiros anos da linguagem lidava com a validação de formulários no cliente. Mesmo hoje, os desenvolvedores passam considerável tempo escrevendo funções para verificar os valores dos campos. Isso ainda é necessário em navegadores modernos? Provavelmente não. Na maioria dos casos, realmente depende do que você está tentando fazer.
Mas primeiro, aqui está uma grande mensagem de aviso:
A validação no cliente é uma conveniência que pode impedir erros comuns de entrada de dados antes que um aplicativo perca tempo e largura de banda enviando dados para um servidor. Não é um substituto para a validação no servidor!
Sempre sanitize os dados no lado do servidor. Nem todas as requisições virão de um navegador. Mesmo quando o fazem, não há garantia de que o navegador validou os dados. Qualquer pessoa que saiba como abrir as ferramentas do desenvolvedor do navegador também pode contornar seu cuidadosamente elaborado HTML e JavaScript.
Campos de Entrada HTML5
O HTML oferece:
<textarea>
para caixas de texto multilinha<select>
para uma lista suspensa de opções<button>
para … botões
Mas você usará <input>
mais frequentemente:
<input type="text" name="username" />
O atributo type
define o tipo de controle, e há uma grande variedade de opções:
type |
description |
---|---|
button |
a button with no default behavior |
checkbox |
a check/tick box |
color |
a color picker |
date |
a date picker for the year, month, and day |
datetime-local |
a date and time picker |
email |
an email entry field |
file |
a file picker |
hidden |
a hidden field |
image |
a button which displays the image defined by the src attribute |
month |
a month and year picker |
number |
a number entry field |
password |
a password entry field with obscured text |
radio |
a radio button |
range |
a slider control |
reset |
a button that resets all form inputs to their default values (but avoid using this, as it’s rarely useful) |
search |
a search entry field |
submit |
a form submission button |
tel |
a telephone number entry field |
text |
a text entry field |
time |
a time picker with no time zone |
url |
a URL entry field |
week |
a week number and year picker |
O navegador recua para text
se você omitir o atributo type
ou se não suportar uma opção. Navegadores modernos têm suporte adequado para todos os tipos, mas navegadores antigos ainda exibirão um campo de entrada de texto.
Outros atributos úteis de <input>
incluem:
attribute | description |
---|---|
accept |
file upload type |
alt |
alternative text for the image types |
autocomplete |
hint for field auto-completion |
autofocus |
focus field on page load |
capture |
media capture input method |
checked |
checkbox/radio is checked |
disabled |
disable the control (it won’t be validated or have its value submitted) |
form |
associate with a form using this ID |
formaction |
URL for submission on submit and image buttons |
inputmode |
data type hint |
list |
ID of <datalist> autocomplete options |
max |
maximum value |
maxlength |
maximum string length |
min |
minimum value |
minlength |
minimum string length |
name |
name of control, as submitted to server |
pattern |
a regular expression pattern, such as [A-Z]+ for one or more uppercase characters |
placeholder |
placeholder text when the field value is empty |
readonly |
the field is not editable, but it will still be validated and submitted |
required |
the field is required |
size |
the size of the control (often overridden in CSS) |
spellcheck |
set true or false spell-checking |
src |
image URL |
step |
incremental values in numbers and ranges |
type |
field type (see above) |
value |
the initial value |
Campos de Saída HTML
Além dos tipos de entrada, o HTML5 fornece saídas somente leitura:
output
: um resultado de texto de um cálculo ou ação do usuárioprogress
: uma barra de progresso com atributosvalue
emax
meter
: uma escala que pode mudar entre verde, âmbar e vermelho, dependendo dos valores definidos para os atributosvalue
,min
,max
,low
,high
eoptimum
.
Labels de Entrada
Os campos devem ter um <label>
associado, que você pode envolver em torno do elemento:
<label>your name <input type="text" name="name" /><label>
Ou vincule o campo pelo id
ao rótulo usando um atributo for
:
<label for="nameid">your name</label>
<input type="text" id="nameid" name="name" />
Os rótulos são importantes para acessibilidade. Você pode ter encontrado formulários que usam um placeholder
para economizar espaço na tela:
<input type="text" name="name" value="" placeholder="your name" />
O texto do espaço reservado desaparece assim que o usuário digita algo – mesmo um único espaço. É melhor mostrar um rótulo do que forçar o usuário a lembrar o que o campo queria!
Comportamentos de Entrada
Tipos de campo e atributos de restrição alteram o comportamento de entrada do navegador. Por exemplo, uma entrada number
mostra um teclado numérico em dispositivos móveis. O campo pode mostrar uma seta e os cliques de teclado para cima/para baixo incrementarão e decrementarão os valores.
A maioria dos tipos de campo é óbvia, mas existem exceções. Por exemplo, cartões de crédito são numéricos, mas o spinner de incremento/decremento é inútil e é muito fácil apertar para cima ou para baixo ao inserir um número de 16 dígitos. É melhor usar um tipo padrão text
, mas definir o atributo inputmode
como numeric
, o que mostra um teclado apropriado. Definir autocomplete="cc-number"
também sugere quaisquer cartões de crédito pré-configurados ou digitados anteriormente.
Usar o tipo de campo correto type
e autocorrect
oferece benefícios que seriam difíceis de alcançar em JavaScript. Por exemplo, alguns navegadores móveis podem:
- importar detalhes de cartão de crédito escaneando um cartão usando a câmera
- importar códigos de uso único enviados por SMS
Validação Automática
O navegador garante que o valor de entrada se adeque às restrições definidas pelos atributos type
, min
, max
, step
, minlength
, maxlength
, pattern
e required
. Por exemplo:
<input type="number" min="1" max="100" required />
Tentativa de enviar um valor vazio impede a submissão do formulário e mostra a seguinte mensagem no Chrome:
Os seletores não permitirão valores fora do intervalo de 1 a 100. Mensagens de validação semelhantes aparecem se você digitar uma string que não seja um número. Tudo isso sem uma única linha de JavaScript.
Você pode desativar a validação do navegador por:
- adicionando um atributo
novalidate
ao elemento<form>
- adicionando um atributo
formnovalidate
ao botão de envio ou imagem
Criando Entradas Personalizadas em JavaScript
Se você está escrevendo um novo componente de entrada de data baseado em JavaScript, pare e afaste-se do seu teclado!
Escrever controles de entrada personalizados é difícil. Você precisa considerar o mouse, teclado, toque, fala, acessibilidade, dimensões da tela e o que acontece quando o JavaScript falha. Você também está criando uma experiência de usuário diferente. Talvez seu controle seja superior ao seletor de datas padrão no desktop, iOS e Android, mas a UI desconhecida confundirá alguns usuários.
Há três razões principais pelas quais os desenvolvedores escolhem criar entradas baseadas em JavaScript.
1. Os controles padrão são difíceis de estilizar
O estilo CSS é limitado e geralmente requer hacks, como sobrepor uma entrada com os pseudo-elementos ::before
e ::after
do rótulo. A situação está melhorando, mas questione qualquer design que priorize a forma sobre a função.
2. Tipos modernos de <input>
não são suportados em navegadores antigos
Em essência, você está codificando para o Internet Explorer. Os usuários do IE não terão um seletor de datas, mas ainda podem inserir datas no formato AAAA-MM-DD
. Se seu cliente insistir, então carregue um polyfill apenas no IE. Não há necessidade de sobrecarregar navegadores modernos.
3. Você precisa de um novo tipo de entrada que nunca foi implementado antes
Essas situações são raras, mas sempre comece com campos apropriados do HTML5. Eles são rápidos e funcionam mesmo antes do script ser carregado. Você pode aprimorar progressivamente os campos conforme necessário. Por exemplo, uma pitada de JavaScript pode garantir que a data de término de um evento do calendário ocorra após a data de início.
Em resumo: evite reinventar controles HTML!
Estilo de Validação CSS
Você pode aplicar os seguintes pseudo-classes a campos de entrada para estilizá-los de acordo com o estado atual:
selector | description |
---|---|
:focus |
the field with focus |
:focus-within |
an element contains a field with focus (yes, it’s a parent selector!) |
:focus-visible |
an element has focus owing to keyboard navigation, so a focus ring or more evident styling is necessary |
:required |
a field with a required attribute |
:optional |
a field without a required attribute |
:valid |
a field that has passed validation |
:invalid |
a field that has not passed validation |
:user-valid |
a field that has passed validation after the user has interacted with it (Firefox only) |
:user-invalid |
a field that hasn’t passed validation after the user has interacted with it (Firefox only) |
:in-range |
the value is within range on a number or range input |
:out-of-range |
the value is out of range on a number or range input |
:disabled |
a field with a disabled attribute |
:enabled |
a field without a disabled attribute |
:read-only |
a field with a read-only attribute |
:read-write: |
a field without a read-only attribute |
:checked |
a checked checkbox or radio button |
:indeterminate |
an indeterminate checkbox or radio state, such as when all radio buttons are unchecked |
:default |
the default submit button or image |
Você pode estilizar o texto do placeholder
de uma entrada com o pseudo-elemento ::placeholder
:
/* texto de placeholder azul em campos de email */
input[type="email"]::placeholder {
color: blue;
}
Os seletores acima têm a mesma especificidade, então a ordem pode ser importante. Considere este exemplo:
input:invalid { color: red; }
input:enabled { color: black; }
Entradas inválidas têm texto vermelho, mas isso é aplicado apenas a entradas com um atributo disabled
— então todas as entradas habilitadas são pretas.
O navegador aplica estilos de validação na carga da página. Por exemplo, no código a seguir, cada campo inválido é dado um contorno vermelho:
:invalid {
border-color: #900;
}
O usuário enfrenta um conjunto assustador de caixas vermelhas antes de interagir com o formulário. Mostrar erros de validação após o primeiro envio ou conforme um valor é alterado ofereceria uma melhor experiência. É aí que entra o JavaScript…
JavaScript e a API de Validação de Restrições
A API de Validação de Restrições oferece opções de personalização de formulários que podem melhorar o verificação de campo HTML padrão. Você poderia:
- impedir a validação até que o usuário interaja com um campo ou envie o formulário
- mostrar mensagens de erro com estilo personalizado
- fornecer validação personalizada que é impossível apenas com HTML. Isso geralmente é necessário quando você precisa comparar duas entradas — como ao inserir um endereço de email ou um número de telefone, verificar se os campos “novo” e “confirmar” de senha têm o mesmo valor, ou garantir que uma data venha depois de outra.
Validação de Formulários
Antes de usar a API, seu código deve desabilitar a validação padrão e mensagens de erro definindo a propriedade noValidate
do formulário como true
(o mesmo que adicionar um atributo novalidate
):
const myform = document.getElementById('myform');
myform.noValidate = true;
Você pode então adicionar manipuladores de eventos — como quando o formulário é enviado:
myform.addEventListener('submit', validateForm);
O manipulador pode verificar se todo o formulário é válido usando os métodos checkValidity()
ou reportValidity()
, que retornam true
quando todos os inputs do formulário são válidos. (A diferença é que checkValidity()
verifica se algum input está sujeito à validação de restrições.)
Os documentos da Mozilla explicam:
Um evento
inválido
também é acionado em cada campo inválido. Isso não se propaga: os manipuladores devem ser adicionados a cada controle que o utiliza.
// validar formulário na submissão
function validateForm(e) {
const form = e.target;
if (form.checkValidity()) {
// formulário é válido - fazer verificações adicionais
}
else {
// formulário é inválido - cancelar envio
e.preventDefault();
}
};
A valid form could now incur further validation checks. Similarly, an invalid form could have invalid fields highlighted.
Validação de Campo
Campos individuais têm as seguintes propriedades de validação de restrição:
-
willValidate
: retornatrue
se o elemento for um candidato para validação de restrição. -
validationMessage
: a mensagem de validação. Isso será uma string vazia se o campo for válido. -
valitity
: um objeto ValidityState. Isso possui uma propriedadeválida
definida comoverdadeira
quando o campo é válido. Se forfalso
, uma ou mais das seguintes propriedades serãoverdadeiras
:ValidityState descrição .badInput
o navegador não consegue entender a entrada .customError
uma mensagem de validade personalizada foi definida .patternMismatch
o valor não corresponde ao atributo padrão
especificado.rangeOverflow
o valor é maior que o atributo máximo
.rangeUnderflow
o valor é menor que o atributo mínimo
.stepMismatch
o valor não se encaixa nas regras do atributo passo
.tooLong
o comprimento da string é maior que o atributo maxlength
.tooShort
o comprimento da string é menor que o atributo minlength
.typeMismatch
o valor não é um email ou URL válido .valueMissing
um valor obrigatório
está vazio
Os campos individuais possuem os seguintes métodos de validação de restrição:
setCustomValidity(message)
: define uma mensagem de erro para um campo inválido. Deve ser passado uma string vazia quando o campo é válido, caso contrário, o campo permanecerá inválido para sempre.checkValidity()
: retornatrue
quando a entrada é válida. A propriedadevalitity.valid
faz a mesma coisa, mascheckValidity()
também dispara um eventoinvalid
no campo, o que pode ser útil.
A função manipuladora validateForm()
pode percorrer todos os campos e aplicar uma classe invalid
ao elemento pai quando necessário:
function validateForm(e) {
const form = e.target;
if (form.checkValidity()) {
// o formulário é válido - faça verificações adicionais
}
else {
// o formulário é inválido - cancelar envio
e.preventDefault();
// aplicar classe inválida
Array.from(form.elements).forEach(i => {
if (i.checkValidity()) {
// campo é válido - remover classe
i.parentElement.classList.remove('invalid');
}
else {
// campo é inválido - adicionar classe
i.parentElement.classList.add('invalid');
}
});
}
};
Suponha que seu HTML definiu um campo de email:
<div>
<label for="email">email</label>
<input type="email" id="email" name="email" required />
<p class="help">Please enter a valid email address</p>
</div>
O script aplica uma classe invalid
ao <div>
quando o email não é especificado ou é inválido. O CSS pode mostrar ou ocultar a mensagem de validação quando o formulário é enviado:
.help { display: none; }
.invalid .help { display: block; }
.invalid label, .invalid input, .invalid .help {
color: red;
border-color: red;
}
Criando um Validador de Formulários Personalizado
A seguinte demonstração mostra um exemplo de formulário de contato que requer um nome de usuário e uma das opções: um endereço de email, um número de telefone, ou ambos:
Ele é implementado usando uma classe de validação de formulários genérica chamada FormValidate
. Um elemento de formulário é passado ao instanciar um objeto. Um segundo parâmetro opcional pode ser definido:
true
para validar cada campo à medida que o usuário interage com elefalse
(o padrão) para validar todos os campos após o primeiro envio (a validação de campo ocorre após isso)
// validar formulário de contato
const contactForm = new FormValidate(document.getElementById('contact'), false);
Um método .addCustom(field, func)
define funções de validação personalizadas. O código a seguir garante que os campos email
ou tel
sejam válidos (nenhum deles tem atributos required
):
// validação personalizada - email e/ou telefone
const
email = document.getElementById('email'),
tel = document.getElementById('tel');
contactForm.addCustom(email, f => f.value || tel.value);
contactForm.addCustom(tel, f => f.value || email.value);
A FormValidate
object monitors both of the following:
focusout
eventos, que então verificam um campo individual- eventos
submit
do formulário, que então verificam todos os campos
Ambos chamam o método .validateField(field)
, que verifica se um campo passa pela validação de restrição padrão. Quando isso acontece, qualquer função de validação personalizada atribuída a esse campo executa em seguida. Todas devem retornar true
para que o campo seja válido.
Campos inválidos têm uma classe invalid
aplicada ao elemento pai do campo, que exibe uma mensagem de ajuda vermelha usando CSS.
Por fim, o objeto chama uma função personalizada submit
quando todo o formulário é válido:
// submit personalizado
contactForm.submit = e => {
e.preventDefault();
alert('Form is valid!\n(open the console)');
const fd = new FormData(e.target);
for (const [name, value] of fd.entries()) {
console.log(name + ': ' + value);
}
}
Alternativamente, você pode usar um addEventListener
padrão para lidar com eventos submit
do formulário, uma vez que FormValidate
impede que outros manipuladores sejam executados quando o formulário é inválido.
Form Finesse
Formulários são a base de todos os aplicativos web e os desenvolvedores gastam considerável tempo manipulando a entrada do usuário. A validação de restrições é bem suportada: os navegadores podem lidar com a maioria dos testes e mostrar opções de entrada apropriadas.
Recomendações:
- Use os tipos de entrada HTML padrão sempre que possível. Defina os atributos
min
,max
,step
,minlength
,maxlength
,pattern
,required
,inputmode
eautocomplete
conforme apropriado. - Se necessário, use um pouco de JavaScript para habilitar validação personalizada e mensagens.
- Para campos mais complexos, aprimore progressivamente os inputs padrão.
Por fim: esqueça o Internet Explorer!
A menos que seus clientes sejam predominantemente usuários do IE, não há necessidade de implementar suas próprias funções de validação de fallback. Todos os campos de entrada HTML5 funcionam no IE, mas podem exigir mais esforço do usuário. (Por exemplo, o IE não detecta quando você insere um endereço de email inválido.) Você ainda precisa validar dados no servidor, então considere usar isso como base para verificação de erros no IE.
Perguntas Frequentes (FAQs) sobre Formulários HTML e Validação de Restrições
Qual é a importância da validação de formulários HTML?
A validação de formulários HTML é um aspecto crucial do desenvolvimento web. Isso garante que os dados inseridos pelos usuários em um formulário atendam a determinados critérios antes de serem enviados ao servidor. Isso não apenas mantém a integridade dos dados, mas também melhora a experiência do usuário ao fornecer feedback imediato sobre a correção dos dados inseridos. Sem validação de formulários, há risco de receber dados incorretos, incompletos ou mesmo mal-intencionados, o que pode levar a vários problemas, incluindo corrupção de dados, violações de segurança e falhas do sistema.
Como o HTML5 melhora a validação de formulários?
O HTML5 introduz vários novos elementos e atributos de formulário que tornam a validação de formulários muito mais fácil e eficiente. Por exemplo, fornece novos tipos de entrada, como email, URL e número, que validam automaticamente os dados de entrada com base no tipo. Também introduz novos atributos, como required, pattern e min/max, que permitem especificar várias restrições nos dados de entrada. Além disso, o HTML5 fornece uma API de validação integrada que permite realizar validação personalizada usando JavaScript.
Posso realizar a validação de formulários sem JavaScript?
Sim, você pode realizar validação básica de formulários usando apenas o HTML5. O HTML5 fornece vários novos tipos de entrada e atributos que permitem especificar várias restrições nos dados de entrada. Por exemplo, você pode usar o atributo required para tornar um campo obrigatório, o atributo pattern para impor um formato específico e os atributos min/max para definir uma faixa para entrada numérica. No entanto, para validação mais complexa, você ainda pode precisar usar JavaScript.
Como posso personalizar as mensagens de erro na validação de formulários HTML5?
O HTML5 fornece uma API de validação que permite personalizar as mensagens de erro. Você pode usar o método setCustomValidity do objeto ValidityState para definir uma mensagem de erro personalizada para um campo. Este método aceita um argumento de string, que se torna a mensagem de validação do campo quando o campo está inválido. Você pode chamar este método em resposta ao evento invalid, que é disparado quando um campo falha na validação.
Como posso desativar a validação de formulários HTML5?
Você pode desativar a validação de formulários HTML5 adicionando o atributo novalidate ao elemento form. Quando este atributo está presente, o navegador não realizará nenhuma validação no formulário quando ele for enviado. Isso pode ser útil se você quiser lidar com a validação inteiramente no lado do servidor ou usando JavaScript personalizado.
Como posso validar vários campos juntos no HTML5?
HTML5 não fornece uma maneira incorporada de validar vários campos juntos. No entanto, você pode alcançar isso usando JavaScript. Você pode escrever uma função de validação personalizada que verifica os valores de vários campos e define uma mensagem de validade personalizada se eles não atenderem aos critérios necessários. Você pode chamar essa função em resposta ao evento de envio do formulário ou aos eventos de entrada/mudança dos campos.
Como posso validar um campo com base no valor de outro campo em HTML5?
HTML5 não fornece uma maneira incorporada de validar um campo com base no valor de outro campo. No entanto, você pode alcançar isso usando JavaScript. Você pode escrever uma função de validação personalizada que verifica o valor de um campo contra o valor de outro campo e define uma mensagem de validade personalizada se eles não coincidirem. Você pode chamar essa função em resposta aos eventos de entrada/mudança dos campos.
Como posso realizar validação assíncrona em HTML5?
HTML5 não suporta validação assíncrona nativamente. No entanto, você pode alcançar isso usando JavaScript. Você pode escrever uma função de validação personalizada que realiza uma operação assíncrona, como uma solicitação AJAX, e define uma mensagem de validade personalizada com base no resultado. Você pode chamar essa função em resposta aos eventos de entrada/mudança dos campos ou ao evento de envio do formulário.
Como posso estilizar as mensagens de erro na validação de formulários HTML5?
A aparência das mensagens de erro na validação de formulários HTML5 é determinada pelo navegador e não pode ser diretamente estilizada usando CSS. No entanto, você pode criar mensagens de erro personalizadas usando JavaScript e estilizá-las como desejar. Você pode usar a API de validação para determinar quando um campo é inválido e exibir uma mensagem de erro personalizada de acordo.
Como posso testar a validação de um formulário HTML?
Você pode testar a validação de um formulário HTML inserindo vários tipos de dados nos campos e tentando enviar o formulário. Você deve testar com dados válidos e inválidos para garantir que a validação funcione corretamente em todos os casos. Você também pode usar ferramentas ou bibliotecas de teste automatizado para realizar testes mais abrangentes.
Source:
https://www.sitepoint.com/html-forms-constraint-validation-complete-guide/