Como formatar campos de formulário automaticamente

Aprenda a formatar dados dos campos de formulário com JavaScript

22/04/2024

Como formatar campos de formulário automaticamente

Como formatar campos de formulário automaticamente

Introdução

Formulários online desempenham um papel crucial em numerosas aplicações digitais, coletando informações essenciais de usuários. No entanto, dados incorretos ou mal formatados podem levar a erros significativos e a ineficiências operacionais. Este artigo foca em solucionar esse problema ao demonstrar como implementar a formatação automática de dados diretamente nos campos de entrada de um formulário.

Utilizando HTML e JavaScript, exploraremos técnicas para garantir que entradas como CPF, CNPJ, números de telefone, placas de carro, CEPs, cartões de crédito, datas de nascimento e horários sejam não apenas validadas mas também corretamente formatadas no momento da digitação. Este método assegura a consistência e a exatidão dos dados coletados, fundamentais para o processamento e análise subsequentes.

Código Pronto para Uso

Este exemplo de formulário inclui campos diversos, cada um com um atributo data-format especificando como os dados devem ser formatados. O JavaScript em anexo manipula a formatação em tempo real enquanto o usuário digita, assegurando que cada entrada adere ao formato pré-definido. Segue abaixo o formulário completo e o script necessário para a formatação automática.

O atributo data-format define o padrão de formatação para cada campo de entrada, utilizando marcadores específicos onde '9' representa um dígito e 'X' uma letra. Por exemplo, o formato '999.999.999-99' é utilizado para CPFs, indicando que os números devem ser inseridos com pontos e traço nas posições especificadas. Para campos que podem necessitar de mais de um formato, como números de telefone que variam em comprimento, o atributo data-alt-format pode ser utilizado para definir um formato alternativo. Isso permite que o script alterne entre os formatos com base no conteúdo digitado pelo usuário, garantindo que a entrada seja formatada corretamente independentemente da variação dos dados.

<form>
  <div>
    <label for="cpf">CPF:</label>
    <input type="text" id="cpf" data-format="999.999.999-99" placeholder="Digite seu CPF">
  </div>

  <div>
    <label for="cnpj">CNPJ:</label>
    <input type="text" id="cnpj" data-format="99.999.999/9999-99" placeholder="Digite seu CNPJ">
  </div>

  <div>
    <label for="phone">Telefone:</label>
    <input type="text" id="phone" data-format="(99) 9999-9999" data-alt-format="(99) 99999-9999" placeholder="Digite seu telefone">
  </div>

  <div>
    <label for="plate">Placa de Carro:</label>
    <input type="text" id="plate" data-format="XXX-9999" data-alt-format="XXX9X99" placeholder="Digite a placa do carro">
  </div>

  <div>
    <label for="cep">CEP:</label>
    <input type="text" id="cep" data-format="99999-999" placeholder="Digite seu CEP">
  </div>

  <div>
    <label for="cc">Cartão de Crédito:</label>
    <input type="text" id="cc" data-format="9999 9999 9999 9999" placeholder="Número do Cartão">
  </div>

  <div>
    <label for="date">Data de Nascimento:</label>
    <input type="text" id="date" data-format="99/99/9999" placeholder="Digite sua data de nascimento">
  </div>

  <div>
    <label for="time">Hora:</label>
    <input type="text" id="time" data-format="99:99" placeholder="Digite a hora">
  </div>

  <div>
    <input type="submit" value="Enviar">
  </div>
</form>

document.querySelectorAll('input[data-format]').forEach(input => {
  input.addEventListener('input', function(e) {
    let primaryFormat = this.getAttribute('data-format');
    let altFormat = this.getAttribute('data-alt-format');
    let rawValue = this.value;
    let value = rawValue.replace(/[^a-zA-Z0-9]/g, ''); // Remove caracteres que não são letras ou números

    // Aplica os formatos
    let formattedPrimary = applyFormat(value, primaryFormat);
    let formattedAlt = altFormat ? applyFormat(value, altFormat) : '';

    // Escolhe o melhor formato baseado na entrada
    this.value = determineBestFormat(value, formattedPrimary, formattedAlt, primaryFormat, altFormat);
  });
});

function applyFormat(value, format) {
  let finalValue = '';
  let index = 0;
  for (let i = 0; i < format.length && index < value.length; i++) {
    if ((format[i] === '9' && /\d/.test(value[index])) || (format[i] === 'X' && /[a-zA-Z]/.test(value[index]))) {
      finalValue += value[index].toUpperCase(); // Converte letras para maiúsculas
      index++;
    } else if (format[i] !== '9' and format[i] !== 'X') {
      finalValue += format[i]; // Adiciona o caractere de formatação
    } else {
      break; // Interrompe a formatação se o caractere não corresponder ao esperado na posição
    }
  }
  return finalValue;
}

function determineBestFormat(value, primary, alternate, primaryFormat, alternateFormat) {
  let primaryConsumption = primary.replace(/[^0-9A-Z]/g, '').length;
  let alternateConsumption = alternate.replace(/[^0-9A-Z]/g, '').length;
  let valueLength = value.length;

  // Preferir o formato que mais se aproxima de utilizar todos os caracteres digitados
  if (alternate && alternateConsumption > primaryConsumption && alternateConsumption == valueLength) {
    return alternate;
  } else if (primaryConsumption == valueLength) {
    return primary;
  }

  return primaryConsumption >= alternateConsumption ? primary : alternate;
}

Explicando o Código

Na próxima seção, detalharemos o código utilizado para formatar dinamicamente os campos do formulário. Vamos dividir a explicação em partes para facilitar o entendimento de cada função específica do script e como elas interagem para manter a integridade e a precisão dos dados inseridos pelos usuários.

Estrutura do Formulário

O formulário apresentado inclui uma série de campos de entrada, cada um dedicado a capturar um tipo específico de dado. Os campos são marcados com um atributo data-format, que especifica o formato desejado para os dados inseridos. Este atributo é crucial para o script de JavaScript, que lê essas especificações para aplicar a formatação correta enquanto o usuário digita.

<form>
  <div>
    <label for="cpf">CPF:</label>
    <input type="text" id="cpf" data-format="999.999.999-99" placeholder="Digite seu CPF">
  </div>
  <div>
    <label for="cnpj">CNPJ:</label>
    <input type="text" id="cnpj" data-format="99.999.999/9999-99" placeholder="Digite seu CNPJ">
  </div>
  <div>
    <label for="phone">Telefone:</label>
    <input type="text" id="phone" data-format="(99) 9999-9999" data-alt-format="(99) 99999-9999" placeholder="Digite seu telefone">
  </div>
  <div>
    <label for="plate">Placa de Carro:</label>
    <input type="text" id="plate" data-format="XXX-9999" data-alt-format="XXX9X99" placeholder="Digite a placa do carro">
  </div>
  <div>
    <label for="cep">CEP:</label>
    <input type="text" id="cep" data-format="99999-999" placeholder="Digite seu CEP">
  </div>
  <div>
    <label for="cc">Cartão de Crédito:</label>
    <input type="text" id="cc" data-format="9999 9999 9999 9999" placeholder="Número do Cartão">
  </div>
  <div>
    <label for="date">Data de Nascimento:</label>
    <input type="text" id="date" data-format="99/99/9999" placeholder="Digite sua data de nascimento">
  </div>
  <div>
    <label for="time">Hora:</label>
    <input type="text" id="time" data-format="99:99" placeholder="Digite a hora">
  </div>
  <div>
    <input type="submit" value="Enviar">
  </div>
</form>

Este segmento de código HTML configura cada campo de entrada com um rótulo associado e especificações claras de formato, garantindo que o usuário tenha orientações visuais sobre como os dados devem ser inseridos.

Interceptação e Processamento da Entrada do Usuário

Para começar a manipulação dos dados de entrada em tempo real, utilizamos o método querySelectorAll para selecionar todos os elementos de entrada que possuem um atributo data-format. Em seguida, adicionamos um ouvinte de eventos que responde a cada entrada do usuário:


document.querySelectorAll('input[data-format]').forEach(input => {
  input.addEventListener('input', function(e) {
    let primaryFormat = this.getAttribute('data-format');
    let altFormat = this.getAttribute('data-alt-format');
    let rawValue = this.value;
    let value = rawValue.replace(/[^a-zA-Z0-9]/g, ''); // Remove caracteres que não são letras ou números

    // Aplica os formatos
    let formattedPrimary = applyFormat(value, primaryFormat);
    let formattedAlt = altFormat ? applyFormat(value, altFormat) : '';

    // Escolhe o melhor formato baseado na entrada
    this.value = determineBestFormat(value, formattedPrimary, formattedAlt, primaryFormat, altFormat);
  });
});

Este bloco de código está encarregado de ouvir mudanças em qualquer campo de entrada especificado, limpar caracteres não alfanuméricos e aplicar o formato adequado. O atributo data-format define o formato primário enquanto data-alt-format pode especificar um formato alternativo, possibilitando adaptabilidade conforme a entrada do usuário.

Função applyFormat

A função applyFormat é chamada para cada mudança de entrada e é responsável por aplicar a máscara de formatação especificada:

function applyFormat(value, format) {
  let finalValue = '';
  let index = 0;
  for (let i = 0; i < format.length && index < value.length; i++) {
    if ((format[i] === '9' && /\d/.test(value[index])) || (format[i] === 'X' && /[a-zA-Z]/.test(value[index]))) {
      finalValue += value[index].toUpperCase(); // Converte letras para maiúsculas
      index++;
    } else if (format[i] !== '9' and format[i] !== 'X') {
      finalValue += format[i]; // Adiciona o caractere de formatação
    } else {
      break; // Interrompe a formatação se o caractere não corresponder ao esperado na posição
    }
  }
  return finalValue;
}

Esta função itera sobre o formato definido, verificando cada caractere de entrada contra o padrão esperado ('9' para números, 'X' para letras). Letras são convertidas para maiúsculas conforme necessário, e a formatação é interrompida se um caractere inesperado é encontrado, garantindo que a entrada mantenha o padrão definido.

Função determineBestFormat

A função determineBestFormat analisa as versões formatadas dos dados (primária e alternativa) e escolhe a que melhor se ajusta ao número total de caracteres inseridos pelo usuário. Essa decisão é crucial para garantir que o formato final seja o mais adequado possível, oferecendo uma experiência de usuário coerente e precisa:

function determineBestFormat(value, primary, alternate, primaryFormat, alternateFormat) {
  let primaryConsumption = primary.replace(/[^0-9A-Z]/g, '').length;
  let alternateConsumption = alternate.replace(/[^0-9A-Z]/g, '').length;
  let valueLength = value.length;

  // Preferir o formato que mais se aproxima de utilizar todos os caracteres digitados
  if (alternate && alternateConsumption > primaryConsumption && alternateConsumption == valueLength) {
    return alternate;
  } else if (primaryConsumption == valueLength) {
    return primary;
  }

  return primaryConsumption >= alternateConsumption ? primary : alternate;
}

Esta função compara o número de caracteres alfanuméricos utilizados em cada formato formatado contra o número total de caracteres digitados. Ela opta pelo formato alternativo se este formatar mais caracteres e todos os caracteres digitados forem utilizados, caso contrário, ela opta pelo formato primário. Essa lógica ajuda a escolher o formato mais preciso em situações como a entrada de números de telefone, onde o número de dígitos pode variar.

Conclusão

Implementar a formatação dinâmica em formulários web é essencial para assegurar a precisão dos dados coletados e oferecer uma melhor experiência ao usuário. Este artigo demonstrou como utilizar HTML e JavaScript para criar um sistema robusto formata informações de entrada em tempo real. Ao aplicar os métodos descritos, desenvolvedores podem evitar erros comuns de entrada de dados e melhorar significativamente a eficiência de processos que dependem de dados precisos e bem formatados.

Esperamos que este artigo tenha sido útil para você melhorar a formatação de dados em seus próprios projetos. Sempre que precisar de hospedagem, seja para seu site ou para sua aplicação web, lembre-se da MCO2. Conheça nossos planos de hospedagem.

Domínios hospedados
Clientes satisfeitos