6
respostas

Erro na formatação de valor digitado para reais

Bom dia. Tenho um script JS que formata o valor digitado em Reais com ponto e virgula. O script esta em anexo. Ocorre que ele formata certinho até o lenght de 12 e o valor de 9.999.999,99 se tento aumentar o lenght para 18 ele não formata corretamente. Ou seja a parte do script que trata o lenght >13 e <= 18 não esta funcionando. Gostaria de orientação de como resolver o problema.

echo form_label("Valor Orçado periodo R$:","valor",array("style" => "height:22px;padding-top:5px;")); echo form_input(array( "name" => "valor", "type" => "text", "id" => "valor", "style" => "width:30%;height:22px;", "maxlength" => "12", "onkeyup" => "formatarMoeda()", "value" => $periodo['valor_previsto'] ));

?>

6 respostas

Oi, Irair!

Parece que o seu problema está relacionado à formatação de valores maiores que 9.999.999,99 no seu script JavaScript. Isso pode ocorrer por conta da lógica de formatação, que provavelmente não está conseguindo lidar com valores acima de 13 dígitos.

Se eu fosse vc tentaria:

  1. Ajustar a lógica da formatação para suportar números maiores.
  2. Modificar o maxlength para aceitar mais caracteres.
  3. Certificar-se de que o script de formatação (na função formatarMoeda()) esteja correto para valores maiores.
  4. Considerar usar uma biblioteca para formatação robusta de moeda.

Bom dia. Obrigado por responder. Atualizando suas respostas.

1 - O entendimento que a lógica de programação esta criada para números maiores, representado pelo "if (valor.length > 12 && valor.length <= 18 ) { valor = valor.replace(/([0-9]{3}).([0-9]{3}).([0-9]{3}),([0-9]{2}$)/g, ".$1.$2.$3,$4")};" e a qual não funciona a contento mas não sei oo porque.

2 - O length foi alterado para numero maior e o que acontece é o seguinte: perde os pontos quando digito um número até 13 digitos editado (anexo 1) e tem comportamento estranho se digito mais um número (anexo 2)

3 - É esse o problema, eu não sei o que esta errado no script para valores maiores.

4 - Tem alguma sugestão?

anexo 1 Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Anexo 2 Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Oi Irair!

Então acho que seu problema está na forma como o script está tentando aplicar a máscara de formatação em números maiores, especialmente no que diz respeito ao uso de regex para inserir os separadores de milhar (pontos) e decimais (vírgula).

Lógica da Regex para formatação A regex que você mencionou:

if (valor.length > 12 && valor.length <= 18 ) {
    valor = valor.replace(/([0-9]{3}).([0-9]{3}).([0-9]{3}),([0-9]{2}$)/g, ".$1.$2.$3,$4");
}

Parece que está tentando formatar o valor com pontos a cada três dígitos, mas há um problema na forma como ela é aplicada, principalmente ao lidar com a parte decimal (a vírgula), e o padrão parece não estar correto.

Aqui estão alguns ajustes que você pode fazer:

Ajuste na Regex

  1. Problema com os pontos (.): O ponto (.) é um caractere especial em regex, por isso precisa ser escapado com uma barra invertida (\.) para ser interpretado literalmente. O mesmo vale para a vírgula na parte decimal.

  2. Ajustando a lógica para suportar números maiores: O script precisa identificar quantos números há à esquerda da vírgula (casas inteiras) e formatá-los adequadamente, sem que o regex entre em conflito com o número de casas decimais.

  3. Código Ajustado Aqui está um exemplo de como você pode ajustar o script:

function formatarMoeda() {
    let valor = document.getElementById('valor').value;

    // Remove qualquer caracter que não seja número ou vírgula
    valor = valor.replace(/\D/g, '');

    // Adiciona a vírgula para as casas decimais
    valor = valor.replace(/(\d)(\d{2})$/, '$1,$2');

    // Aplica a formatação dos pontos a cada 3 dígitos, mas só nas casas inteiras
    valor = valor.replace(/(\d)(\d{3})(?=\d)/g, '$1.$2');

    // Atualiza o valor do campo de entrada
    document.getElementById('valor').value = valor;
}
  • A primeira regex valor.replace(/\D/g, '') remove qualquer caractere que não seja número ou vírgula (evitando erros com pontos ou outros caracteres).
  • A segunda regex valor.replace(/(\d)(\d{2})$/, '$1,$2') coloca a vírgula corretamente antes dos dois últimos dígitos (casas decimais).
  • A terceira regex valor.replace(/(\d)(\d{3})(?=\d)/g, '$1.$2') aplica a formatação de pontos a cada três dígitos, mas somente para a parte inteira do número, de maneira que você consiga lidar com números grandes, até 18 dígitos.

O maxlength="12" no seu HTML vai cortar os valores digitados. Você mencionou que o comprimento máximo precisa ser maior para suportar valores maiores, então altere isso no seu HTML para um valor maior, como:

<input type="text" name="valor" id="valor" maxlength="18" onkeyup="formatarMoeda()" />

Tente usar esse código ajustado e veja se ele resolve o problema com valores de até 18 dígitos. Se o comportamento continuar estranho ao digitar números maiores, pode ser interessante verificar também o valor que está sendo passado para a função formatarMoeda para garantir que não haja problemas de tipo ou formatação extra.

Me fala se funcionou!

Bom dia.

Copiei o seu script e também a linha de código do input

Fiz os teste e reproduzo na imagem anexo

Não esta adequado na pontuação do número inteiro. Veja a partir do teste 2.

Obrigado

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

function formatarMoeda() { let valor = document.getElementById('valor').value;

// Remove qualquer caracter que não seja número ou vírgula
valor = valor.replace(/\D/g, '');

// Adiciona a vírgula para as casas decimais
valor = valor.replace(/(\d)(\d{2})$/, '$1,$2');

// Aplica a formatação dos pontos a cada 3 dígitos, ajustada para números maiores
valor = valor.replace(/\B(?=(\d{3})+(?!\d))/g, '.');

// Atualiza o valor do campo de entrada
document.getElementById('valor').value = valor;

}

Olha se esse código funciona.

\B(?=(\d{3})+(?!\d)): \B: Asserção de borda de palavra, garante que o ponto seja inserido entre dígitos. (?=(\d{3})+): Olha à frente para encontrar grupos de 3 dígitos. (?!\d): Garante que não haja mais dígitos após o último grupo de 3, evitando inserir pontos desnecessários.

o teste não apresentou pontuação

Insira aqui a descrição dessa imagem para ajudar na acessibilidadeO código utulizado: