Formatting Brazilian currency in Javascript

Asked

Viewed 79,762 times

40

I have the following variable:

var atual = 600000.00 ;

Here we have the value six hundred thousand in American standard, I would like when I print on the screen to look like this:

600.000,00

I’m using jquery in the project if it helps.

  • You want to format or show a validation saying it is incorrect?

  • format the output

  • logic works in many <3 languages

12 answers

85


Solution with toLocaleString().

var atual = 600000.00;

//com R$
var f = atual.toLocaleString('pt-br',{style: 'currency', currency: 'BRL'});

//sem R$
var f2 = atual.toLocaleString('pt-br', {minimumFractionDigits: 2});

console.log(f);
console.log(f2);

  • 2

    Excellent use of language!

  • What the minimum attribute?

  • 1

    @RXSD, minimumFractionDigits determines that always show a minimum of decimals, even if they don’t exist. 600.1 will be formatted as 600.10.

18

Try this function:

<script language="javascript">   
function moeda(a, e, r, t) {
    let n = ""
      , h = j = 0
      , u = tamanho2 = 0
      , l = ajd2 = ""
      , o = window.Event ? t.which : t.keyCode;
    if (13 == o || 8 == o)
        return !0;
    if (n = String.fromCharCode(o),
    -1 == "0123456789".indexOf(n))
        return !1;
    for (u = a.value.length,
    h = 0; h < u && ("0" == a.value.charAt(h) || a.value.charAt(h) == r); h++)
        ;
    for (l = ""; h < u; h++)
        -1 != "0123456789".indexOf(a.value.charAt(h)) && (l += a.value.charAt(h));
    if (l += n,
    0 == (u = l.length) && (a.value = ""),
    1 == u && (a.value = "0" + r + "0" + l),
    2 == u && (a.value = "0" + r + l),
    u > 2) {
        for (ajd2 = "",
        j = 0,
        h = u - 3; h >= 0; h--)
            3 == j && (ajd2 += e,
            j = 0),
            ajd2 += l.charAt(h),
            j++;
        for (a.value = "",
        tamanho2 = ajd2.length,
        h = tamanho2 - 1; h >= 0; h--)
            a.value += ajd2.charAt(h);
        a.value += r + l.substr(u - 2, u)
    }
    return !1
}
 </script>  
 Entrar caracteres:  <br><br>
 <form>  
 Valor em R$: <input type="text" name="valor" placeholder="Digite aqui" onKeyPress="return(moeda(this,'.',',',event))">  
 </form> 

Source: https://gist.github.com/antoniopassos/203181.

  • 9

    Hello, you could give credit to the author of the code you used as a response: http://codigofonte.uol.com.br/codigos/mascara-currency

  • 4

    What do these tech notes have to do with the answer? It has nothing to do, much less are necessary, if you copied the code from somewhere simply cite the source and that’s it, you don’t have to justify your mistake with unnecessary citations. (cc @Math)

  • 1

    Good ! Helped me cool.

16

I found a solution with Reg Exp. You use the regular expression to locate the numbers values and replace them with Real formatting.

<script type="text/javascript">
    var test = 'R$ 1.700,90';


function getMoney( str )
{
        return parseInt( str.replace(/[\D]+/g,'') );
}
function formatReal( int )
{
        var tmp = int+'';
        tmp = tmp.replace(/([0-9]{2})$/g, ",$1");
        if( tmp.length > 6 )
                tmp = tmp.replace(/([0-9]{3}),([0-9]{2}$)/g, ".$1,$2");

        return tmp;
}


var int = getMoney( test );
//alert( int );


console.log( formatReal( 1000 ) );
console.log( formatReal( 19990020 ) );
console.log( formatReal( 12006 ) );
console.log( formatReal( 111090 ) );
console.log( formatReal( 1111 ) );
console.log( formatReal( 120090 ) );
console.log( formatReal( int ) );

</script>

Notice that it locates the "value" in this excerpt.

tmp.replace(/([0-9]{2})$/g, ",$1");

and replaces the value in the format of "Brazilian real"

tmp.replace(/([0-9]{3}),([0-9]{2}$)/g, ".$1,$2");

Source

14

You can use regular expressions for this:

function formatarMoeda() {
  var elemento = document.getElementById('valor');
  var valor = elemento.value;
  
  valor = valor + '';
  valor = parseInt(valor.replace(/[\D]+/g,''));
  valor = valor + '';
  valor = valor.replace(/([0-9]{2})$/g, ",$1");

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

  elemento.value = valor;
}
<input type="text" id="valor" onkeyup="formatarMoeda();" />

8

Because the Sorack function has two bugs: one of Nan when deleting all numbers with Backspace, and the other when typing only one number, which appears integer instead of decimal.

So I made this version below using the same idea, only simpler and it works on multiple input’s.

Maybe it’ll help someone.

Follows:

function k(i) {
	var v = i.value.replace(/\D/g,'');
	v = (v/100).toFixed(2) + '';
	v = v.replace(".", ",");
	v = v.replace(/(\d)(\d{3})(\d{3}),/g, "$1.$2.$3,");
	v = v.replace(/(\d)(\d{3}),/g, "$1.$2,");
	i.value = v;
}
Valor R$ <input onkeyup="k(this);" /><br/>
Valor R$ <input onkeyup="k(this);" /><br/>
Valor R$ <input onkeyup="k(this);" /><br/>

Click on the Run button above to test.

Hugs

  • Thanks @Lynx, it helped me the most =)

7

I may be late, but I will post here how to format coins in nodejs.

num
.toFixed(2) // casas decimais
.replace('.', ',')
.replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1.')

I hope I’ve helped.

  • Worked for me helped out thanks

3

Javascript has this method Intl that almost no one knows. It not only formats number as date.

const atual = 600000.00;

const valorFormatado = Intl.NumberFormat('pt-br', {style: 'currency', currency: 'BRL'}).format(atual)

console.log(valorFormatado)

  • 1

    Hello Gilmar, how about a little more detail to clarify your solution?

  • Ja of a brief explanation, rotate. ai that works. : D

  • Accepted answers are those that best point the error, describe the solution and if possible cite references.

  • Clean solution that works perfectly.

  • I went here and returns "R$ 600,000,00", the right one would not be "R$ 600,000,00"? That is, change the place of the comma and period. For me this code does not work as expected.

1

Follow another solution.

function formatMoney(n, c, d, t) {
  c = isNaN(c = Math.abs(c)) ? 2 : c, d = d == undefined ? "," : d, t = t == undefined ? "." : t, s = n < 0 ? "-" : "", i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "", j = (j = i.length) > 3 ? j % 3 : 0;
  return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
}
console.log(formatMoney(600000.00));
console.log(formatMoney(10));
console.log(formatMoney(100));
console.log(formatMoney(0.5));
console.log(formatMoney(1500));
console.log(formatMoney(89));

1

Although the question already has an answer, I leave an alternative for the next people who open this question. I modified a little the code of lynx_74 to format text regardless of input text length.

function Formatar(valor)
{
    const v = ((valor.replace(/\D/g, '') / 100).toFixed(2) + '').split('.');

    const m = v[0].split('').reverse().join('').match(/.{1,3}/g);

    for (let i = 0; i < m.length; i++)
        m[i] = m[i].split('').reverse().join('') + '.';

    const r = m.reverse().join('');

    return r.substring(0, r.lastIndexOf('.')) + ',' + v[1];
}

If you want you can put 'R$ ' + r.substring(0, r.lastIndexOf('.')) + ',' + v[1] on the return of function.

What’s more, if you want to work with the value after formatting (like sending to an API), you can easily convert it as follows:

const valor = parseFloat(c.replace(/[^0-9,.]/g, '').replace(/[.]/g, '').replace(',', '.'));

Where c is the value converted by the function Formatar. The first replace removes characters not included in the range [0, 9] and also the different , and .. The second replace exchange all the . for '' and the third the only , for ..

Hugs!

1

A change in the function of Guilherme Nascimento to prefix "R$"

function moeda(a, e, r, t) {
            let n = ""
              , h = j = 0
              , u = tamanho2 = 0
              , l = ajd2 = ""
              , o = window.Event ? t.which : t.keyCode;
              a.value = a.value.replace('R$ ','');            
            if (n = String.fromCharCode(o),
            -1 == "0123456789".indexOf(n))
                return !1;
            for (u = a.value.replace('R$ ','').length,
            h = 0; h < u && ("0" == a.value.charAt(h) || a.value.charAt(h) == r); h++)
                ;
            for (l = ""; h < u; h++)
                -1 != "0123456789".indexOf(a.value.charAt(h)) && (l += a.value.charAt(h));
            if (l += n,
            0 == (u = l.length) && (a.value = ""),
            1 == u && (a.value = "R$ 0" + r + "0" + l),
            2 == u && (a.value = "R$ 0" + r + l),
            u > 2) {
                for (ajd2 = "",
                j = 0,
                h = u - 3; h >= 0; h--)
                    3 == j && (ajd2 += e,
                    j = 0),
                    ajd2 += l.charAt(h),
                    j++;
                for (a.value = "R$ ",
                tamanho2 = ajd2.length,
                h = tamanho2 - 1; h >= 0; h--)
                    a.value += ajd2.charAt(h);
                a.value += r + l.substr(u - 2, u)
            }
            return !1
        }
<input type="text" name="field" placeholder="R$" onKeyPress="return(moeda(this,'.',',',event))">

0

Up-to-date complete solution

This is the complete solution as a function that I created based on the chosen answer of this question of friend Lleon:

function convertToReal(number, options = {}) {
    const { moneySign = true } = options;

    if(Number.isNaN(number) || !number) return "need a number as the first parameter";

    if(typeof number === "string") { // n1
        number = Number(number);
    }

    let res;

    const config = moneySign ? {style: 'currency', currency: 'BRL'} : {minimumFractionDigits: 2};

    moneySign
    ? res = number.toLocaleString('pt-BR', config)
    : res = number.toLocaleString('pt-BR', config)

    const needComma = number => number <= 1000;
    if(needComma(number)) {
        res = res.toString().replace(".", ",");
    }

    return res; // n2
}

/* COMMENTS
n1: although the function returns as a string, the target value should be a 
number. Otherwise, no effect will be made.
n2: returns a string.
*/ 

const test1 = convertToReal('60.45');
const test2 = convertToReal(60.45);
const test3 = convertToReal(60.45, { moneySign: false })
const test4 = convertToReal(undefined, { moneySign: false })

console.log(test1)
console.log(test2)
console.log(test3)
console.log(test4)

In this solution, I added the exception handling to avoid flaws in your code like - for example - if the value is a string, then toLocaleString won’t work, only if it’s a number.

Another thing that I noticed, is that values below 1000 still get point instead of comma. 60.0 continues like this instead of converting to 60.0. To ensure this is converted I added the function needComma to convert values below 1000.

0

I developed this function to fit any monetary system in the world. Basically it applies by adding 3 important data:

var decimais = 2; - Número de casas decimais após a vírgula, deixe em 0, caso queira apenas número inteiro.
var separador_milhar = '.'; - Carácter que irá separar a cada 1000 unidades
var separador_decimal = ','; - Carácter que irá separar a casa decimal

Follow the function below:

function atacado(i) {
//ADD dados para a másrcara
    var decimais = 2;
  var separador_milhar = '.';
  var separador_decimal = ',';
  
  var decimais_ele = Math.pow(10, decimais);
  var thousand_separator = '$1'+separador_milhar;
  var v = i.value.replace(/\D/g,'');
    v = (v/decimais_ele).toFixed(decimais) + '';
  var splits = v.split(".");
    var p_parte = splits[0].toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, thousand_separator);
  (typeof splits[1] === "undefined") ? i.value = p_parte : i.value = p_parte+separador_decimal+splits[1];
  
}

Follows the HTML:

<input onkeyup="atacado(this);" />

Browser other questions tagged

You are not signed in. Login or sign up in order to post.