Trabalhando com formulários
Esta aula ensina como trabalhar com formulários HTML em JavaScript, cobrindo leitura de valores, validação, evento submit e a API FormData. O aluno aprenderá a capturar dados do usuário, validar campos e enviar formulários de forma eficiente.
Formulários são a principal forma de interação do usuário com uma aplicação web. Nesta aula, você aprenderá a manipular formulários usando JavaScript: desde a leitura de valores até a validação e envio assíncrono com a API FormData. Vamos explorar os conceitos fundamentais e boas práticas para criar formulários robustos e com boa experiência de usuário.
Dominar formulários é essencial para qualquer desenvolvedor front-end, pois eles estão presentes em cadastros, login, pesquisas e muito mais. Com JavaScript, podemos controlar cada etapa do fluxo: capturar dados, validar em tempo real, evitar envios inválidos e enviar dados sem recarregar a página.
Lendo valores
Para ler valores de um formulário, primeiro precisamos acessar os elementos do DOM. Existem várias formas: pelo ID do elemento, pelo name, ou percorrendo os elementos do formulário. O objeto document.forms contém todos os formulários da página, e cada formulário possui uma propriedade elements que é uma coleção dos campos.
Exemplo: suponha um formulário com campos de texto, select e checkbox. Vamos ler seus valores:
<form id="meuForm">
<input type="text" name="nome" id="nome" value="João">
<select name="cidade" id="cidade">
<option value="sp">São Paulo</option>
<option value="rj" selected>Rio de Janeiro</option>
</select>
<input type="checkbox" name="aceito" id="aceito" checked>
</form>
<script>
const form = document.getElementById('meuForm');
const nome = form.elements.nome.value; // "João"
const cidade = form.elements.cidade.value; // "rj"
const aceito = form.elements.aceito.checked; // true
console.log(nome, cidade, aceito);
</script>Para inputs do tipo radio, podemos iterar sobre os elementos com o mesmo name para encontrar o selecionado. Já para textarea e select múltiplo, a lógica é similar: use .value para o primeiro selecionado ou percorra as opções.
Validação
Validação de formulários pode ser feita tanto no lado do cliente quanto no servidor. No cliente, usamos JavaScript para verificar se os dados estão no formato esperado antes de enviar. Isso melhora a experiência do usuário, evitando recarregamentos desnecessários.
Existem duas abordagens principais: validação manual (com funções) e a API de validação do HTML5 (como required, pattern, minlength, etc.). Podemos combinar ambas. Exemplo de validação manual:
function validarFormulario() {
const form = document.getElementById('meuForm');
const nome = form.elements.nome.value.trim();
const email = form.elements.email.value.trim();
const erros = [];
if (nome.length < 3) {
erros.push('Nome deve ter pelo menos 3 caracteres.');
}
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(email)) {
erros.push('Email inválido.');
}
if (erros.length > 0) {
alert(erros.join('\n'));
return false;
}
return true;
}Também podemos usar a propriedade checkValidity() do elemento, que retorna true se o campo passar nas restrições HTML5. O objeto validity fornece detalhes sobre o erro (valueMissing, typeMismatch, etc.).
Evento submit
O evento submit é disparado quando o formulário é enviado. Podemos interceptá-lo para validar os dados, impedir o envio padrão (que recarrega a página) e, opcionalmente, enviar os dados via AJAX.
Para capturar o submit, adicionamos um listener ao formulário. Dentro do callback, chamamos event.preventDefault() para cancelar o envio tradicional. Exemplo:
const form = document.getElementById('meuForm');
form.addEventListener('submit', function(event) {
event.preventDefault(); // impede recarregamento
if (validarFormulario()) {
// Dados válidos - enviar via fetch ou AJAX
const dados = new FormData(form);
fetch('/api/cadastro', {
method: 'POST',
body: dados
})
.then(response => response.json())
.then(data => console.log('Sucesso:', data))
.catch(error => console.error('Erro:', error));
}
});É importante lembrar que a validação no cliente nunca substitui a validação no servidor, pois o JavaScript pode ser desabilitado ou manipulado. Sempre valide os dados no backend também.
FormData
A API FormData permite construir um conjunto de pares chave/valor representando os campos de um formulário. É muito útil para enviar dados via AJAX, especialmente quando o formulário contém arquivos (uploads).
Podemos criar um FormData a partir de um elemento form existente, ou manualmente adicionando campos. Exemplo:
// A partir de um formulário
const form = document.getElementById('meuForm');
const formData = new FormData(form);
// Adicionar campos extras
formData.append('token', 'abc123');
// Enviar com fetch
fetch('/api/upload', {
method: 'POST',
body: formData
});
// Ler valores do FormData
for (let [chave, valor] of formData.entries()) {
console.log(chave, valor);
}FormData também permite enviar arquivos: o campo <input type="file"> será incluído automaticamente. Para enviar apenas arquivos, podemos criar um FormData vazio e adicionar manualmente o arquivo obtido de um input file.
Boas práticas
- Use validação tanto no cliente quanto no servidor.
- Dê feedback visual imediato (cores, mensagens) para campos inválidos.
- Evite enviar formulários com dados inválidos; use
event.preventDefault(). - Prefira
FormDatapara formulários com arquivos ou muitos campos. - Desabilite o botão de submit após o envio para evitar duplicatas.
Referências
- MDN: HTMLFormElement
- MDN: FormData
- MDN: Validação de formulários
- MDN: Evento submit
- MDN: HTMLInputElement
- MDN: ValidityState
Exercícios
Crie um formulário HTML com campos nome (texto), email (email) e senha (password). Em JavaScript, ao submeter, valide se o nome tem pelo menos 3 caracteres, o email é válido e a senha tem no mínimo 6 caracteres. Exiba os erros em um alerta.
✓ Resposta:<form id="form1"> <input type="text" name="nome" placeholder="Nome"> <input type="email" name="email" placeholder="Email"> <input type="password" name="senha" placeholder="Senha"> <button type="submit">Enviar</button> </form> <script> document.getElementById('form1').addEventListener('submit', function(e) { e.preventDefault(); const nome = this.elements.nome.value.trim(); const email = this.elements.email.value.trim(); const senha = this.elements.senha.value.trim(); const erros = []; if (nome.length < 3) erros.push('Nome deve ter pelo menos 3 caracteres.'); if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) erros.push('Email inválido.'); if (senha.length < 6) erros.push('Senha deve ter no mínimo 6 caracteres.'); if (erros.length > 0) alert(erros.join('\n')); else alert('Dados válidos!'); }); </script>Usando a API de validação HTML5 (required, pattern, etc.), crie um formulário com campos nome (required), email (required, type email) e idade (required, min 18). Use JavaScript para exibir mensagens personalizadas de erro usando a propriedade
validationMessage.✓ Resposta:<form id="form2"> <input type="text" name="nome" required placeholder="Nome"> <input type="email" name="email" required placeholder="Email"> <input type="number" name="idade" required min="18" placeholder="Idade"> <button type="submit">Enviar</button> </form> <script> document.getElementById('form2').addEventListener('submit', function(e) { e.preventDefault(); const campos = this.elements; for (let campo of campos) { if (campo.type !== 'submit' && !campo.validity.valid) { alert(campo.validationMessage); return; } } alert('Formulário válido!'); }); </script>Intercepte o evento submit de um formulário e, em vez de enviar para o servidor, exiba os dados do formulário em um console.log usando FormData.
✓ Resposta:<form id="form3"> <input type="text" name="nome" value="Maria"> <input type="checkbox" name="newsletter" checked> <button type="submit">Enviar</button> </form> <script> document.getElementById('form3').addEventListener('submit', function(e) { e.preventDefault(); const data = new FormData(this); for (let [key, value] of data.entries()) { console.log(key + ': ' + value); } }); </script>Crie um formulário com um campo de arquivo (input type file). Ao submeter, use FormData para enviar o arquivo para uma URL fictícia via fetch. (Simule a resposta com um console.log).
✓ Resposta:<form id="form4"> <input type="file" name="arquivo"> <button type="submit">Enviar</button> </form> <script> document.getElementById('form4').addEventListener('submit', function(e) { e.preventDefault(); const formData = new FormData(this); fetch('https://exemplo.com/upload', { method: 'POST', body: formData }) .then(response => console.log('Arquivo enviado!')) .catch(error => console.error('Erro:', error)); }); </script>Escreva uma função que recebe um formulário e retorna um objeto JavaScript com os valores dos campos (incluindo checkboxes como booleanos e selects como valor). Teste com um formulário de exemplo.
✓ Resposta:function formToObject(form) { const data = new FormData(form); const obj = {}; for (let [key, value] of data.entries()) { obj[key] = value; } // Para checkboxes, ajusta para boolean const checkboxes = form.querySelectorAll('input[type="checkbox"]'); checkboxes.forEach(cb => { obj[cb.name] = cb.checked; }); return obj; } // Exemplo de uso: const form = document.getElementById('meuForm'); console.log(formToObject(form));