Sum array in javascript currency

Asked

Viewed 907 times

5

I need help to convert and add formatted currency fields coming in this format "1.568,78"

I have a code that sums an array of parcels and checks if it is equal to the total value of the invoice that I got here after several queries in user replies, and works perfectly with integers, but when I type the number formatted in real it does not add up:

var quant = document.getElementsByName("valor[]");
function somarValores(){
var valor_fatura = parseInt(document.getElementById('valor_fatura').value);
var soma = 0;
var soma = [].reduce.call(quant, function (somatorio, el) {
    return somatorio + parseInt(el.value, 10) || 0;
}, 0);
if(soma != valor_fatura){
 alert('Valor não confere. Fatura='+valor_fatura+' - Parcelas='+soma+'');
 return false;
}

}

I assume then that I have to convert the variables "Quant" and "invoice value" to the format 1568.78 before calculating because as it is it rounds to whole numbers and disregards the cents causing error in my validation

  • I started writing an answer but then I saw the size of the responsibility. Basically, you’ll have to do a function that replaces the commas with dots and vice versa and then use parseFloat. The problem is that Javascript does not have a "replaceAll". Substitutes include using regular expressions, but this brings the danger of entries containing metacharacters (special regular expression characters). Then you would also have to do a pretreatment of the entrance to avoid this. That is, it will take a little work. If you follow this tip, post here to us your solution. :)

3 answers

4

  1. Remove the dot character (.)

  2. Replace the semicolon character (,) with a dot (.)

str = '1.568,78901';
str = str.replace(/[.]/g, '');
str = str.replace(/[,]/g, '.');
console.log(str);
document.getElementById('foo').innerHTML = str;


/**
Uma situação muito perigosa, inclusive citada num dos comentários, consiste em remover o ponto e a vírgula e dividir por 100. 
Isso não é seguro pois se trabalharmos com casas decimais maior ou menor que 2 casas, retornará um número errado.
*/
str = '1.568,78901';
str = str.replace(/[.,]/g, '');
str = parseInt(str) / 100;
console.log(str);
document.getElementById('foo2').innerHTML = 'cuidado... o resultado é errado: '+str;
<div id="foo"></div>
<br />
<div id="foo2"></div>

To perform mathematical operations, always use parseint() or parsetFloat() to convert the strings to a numeric format suitable for calculations.

Function names are suggestive "Int" for integers and "Float" is for floating numbers (with decimals).

A more complete example, converting the numbers and performing a mathematical operation:

function number_format(number, decimals, dec_point, thousands_sep) {
  //  discuss at: http://phpjs.org/functions/number_format/
  number = (number + '')
    .replace(/[^0-9+\-Ee.]/g, '');
  var n = !isFinite(+number) ? 0 : +number,
    prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
    sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
    dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
    s = '',
    toFixedFix = function(n, prec) {
      var k = Math.pow(10, prec);
      return '' + (Math.round(n * k) / k)
        .toFixed(prec);
    };
  // Fix for IE parseFloat(0.55).toFixed(0) = 0;
  s = (prec ? toFixedFix(n, prec) : '' + Math.round(n))
    .split('.');
  if (s[0].length > 3) {
    s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
  }
  if ((s[1] || '')
    .length < prec) {
    s[1] = s[1] || '';
    s[1] += new Array(prec - s[1].length + 1)
      .join('0');
  }
  return s.join(dec);
}


function floatFilter(str)
{
    str = str.replace(/[.]/g, '');
    str = str.replace(/[,]/g, '.');
    return parseFloat(str);
}

var n1 = '1.568,78901';
var n2 = '5.311';
var sum = floatFilter(n1) + floatFilter(n2);
document.getElementById('foo3').innerHTML = n1+' + '+n2+' = '+sum+' ou ('+number_format(sum, 5, ',', '.')+')';
<div id="foo3"></div>

Obs: The function number_format() is from the PHPJS.org project: http://phpjs.org/functions/number_format/

It is a project that translates PHP functions to Javascript.

4

Guys, the tips really helped me out. I was able to solve by removing the punctuation of the string and using the parseFloat inside the code itself so as not to have a huge code.

var quant = document.getElementsByName("valor[]");
function somarValores(){
var valor_fatura = parseFloat(document.getElementById('valor_fatura').value.replace('.','').replace(',','.'));
var soma = 0;
var soma = [].reduce.call(quant, function (somatorio, el) {
    return somatorio + parseFloat(el.value.replace('.','').replace(',','.'), 10) || 0;
}, 0);
if(soma != valor_fatura){
var diferenca = soma - valor_fatura;
$("#lcto_mostraerro").append("Valor não confere. Há uma diferença de "+parseFloat(diferenca)+"");
return false;
}    
}

First include parseFloat at the beginning of the string and remove the score with replace ". replace('.','). replace(',','.')".

To give an increment I used .append to show the error inside a div instead of the Alert

0

Use Javascript parseFloat(). If your string comes as "1.568,78" (example). You should do so:

parseFloat("1.568,78") //1568.78

  • Continue rounding "var invoice value = parseFloat(Document.getElementById('invoice value'). value);"

  • It must be because you are passing parseint() further down.

  • replaced by parseFloat below and also not solved

  • You can remove the colons and commas from each value and divide by 100. var str = "1.568,78"; str = str.replace(/[,.]/g, ''); alert(parseInt(str)/100) ;

  • OP, there is a great and simple Battisti alternative in the following link. This is the last function moeda2Float(): https://battisti.wordpress.com/2007/03/08/roundformating-formating-formating-values-em-javascript/

Browser other questions tagged

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