4
respostas

[Dúvida] Problema com CPFs que recebem hiféns se o campo de CPF for type="number"

No curso, é passado o código a seguir:

export default function validaCPF(campo){
    const cpf = campo.value.replace(/\.|-|-/g,"");

    if( validaNumerosRepetidos(cpf) || validaPrimeiroDigito(cpf) || validaSegundoDigito(cpf)){
            console.log('Esse CPF não existe');            
      }else{
        console.log('Esse CPF existe');
      }
}

Ele captura o valor do campo de CPF que, está como "type" number, e aplica um replace para deixar o valor sem pontos ou hiféns. Porém, há um problema caso haja um hífen no valor do input. Logo abaixo da declaração da constante "Cpf" eu adicionei uma linha com console.log(cpf) para que ele me retornasse o valor da constante. Sempre que escrevo um valor com ponto, ele me retorna, no console do navegador, o número sem pontos. Porém ele não me retorna nada quando há um hifén(ou sinal de subtração) no valor do input. Por não retornar nada, ele não passa o valor do campo como parâmetro para as demais funções, fazendo com que elas não funcionem. Notando isso eu tentei retirar o type="number" do input em questão e notei que no console.log ele retira tanto os pontos como os hiféns , "normalizando" o CPF para o padrão que a gente precisa. Se tirarmos o tipo type="number" será possível colocar letras, e não é isso que queremos. Porém se deixarmos, esse "bug"(vou chamar de bug, mas deve ser alguma propriedade do JS que eu desconheço) pode atrapalhar. Então qual seria a melhor opção para resolver esse problema? Eu pensei em reforçar ao usuário uma mensagem para não colocar hiféns, caso seja detectado no input. Ou existe alguma forma de impedir a inserção do " - " no input?

4 respostas

Olá, Annie, tudo bem?

Agradeço por compartilhar sua dúvida conosco sobre o problema.

Vou explicar o comportamento observado e apresentar algumas soluções para resolver essa questão.

Ao utilizar o código fornecido no curso, o valor do campo de CPF é capturado e é aplicado um replace para remover os pontos e hifens, deixando apenas os dígitos do CPF. No entanto, quando o campo possui um hifen (-), você observou que o valor não é retornado corretamente pelo console.log, e isso faz com que o valor não seja passado corretamente como parâmetro para as outras funções de validação.

Esse comportamento ocorre porque o atributo "type" do campo de CPF está definido como "number". Quando o atributo "type" é definido como "number", o navegador tenta validar e restringir a entrada para aceitar apenas valores numéricos. Portanto, ao digitar um hifen (-), o navegador não considera esse caractere como válido e não o inclui no valor do campo.

Para solucionar esse problema, existem algumas opções que podemos considerar:

  1. Utilizar um campo de texto com máscara: Uma solução é alterar o atributo "type" do campo de CPF para "text" e adicionar uma máscara que formate o valor conforme o usuário digita. Dessa forma, o usuário poderá visualizar o hifen enquanto digita, mas ele será removido quando o valor do campo for processado. Existem várias bibliotecas JavaScript, como a "input-mask" (https://github.com/RobinHerbots/Inputmask), que podem ajudar a implementar facilmente máscaras nos campos de texto.

    Exemplo de uso da biblioteca "input-mask" no campo de CPF:

    <input type="text" id="cpf" data-inputmask="'mask': '999.999.999-99'">
    
  2. Validar e remover hifens manualmente: Outra opção é realizar a validação e remoção dos hifens manualmente, sem depender do comportamento do campo de CPF com o atributo "type" definido como "number". Nesse caso, você pode adicionar um evento de escuta (event listener) ao campo de CPF para capturar o valor digitado pelo usuário, remover os hifens e, em seguida, prosseguir com as validações.

    Exemplo de código JavaScript para validação e remoção dos hifens:

    const cpfInput = document.getElementById('cpf');
    
    cpfInput.addEventListener('input', function() {
      const cpf = cpfInput.value.replace(/\.|-/g, '');
    
      // Continue com as validações do CPF
      if (validaNumerosRepetidos(cpf) || validaPrimeiroDigito(cpf) || validaSegundoDigito(cpf)) {
        console.log('Esse CPF não existe');
      } else {
        console.log('Esse CPF existe');
      }
    });
    
  3. Utilizar um campo de texto e validar o formato do CPF: Em vez de remover os hifens automaticamente, você pode instruir os usuários a digitarem o CPF sem os hifens, mas permitir que os hifens sejam exibidos no campo de texto. Dessa forma, você pode adicionar uma validação adicional para garantir que o formato do CPF esteja correto antes de realizar as demais validações.

    Exemplo de código JavaScript para validar o formato do CPF:

    const cpfInput = document.getElementById('cpf');
    
    cpfInput.addEventListener('input', function() {
      const cpf = cpfInput.value;
    
      // Verifica se o formato do CPF está correto (11 dígitos numéricos)
      if (/^\d{11}$/.test(cpf)) {
        // Continue com as validações do CPF
        if (validaNumerosRepetidos(cpf) || validaPrimeiroDigito(cpf) || validaSegundoDigito(cpf)) {
          console.log('Esse CPF não existe');
        } else {
          console.log('Esse CPF existe');
        }
      } else {
        console.log('Por favor, digite um CPF válido (sem pontos ou hifens)');
      }
    });
    

Essas são algumas opções para resolver o problema!

Cada uma dessas abordagens tem suas próprias vantagens e considerações, portanto, escolha aquela que melhor se adapta às suas necessidades e ao contexto do seu projeto.

Espero que tenha te ajudado a encontrar uma solução adequada para o problema.

Se tiver mais alguma dúvida, sinta-se à vontade para perguntar.

Abraços e Bons estudos!

Testei aqui e nenhuma solução funcionou. Instalei o input mask e não consegui fazer funcionar, e fui ver a documentação mas não está clara o suficiente. O segundo não consigo fazer ele substituir e ainda funcionar com o código modularizado. Na real, nem sequer consigo fazer ele tirar pontos e hifens quando digito. O terceiro método retorna ao problema original do meu post.

O que eu consegui fazer foi usar:

type="text" oninput="this.value = this.value.replace(/[^0-9]/g, '')"

Mas não sei se é o mais adequado

Olá, Annie, tudo ok contigo?

Agradeço por compartilhar suas experiências com as soluções que propus. Entendo que encontrar a melhor abordagem pode ser um desafio, mas estou aqui para te ajudar a resolver esse problema.

Vamos revisar cada uma das opções novamente e explorar outras possibilidades para garantir que encontraremos a solução mais adequada para o seu caso.

  1. Utilizando uma biblioteca de máscara (input-mask):

    A biblioteca "input-mask" pode ser uma ótima ferramenta para adicionar máscaras a campos de texto, mas, como você mencionou que teve dificuldades, vamos explorar um pouco mais essa opção.

    Primeiro, certifique-se de ter incluído corretamente a biblioteca no seu projeto. Você pode fazer isso adicionando o seguinte código em seu HTML, antes do fechamento da tag </body>:

    <script src="caminho/para/inputmask.min.js"></script>
    

    Lembre-se de substituir caminho/para/inputmask.min.js pelo caminho correto para o arquivo inputmask.min.js.

    Além disso, você precisará adicionar também o arquivo de definições de máscara para CPF. Você pode fazer isso assim:

    <script src="caminho/para/inputmask.min.js"></script>
    <script src="caminho/para/jquery.inputmask.min.js"></script>
    <script src="caminho/para/inputmask.binding.min.js"></script>
    <script src="caminho/para/inputmask.numeric.extensions.min.js"></script>
    <script src="caminho/para/inputmask.mask.extensions.min.js"></script>
    

    Lembre-se de substituir caminho/para/ pelo caminho correto para cada um dos arquivos.

    Agora, vamos adicionar a máscara ao campo de CPF:

    <input type="text" id="cpf" data-inputmask="'mask': '999.999.999-99'">
    

    Ao fazer isso, o campo de CPF deve agora apresentar a máscara com pontos e hífen, e o valor digitado será processado corretamente, mantendo apenas os dígitos do CPF para as demais validações. Certifique-se de que o caminho para os arquivos da biblioteca está correto e que você adicionou os scripts na ordem correta.

  2. Validar e remover hifens manualmente:

    Se você preferir evitar o uso de bibliotecas adicionais, podemos optar por fazer a validação e a remoção dos hifens manualmente, sem depender do comportamento do campo de CPF com o atributo "type" definido como "number".

    Vamos revisar o código novamente:

    const cpfInput = document.getElementById('cpf');
    
    cpfInput.addEventListener('input', function() {
      const cpf = cpfInput.value.replace(/\.|-/g, '');
    
      // Continue com as validações do CPF
      if (validaNumerosRepetidos(cpf) || validaPrimeiroDigito(cpf) || validaSegundoDigito(cpf)) {
        console.log('Esse CPF não existe');
      } else {
        console.log('Esse CPF existe');
      }
    });
    

    Certifique-se de que o campo de CPF tem o atributo type="text" e não o type="number". Com essa abordagem, o código deve remover corretamente os pontos e hifens, mantendo apenas os dígitos do CPF para as demais validações.

  3. Utilizar um campo de texto e validar o formato do CPF:

    Essa opção requer a colaboração do usuário para digitar o CPF corretamente, sem os pontos e hifens, mas permite que esses caracteres sejam exibidos no campo de texto.

    Vamos revisar o código:

    const cpfInput = document.getElementById('cpf');
    
    cpfInput.addEventListener('input', function() {
      const cpf = cpfInput.value;
    
      // Verifica se o formato do CPF está correto (11 dígitos numéricos)
      if (/^\d{11}$/.test(cpf)) {
        // Continue com as validações do CPF
        if (validaNumerosRepetidos(cpf) || validaPrimeiroDigito(cpf) || validaSegundoDigito(cpf)) {
          console.log('Esse CPF não existe');
        } else {
          console.log('Esse CPF existe');
        }
      } else {
        console.log('Por favor, digite um CPF válido (sem pontos ou hifens)');
      }
    });
    

    Com essa abordagem, o campo de CPF permite que o usuário digite o valor sem a máscara, mas uma mensagem é exibida caso o formato não esteja correto, orientando o usuário a não utilizar pontos ou hifens.


Sobre a opção que você mencionou:

<input type="text" oninput="this.value = this.value.replace(/[^0-9]/g, '')">

Essa solução também pode ser uma alternativa válida para garantir que apenas números sejam inseridos no campo de CPF. No entanto, ela não trata a formatação do CPF e, portanto, a exibição de pontos e hifens não será possível.

Espero que essas informações e detalhes adicionais te ajudem a encontrar a solução mais adequada para o seu projeto. Lembre-se de que estou aqui para ajudar, e se precisar de mais alguma explicação ou tiver dúvidas, estou à disposição.

Continue com seus estudos e conte comigo para te auxiliar sempre que precisar.

Desejo lhe sucesso em sua jornada de aprendizado! :)

Abraços e bons estudos.