0

I have a form that uses javascript to total it's values, It works fine until you enter a currency value that has cents in it, so a value of $2.99 will only show 2.00 in the total. Here is my jsFiddle http://jsfiddle.net/vegas/JwFCB/

    function multiplyRow(row) {

    var this_qty = row + "_value1"
    var this_price = row + "_value2"
    var this_extend = "extend" + row;
    document.getElementById(this_extend).value = (parseInt(document.getElementById(this_qty).value) * parseInt(document.getElementById(this_price).value)) || 0;
    summate();

}

function rateRow(row) {
    var this_payrate = "payrate" + row;
    var this_hours = "hours" + row;
    var this_subtot = "subtotal" + row;
    document.getElementById(this_subtot).value = (parseInt(document.getElementById(this_payrate).value) * parseInt(document.getElementById(this_hours).value)) || 0;
    getlabor();

}

function summate() {
    var materialcost = 0
    for (var i = 1; i <= 5; i++) {
        var id = "extend" + i;
        var thisVal = parseInt(document.getElementById(id).value, 10) || 0;
        materialcost += thisVal;
    }
    document.getElementById("materialcost").value = materialcost || 0;
    tax();
    grandTotal();
}

function getlabor() {
    var labortotal = 0
    var hourCounter = 0
    for (var i = 1; i <= 5; i++) {
        var id = "subtotal" + i;
        var idHours = "hours" + i;
        var thisVal = parseInt(document.getElementById(id).value, 10) || 0;
        var thisValHours = parseInt(document.getElementById(idHours).value, 10) || 0;
        labortotal += thisVal;
        hourCounter += thisValHours;

    }
    document.getElementById("labortotal").value = labortotal || 0;
    document.getElementById("totalhours").value = hourCounter || 0;
    grandTotal();

}

function tax() {
    var materialcost = document.getElementById('materialcost').value || 0;
    var shipping = document.getElementById('shipping').value || 0;
    var salestax = (Math.round(((materialcost / 100) * 8.1) * 100) / 100) || 0;
    var materialtotal = ((materialcost * 1) + (salestax * 1) + (shipping * 1)) || 0;

    document.getElementById('materialcost').value = materialcost;
    document.getElementById('salestax').value = salestax;
    document.getElementById('shipping').value = shipping;
    document.getElementById('materialtotal').value = materialtotal;
    grandTotal();


}

function grandTotal() {
    var labor = parseInt(document.getElementById("labortotal").value, 10) || 0;
    var material = parseFloat(document.getElementById("materialtotal").value, 10) || 0;
    document.getElementById('grandtotal').value = (labor + material).toFixed(2);
}
Jason
  • 224
  • 3
  • 11

2 Answers2

2

a decimal value will only show as integer

Then don't use parseInt, but parseFloat.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Bergi I changed it to parseFloat but now my totals show up as 29.4900000 – Jason Jun 02 '13 at 22:57
  • @jason—the trick is to work in integer minor units (e.g. cents), then convert to major units ($) only for the final display. – RobG Jun 02 '13 at 23:00
  • @RobG you're giving me more credit at understanding javascript than I really have. lol – Jason Jun 02 '13 at 23:01
  • @Jason: Check out http://stackoverflow.com/q/6466846 and similar questions - you can just use [`.toFixed(2)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) on it for simplicity. Btw, don't forget that you're dealing with [floating-point numbers](http://floating-point-gui.de/) here. – Bergi Jun 02 '13 at 23:08
  • @Bergi Thanks, I'm using toFixed(2) in my grandtotal already but changing this parseFloat(document.getElementById(id).value, 10) to this parseFloat(document.getElementById(id).value, 100) actually solved my issues. – Jason Jun 02 '13 at 23:33
  • @Jason: `parseFloat` doesn't take a second parameter? – Bergi Jun 02 '13 at 23:44
  • @Bergi lol I see that now, something weird happened as it worked when I did that but stopped so I used .toFixed(2) on my materialtotal and problem fixed thanks for the heads up! – Jason Jun 02 '13 at 23:50
1

Just a comment:

Mathematics with strings is only problematic where you are using the overloaded "+" operator. In your calculations, you can use:

document.getElementById(this_extend).value = document.getElementById(this_qty).value) * document.getElementById(this_price).value;

The only advantage of parseInt and parseFloat is that they trim trailing non-digit values. You should be validating user input before using it in calculations.

RobG
  • 142,382
  • 31
  • 172
  • 209