Validação Avançada
A validação HTML5 nativa funciona automaticamente com o VanillaSmartSelect. O select original permanece
sincronizado, permitindo usar atributos padrão como required sem nenhum código adicional.
Formulário com Validação HTML5
Exemplo completo de formulário com campos obrigatórios e validação nativa do navegador.
Ver código
HTML
<form id="customForm">
<div>
<label for="department">Departamento: *</label>
<select id="department" required>
<option value="">Selecione...</option>
<option value="ti">TI</option>
<option value="rh">RH</option>
<option value="vendas">Vendas</option>
<option value="marketing">Marketing</option>
</select>
</div>
<div>
<label for="level">Nível: *</label>
<select id="level" required>
<option value="">Selecione...</option>
<option value="junior">Júnior</option>
<option value="pleno">Pleno</option>
<option value="senior">Sênior</option>
</select>
</div>
<div>
<label for="shift">Turno:</label>
<select id="shift">
<option value="">Selecione...</option>
<option value="morning">Manhã</option>
<option value="afternoon">Tarde</option>
<option value="night">Noite</option>
</select>
</div>
<button type="submit">Enviar</button>
</form>
JavaScript
// Inicializa os selects
new VanillaSmartSelect('#department', { searchable: true });
new VanillaSmartSelect('#level', { searchable: true });
new VanillaSmartSelect('#shift', { searchable: true });
// Validação customizada simples
const form = document.getElementById('customForm');
const resultDiv = document.getElementById('result');
form.addEventListener('submit', (e) => {
e.preventDefault();
if (form.checkValidity()) {
// Válido - processar
const formData = new FormData(form);
const data = Object.fromEntries(formData);
resultDiv.className = 'result success';
resultDiv.style.display = 'block';
resultDiv.style.background = '#d4edda';
resultDiv.style.border = '1px solid #28a745';
resultDiv.style.color = '#155724';
resultDiv.innerHTML = `
<strong>✓ Formulário Válido!</strong><br>
`;
console.log('Dados válidos:', data);
} else {
// Inválido - mostrar erro
form.reportValidity(); // Mensagem nativa do navegador
resultDiv.style.display = 'block';
resultDiv.style.background = '#f8d7da';
resultDiv.style.border = '1px solid #dc3545';
resultDiv.style.color = '#721c24';
resultDiv.innerHTML = '<strong>✗ Erro!</strong> Preencha todos os campos obrigatórios.';
}
});
Validação Customizada com API HTML5
Use a API de validação do HTML5 para definir regras e mensagens de erro customizadas.
Ver código
HTML
<form id="customValidationForm">
<div>
<label for="custom-validation">Selecione uma prioridade: *</label>
<select id="custom-validation" required>
<option value="">Selecione...</option>
<option value="low">Baixa</option>
<option value="medium">Média</option>
<option value="high">Alta</option>
<option value="critical">Crítica</option>
</select>
</div>
<button type="submit">Enviar</button>
<button type="button" id="checkValidityBtn">Verificar Validade</button>
<button type="button" id="showErrorBtn">Mostrar Mensagem</button>
</form>
JavaScript
const selectElement = document.querySelector('#custom-validation');
const select = new VanillaSmartSelect('#custom-validation');
// Validar quando o valor mudar
selectElement.addEventListener('change', () => {
const value = selectElement.value;
// Apenas "high" ou "critical" são válidos
if (value && value !== 'high' && value !== 'critical') {
selectElement.setCustomValidity('Apenas prioridades "Alta" ou "Crítica" são permitidas');
} else {
selectElement.setCustomValidity(''); // Limpa o erro
}
});
// Verificar validade programaticamente
document.getElementById('checkValidityBtn').addEventListener('click', () => {
if (selectElement.checkValidity()) {
console.log('✓ Campo válido!');
} else {
console.log('✗ Campo inválido!');
}
});
// Mostrar mensagem de validação
document.getElementById('showErrorBtn').addEventListener('click', () => {
selectElement.reportValidity(); // Mostra mensagem nativa do navegador
});
Validação de Dependência Entre Campos
Campo "Cidade" só pode ser selecionado após escolher um "Estado".
Ver código
HTML
<form id="dependencyForm">
<div>
<label for="state">Estado: *</label>
<select id="state" required>
<option value="">Selecione um estado...</option>
<option value="sp">São Paulo</option>
<option value="rj">Rio de Janeiro</option>
<option value="mg">Minas Gerais</option>
<option value="rs">Rio Grande do Sul</option>
</select>
</div>
<div>
<label for="city">Cidade: *</label>
<select id="city" required disabled>
<option value="">Selecione um estado primeiro...</option>
</select>
</div>
<button type="submit">Enviar</button>
</form>
JavaScript
// Inicializar selects
new VanillaSmartSelect('#state');
new VanillaSmartSelect('#city');
// Dados das cidades por estado
const citiesByState = {
sp: ['São Paulo', 'Campinas', 'Santos', 'Ribeirão Preto'],
rj: ['Rio de Janeiro', 'Niterói', 'Petrópolis', 'Cabo Frio'],
mg: ['Belo Horizonte', 'Uberlândia', 'Contagem', 'Juiz de Fora'],
rs: ['Porto Alegre', 'Caxias do Sul', 'Pelotas', 'Canoas']
};
const stateSelect = document.querySelector('#state');
const citySelect = document.querySelector('#city');
stateSelect.addEventListener('change', () => {
if (!stateSelect.value) {
citySelect.disabled = true;
citySelect.innerHTML = '<option value="">Selecione um estado primeiro...</option>';
citySelect.setCustomValidity('Selecione um estado primeiro');
} else {
citySelect.disabled = false;
citySelect.setCustomValidity('');
// Preencher cidades do estado selecionado
const cities = citiesByState[stateSelect.value];
citySelect.innerHTML = '<option value="">Selecione uma cidade...</option>' +
cities.map(city => `<option value="${city}">${city}</option>`).join('');
}
});
Validação Customizada com Regex
Validar se o código do produto segue um padrão específico (XXX-9999).
Ver código
HTML
<form id="regexForm">
<div>
<label for="product-code">Código do Produto: *</label>
<select id="product-code" required>
<option value="">Selecione um código...</option>
<option value="ABC-1234">ABC-1234 ✓</option>
<option value="XYZ-5678">XYZ-5678 ✓</option>
<option value="DEF-9012">DEF-9012 ✓</option>
<option value="INVALID">INVALID ✗</option>
<option value="123-ABC">123-ABC ✗</option>
<option value="AB-1234">AB-1234 ✗</option>
</select>
</div>
<button type="submit">Validar</button>
</form>
JavaScript
// Inicializar select
new VanillaSmartSelect('#product-code');
const codeSelect = document.querySelector('#product-code');
// Validar quando o valor mudar
codeSelect.addEventListener('change', () => {
const value = codeSelect.value;
const pattern = /^[A-Z]{3}-\d{4}$/; // Ex: ABC-1234
if (value && !pattern.test(value)) {
codeSelect.setCustomValidity('Código inválido. Use o formato: XXX-9999');
} else {
codeSelect.setCustomValidity('');
}
});
Como Funciona
📋 Princípios da Validação:
- Select Original Sincronizado: O VanillaSmartSelect mantém o select original sempre atualizado
- Atributo
required: Funciona nativamente sem código adicional - Borda Vermelha Automática: Feedback visual quando campo obrigatório está vazio
- form.checkValidity(): Valida todos os campos de uma vez
- form.reportValidity(): Mostra mensagens de erro nativas do navegador
Integração com Bibliotecas de Validação
Como o select original permanece sincronizado, você pode usar qualquer biblioteca de validação que trabalhe com o DOM:
| Biblioteca | Compatibilidade | Observação |
|---|---|---|
| HTML5 Validation | ✅ Total | Funciona nativamente, sem configuração |
| Vuelidate | ✅ Total | Acessa o select original diretamente |
| Yup | ✅ Total | Validação baseada em schema funciona perfeitamente |
| Joi | ✅ Total | Lê valores do FormData automaticamente |
| Zod | ✅ Total | TypeScript-first, funciona com DOM |
| jQuery Validation | ✅ Total | Valida o select original, não o wrapper |
✅ Por que funciona: O VanillaSmartSelect é um wrapper visual que mantém o
select HTML original no DOM e sempre sincronizado. Bibliotecas de validação podem acessar
e validar o select original normalmente.
Boas Práticas
📌 Recomendações:
- Use HTML5 Primeiro: Na maioria dos casos, validação nativa é suficiente
- Feedback Visual: Campos obrigatórios já mostram borda vermelha automaticamente
- Mensagens Claras: Use
setCustomValidity()para mensagens específicas - Valide no Submit: Sempre valide no evento submit do formulário
- Sincronização Garantida: O select original está sempre atualizado
- Escala Bem: Mesma abordagem funciona para 10 ou 100 campos