Documentation 12 min read

Advanced Form Validator

Published: April 21, 2025

Introdução

O Advanced Form Validator é uma biblioteca JavaScript robusta e extensível, projetada para simplificar e aprimorar a validação de formulários HTML em aplicações web. Construída sem dependências externas (Vanilla JS), ela oferece uma API flexível e um conjunto rico de funcionalidades para lidar com diversos cenários de validação, desde regras simples até validações assíncronas complexas e condicionais.

Principais funcionalidades do Advanced Form Validator:

  • Sistema de regras de validação altamente extensível (permite adicionar validadores síncronos e assíncronos personalizados).
  • Regras de validação condicionais baseadas nos dados do formulário.
  • Validação de grupos de campos (ex: grupos de checkboxes ou radio buttons).
  • Suporte avançado a internacionalização (i18n) com placeholders detalhados.
  • Estratégias flexíveis para exibição de erros (integradas e personalizáveis).
  • Acessibilidade aprimorada com atributos ARIA (aria-invalid, aria-describedby).
  • Validação em tempo real com debounce para otimizar performance em eventos de input/change.
  • API baseada em Promises para resultados de validação assíncronos.
  • Métodos abrangentes de ciclo de vida (init, destroy, reset).
  • Rastreamento detalhado do estado de validação de cada campo (valid, invalid, pending, unvalidated).

Características Principais

  • Sistema de Regras Extensível: Adicione facilmente suas próprias regras de validação síncronas ou assíncronas.
  • Validação Condicional: Defina condições para que regras específicas sejam aplicadas apenas quando necessário.
  • Validação de Grupos: Valide campos como grupos (ex: exigir um número mínimo de checkboxes marcados).
  • Internacionalização (i18n): Forneça mensagens de erro em múltiplos idiomas e personalize-as facilmente.
  • Exibição de Erros Flexível: Escolha como e onde os erros são exibidos (antes/depois do campo, dentro de um container) ou implemente sua própria lógica.
  • Acessibilidade (ARIA): Atualiza automaticamente atributos ARIA para indicar o estado de validação dos campos.
  • Validação em Tempo Real (Debounced): Valida campos enquanto o usuário digita (com debounce configurável) para feedback imediato sem sobrecarregar.
  • API Assíncrona (Promises): Os métodos de validação retornam Promises, facilitando a integração com fluxos assíncronos.
  • Manipulador de Submissão: Forneça uma função submitHandler personalizada para controlar o que acontece após a validação bem-sucedida.
  • Controle de Foco e Scroll: Opções para focar automaticamente no primeiro campo inválido e/ou rolar a página até ele após a submissão falhar.
  • Sem Dependências: Funciona puramente com JavaScript Vanilla.
  • Gerenciamento de Estado: Métodos para obter o estado de validação de campos individuais ou do formulário inteiro.

Instalação

Para usar o Advanced Form Validator, siga os passos abaixo:

1. Inclua o Script

Adicione o script JavaScript no seu HTML, preferencialmente antes do fechamento da tag </body>:

<script src="https://cdn.alphasystem.dev/plugins/advanced-form-validator/latest/script-min.js"></script>

(Nota: O script fornecido anteriormente já contém a biblioteca. Se estiver usando o HTML de teste, este passo já está coberto.)

2. Inicialize a Biblioteca

O Advanced Form Validator não inicializa automaticamente. Você precisa criar uma instância da classe AdvancedFormValidator, passando o elemento do formulário (ou seletor), a configuração de validação e, opcionalmente, um objeto de opções.

Inicialização Básica:

// Espera o DOM carregar
document.addEventListener('DOMContentLoaded', () => {
	const myForm = document.getElementById('meu-formulario');

	// Define as regras de validação
	const validationConfig = {
		nomeUsuario: [
			{ type: 'required', message: 'O nome de usuário é obrigatório.' },
			{ type: 'minLength', value: 5 }
		],
		email: [
			{ type: 'required' },
			{ type: 'email' }
		]
		honeypot: [
			{ type: 'honeypot' } // Campo deve ser vazio.
		]
		// ... outras regras para outros campos
	};

	// Cria a instância do validador
	const validator = new AdvancedFormValidator(myForm, validationConfig);

	console.log('Validador inicializado!');
});

Inicialização com Opções:

document.addEventListener('DOMContentLoaded', () => {
	const myForm = '#meu-formulario'; // Pode usar seletor CSS

	const validationConfig = {
		// ... regras ...
	};

	const validatorOptions = {
		validateOnInput: true, // Validar enquanto digita
		inputDebounce: 400,   // Atraso para validação no input
		containerSelector: '.form-group', // Onde exibir erros
		submitHandler: (form, event, validatorInstance) => {
			console.log('Formulário válido! Enviando dados...');
			// Lógica de envio customizada aqui
			// Ex: Enviar dados via fetch/axios
			// form.submit(); // Para submissão padrão (se necessário)
		},
		defaultLanguage: 'pt-br', // Definir idioma padrão
		i18n: {
			'pt-br': { // Sobrescrever ou adicionar mensagens pt-br
				required: 'Este campo não pode ficar vazio.',
				email: 'Por favor, insira um e-mail válido.'
			}
		}
	};

	const validator = new AdvancedFormValidator(myForm, validationConfig, validatorOptions);
});

Configuração

O Advanced Form Validator é configurado principalmente através do construtor new AdvancedFormValidator(formElementOrSelector, config, options).

  1. formElementOrSelector: (HTMLFormElement | String) O elemento form a ser validado ou um seletor CSS para encontrá-lo.
  2. config: (Object | Array) A configuração das regras de validação. Pode ser:
    • Um objeto onde as chaves são os nomes (name ou id) dos campos e os valores são arrays de objetos de regra (ValidatorRuleInstance).
    • Um array de objetos no formato { field: 'fieldName', rules: [ruleInstance1, ...] }.
  3. options: (Object, opcional) Um objeto para personalizar o comportamento do validador. As principais opções são:
    • errorClass: (String) Classe CSS para o elemento que exibe a mensagem de erro. Padrão: 'validator-error'.
    • errorFieldClass: (String) Classe CSS adicionada ao campo inválido (ou ao container, dependendo do campo). Padrão: 'field-error'.
    • validFieldClass: (String) Classe CSS adicionada ao campo válido (ou container). Padrão: 'field-valid'.
    • pendingFieldClass: (String) Classe CSS adicionada durante validação assíncrona. Padrão: 'field-pending'.
    • errorElementTag: (String) Tag HTML para o elemento de erro. Padrão: 'div'.
    • containerSelector: (String | null) Seletor CSS (relativo ao campo) para encontrar o container onde o erro deve ser exibido e as classes de estado aplicadas (ex: '.form-group'). Se null, usa o parentElement do campo. Padrão: null.
    • errorDisplayStrategy: (String | Function) Como exibir o erro: 'afterField' (padrão), 'beforeField', 'appendToContainer', ou uma função customizada.
    • validateOnInit: (Boolean) Validar o formulário imediatamente na inicialização. Padrão: false.
    • validateOnInput: (Boolean) Habilitar validação em tempo real nos eventos input ou change. Padrão: true.
    • inputDebounce: (Number) Atraso (ms) para a validação em tempo real. Padrão: 350.
    • focusOnError: (Boolean) Focar no primeiro campo inválido após tentativa de submissão. Padrão: true.
    • scrollOnError: (Boolean | String) Rolar até o primeiro campo inválido. Pode ser true (comportamento padrão do scrollIntoView), 'smooth', 'auto', ou false. Padrão: true.
    • scrollOptions: (Object) Opções passadas para element.scrollIntoView(). Padrão: { behavior: 'smooth', block: 'center' }.
    • submitHandler: (Function | null) Callback (form, event, validatorInstance) chamado se a validação for bem-sucedida na submissão. Se definido, previne a submissão padrão do formulário. Padrão: null.
    • i18n: (Object) Objeto para sobrescrever ou adicionar pacotes de idiomas. Formato: { langCode: { ruleType: message, ... }, ... }. Padrão: {}.
    • defaultLanguage: (String) Código do idioma padrão a ser usado das mensagens. Padrão: 'en'.

Estrutura de uma Regra (ValidatorRuleInstance)

{
	type: 'required', // Nome da regra (string, obrigatório)
	value: 5,         // Parâmetro da regra (opcional, depende da regra, ex: minLength)
	message: 'Mínimo de {value} caracteres necessários.', // Mensagem customizada (opcional)
	condition: (formData, validator) => formData.campoX === 'valorY', // Função condicional (opcional)
	details: 'detalhes extras' // Detalhes para placeholders como {details} (opcional)
}

Uso e Integração

Após configurar e instanciar o validador, ele funcionará automaticamente com base nas opções.

Definindo Regras

A parte mais importante é definir o objeto config corretamente, mapeando os nomes dos campos (atributo name ou id) para um array de regras a serem aplicadas.

const validationConfig = {
	// Campo 'username' (pode ser ID ou Name)
	username: [
		{ type: 'required' }, // Regra obrigatória
		{ type: 'minLength', value: 3, message: 'Usuário muito curto (mínimo {value}).' },
		{ type: 'maxLength', value: 20 }
	],
	// Campo 'email'
	email: [
		{ type: 'required' },
		{ type: 'email' }
	],
	// Campo 'idade' com condição
	idade: [
		{ type: 'required' },
		{ type: 'integer' },
		{
			type: 'min',
			value: 18,
			// Só aplica a regra 'min' se o checkbox 'aceitaTermos' estiver marcado
			condition: (formData) => formData.aceitaTermos === true
		}
	],
	// Grupo de checkboxes 'interesses' (usar o 'name' do grupo)
	interesses: [
		{ type: 'groupRequired', value: 2, message: 'Selecione ao menos {value} interesses.' }
	],
	// Senha e confirmação
	senha: [
		{ type: 'required' },
		{ type: 'passwordStrength', value: 4 } // Nível de força
	],
	confirmarSenha: [
		{ type: 'required' },
		{ type: 'match', value: 'senha' } // Deve corresponder ao campo 'senha'
	]
};

Regras Pré-Definidas

O Advanced Form Validator vem com um conjunto abrangente de regras de validação pré-definidas, que você pode utilizar diretamente ou customizar conforme necessário. Segue uma breve descrição de cada regra incorporada:

required:
Garante que o campo não esteja vazio. Essa regra é aplicada mesmo quando o valor não está presente, forçando o usuário a preencher o campo.

email:
Verifica se o valor informado corresponde a um formato válido de e-mail.

minLength:
Assegura que o número de caracteres do valor seja, no mínimo, o especificado (por exemplo, { type: 'minLength', value: 5 }).

maxLength:
Garante que o número de caracteres do valor não exceda o limite especificado.

pattern:
Valida o valor contra uma expressão regular (RegExp) fornecida.

number:
Confirma se o valor informado é um número válido, permitndo casas decimais.

integer:
Verifica se o valor é um número inteiro.

range:
Valida se um valor numérico está dentro de um intervalo especificado (com parâmetros min e max).

min:
Exige que o valor numérico seja maior ou igual ao valor configurado.

max:
Exige que o valor numérico seja menor ou igual ao valor configurado.

url:
Valida se o valor corresponde a um formato válido de URL.

match:
Compara o valor de um campo com o de outro campo, geralmente usado para confirmação (ex: senha e confirmar senha).

checked:
Geralmente utilizada para checkboxes, certifica-se de que o campo esteja marcado.

groupRequired:
Valida grupos de campos (como múltiplos checkboxes) para assegurar que pelo menos um número mínimo de opções esteja selecionado.

passwordStrength:
Avalia a força de uma senha com base em critérios como tamanho, letras minúsculas, letras maiúsculas, números e caracteres especiais. Pode receber um parâmetro que indique o nível mínimo de força exigido.

honeypot:
A nova regra honeypot foi adicionada para combater bots automatizados. Ela garante que o campo designado permaneça vazio. Se o campo for preenchido, a validação falhará, sinalizando uma possível tentativa de spam.

Você pode usar estas regras diretamente na configuração ao instanciar o validador. Além disso, novas regras customizadas podem ser adicionadas utilizando o método addRule.

Validação na Submissão

A validação ocorre automaticamente quando o formulário é submetido.

  • Se válido e submitHandler não for definido, o formulário é submetido normalmente.
  • Se válido e submitHandler for definido, a função submitHandler é chamada, e a submissão padrão é prevenida.
  • Se inválido, a submissão é prevenida, os erros são exibidos, e o foco/scroll (se habilitados) são acionados.

Validação em Tempo Real

Se validateOnInput: true, os campos serão validados enquanto o usuário interage (eventos input ou change, com debounce).

Adicionando Regras Customizadas

Use o método addRule para definir novas regras.

// Adiciona uma regra síncrona customizada
validator.addRule({
	type: 'startsWithA', // Nome da nova regra
	validateSync: (value, element, param) => {
		if (!value) return true; // Permite vazio (a menos que 'required' seja usado)
		return String(value).toLowerCase().startsWith('a');
	},
	defaultMessage: 'O valor deve começar com a letra A.'
});

// Adiciona uma regra assíncrona customizada (ex: verificar disponibilidade de username)
validator.addRule({
	type: 'usernameAvailable',
	validateAsync: async (value, element, param) => {
		if (!value) return true;
		try {
			const response = await fetch(`/api/check-username?username=${encodeURIComponent(value)}`);
			const data = await response.json();
			return data.isAvailable; // API deve retornar { isAvailable: true/false }
		} catch (error) {
			console.error('Erro na validação assíncrona:', error);
			return false; // Falha na validação se a API falhar
		}
	},
	defaultMessage: 'Este nome de usuário já está em uso.'
});

// Agora você pode usar 'startsWithA' e 'usernameAvailable' na sua config:
const newConfig = {
	apelido: [ { type: 'startsWithA' } ],
	novoUsuario: [ { type: 'required' }, { type: 'usernameAvailable' } ]
};

Nota: Para adicionar regras a uma instância existente, você precisaria recriar a instância ou ter um método para atualizar a config (não padrão). É melhor definir regras customizadas antes de instanciar.

Resetando a Validação

Para limpar os erros e o estado de validação (sem limpar os valores dos campos):

validator.reset();

Para limpar também os valores dos campos, use o reset nativo do formulário junto:

myFormElement.reset(); // Limpa valores
validator.reset();     // Limpa estado de validação

Destruindo a Instância

Para remover todos os event listeners e limpar o estado:

validator.destroy();

Referência da API

Construtor

  • new AdvancedFormValidator(formElementOrSelector, config, options?): Cria uma nova instância do validador.
    • Parâmetros:
      • formElementOrSelector (HTMLFormElement | String): O formulário ou seletor.
      • config (Object | Array): Configuração das regras.
      • options (Object, opcional): Opções de personalização.
    • Retorna: Instância de AdvancedFormValidator.

Métodos Principais

  • validate(): Valida o formulário inteiro manualmente.
    • Retorna: Promise<boolean> - Resolve para true se válido, false caso contrário.
  • validateField(fieldName): Valida um campo específico manualmente.
    • Parâmetros:
      • fieldName (String): O name ou id do campo.
    • Retorna: Promise<boolean> - Resolve para true se válido, false caso contrário.
  • addRule(ruleDefinition): Adiciona uma definição de regra customizada.
    • Parâmetros:
      • ruleDefinition (Object): Objeto definindo a regra (type, validateSync/validateAsync, defaultMessage, etc.).
    • Retorna: void.
  • reset(): Limpa todos os erros, classes de estado e redefine o status dos campos para 'unvalidated'. Não limpa os valores dos campos.
    • Retorna: void.
  • destroy(): Remove event listeners, limpa erros e redefine o estado interno. Torna a instância inativa.
    • Retorna: void.
  • getFormData(): Obtém os dados atuais do formulário como um objeto chave-valor. Lida com checkboxes e selects múltiplos.
    • Retorna: Object.
  • getErrors(): Retorna um objeto com os erros de validação atuais.
    • Retorna: Object.<string, string> - Mapeamento de fieldName para errorMessage.
  • getFieldStatus(fieldName): Retorna o status de validação atual de um campo.
    • Parâmetros:
      • fieldName (String): O nome do campo.
    • Retorna: 'valid' | 'invalid' | 'pending' | 'unvalidated'.
  • getAllFieldStatuses(): Retorna um objeto com o status de todos os campos configurados.
    • Retorna: Object.<string, ('valid' | 'invalid' | 'pending' | 'unvalidated')>.
  • isValid(): Verifica se o formulário é considerado válido com base no último estado de validação.
    • Retorna: boolean.
  • isFieldValid(fieldName): Verifica se um campo específico é considerado válido.
    • Parâmetros:
      • fieldName (String): O nome do campo.
    • Retorna: boolean.
  • setLanguage(langCode): Altera o idioma atual para as mensagens de erro.
    • Parâmetros:
      • langCode (String): O código do idioma (ex: 'en', 'pt-br') que deve existir nas mensagens configuradas (DEFAULT_MESSAGES ou options.i18n).
    • Retorna: void.

Propriedades (Acesso via Métodos Recomendado)

  • errors: Objeto interno de erros (use getErrors()).
  • fieldStatus: Objeto interno de status (use getFieldStatus() / getAllFieldStatuses()).
  • options: Objeto de opções usado pela instância.
  • messages: Objeto de mensagens de erro (combinado de padrões e i18n).
  • currentLang: Código do idioma atual.

Resolução de Problemas

  • AdvancedFormValidator is not defined: Verifique se o script foi incluído corretamente no HTML antes de tentar usar new AdvancedFormValidator(...).
  • Validação não funciona / Erros não aparecem:
    • Confira se o seletor do formulário está correto.
    • Verifique se os nomes/IDs dos campos na config correspondem exatamente aos atributos name ou id dos elementos HTML.
    • Confirme se as regras estão definidas corretamente (type existe, value fornecido se requiresParam: true).
    • Verifique se o containerSelector (se usado) está correto e se os elementos container existem.
    • Inspecione o console do navegador por erros de JavaScript.
    • Verifique se as classes CSS (errorClass, errorFieldClass) estão definidas no seu CSS para que os erros sejam visualmente aparentes.
  • Validação assíncrona (async) não funciona:
    • Certifique-se de que a regra asyncValidator retorna uma Promise que resolve para true ou false.
    • Verifique a rede (Network tab) e o console por erros na requisição (se aplicável).
    • A classe field-pending deve ser estilizada se desejar feedback visual durante a espera.
  • submitHandler não é chamado:
    • O submitHandler só é chamado se a validação for 100% bem-sucedida. Verifique se há erros ocultos usando validator.getErrors() ou inspecionando o console.
  • Validação em tempo real (validateOnInput) muito lenta/rápida:
    • Ajuste a opção inputDebounce (valor maior = menos validações, valor menor = mais rápido).
  • Mensagens de erro não mudam com setLanguage:
    • Verifique se o langCode passado existe no objeto messages da instância (seja nos padrões ou no options.i18n).
    • Após mudar o idioma, pode ser necessário revalidar o formulário (validator.validate()) ou os campos individuais para que as mensagens de erro sejam atualizadas na UI, se já estiverem visíveis.