Kevin
Kevin

Reputation: 13226

Javascript - Calculating monetary totals

I have a page on a site that calculates rate totals for a rental, which are optional. The javascript serves nothing more but to show you the updated total if you select or unselect checkbox options.

Here is what I've tried. It appears to work, but it is adding 2 cents to every other click for one of the checkboxes, I believe because toFixed rounds. How can I keep the number from rounding?

function update_rate(state, amount, field) {
        if (state == true) {
            rate = parseFloat($('span.rateTotal').text()) + amount;
            rate = rate.toFixed(2);
            due = parseFloat($('span.'+field).text()) + amount;
            due = due.toFixed(2);
            $('span.rateTotal').text(rate);
            $('span.'+field).text(due);
        } else {
            rate = parseFloat($('span.rateTotal').text()) - amount;
            rate = rate.toFixed(2);
            due = parseFloat($('span.'+field).text()) - amount;
            due = due.toFixed(2);
            $('span.rateTotal').text(rate);
            $('span.'+field).text(due);
        }
    }

Checkbox HTML:

<cfinput type="checkbox" name="linen_service" id="linen_service" checked="checked" value="0" onClick="update_rate(this.checked, #reservationQuery[7].xmlChildren[i]['dblAmount'].xmlText#, 'second-due');" />

Basically passes in the amount of the option, checkbox state, and the name of the field that should be affected.

Edit: Fiddle URL: http://jsfiddle.net/nGrVf/6/

Upvotes: 4

Views: 323

Answers (2)

Mutation Person
Mutation Person

Reputation: 30498

Are you stuck with your your types?

I find it is almost always better to store monetary values in whole numbers of the lowest unit (e.g, cents, or pence) and then add the decimal point two places from the right when displaying.

So the conversions might look like:

var dollars = 100.43;
var cents = Math.round(dollars * 100);

//convert for display
var sCents = String(cents);
var display = sCents.substr(0, sCents.length-2) + "." + sCents.substr(sCents.length-2,2);
alert(display);

Can be seen here at http://jsfiddle.net/jameswiseman76/jhjtP/

Then you don't have to worry about any ugly floating point conversions.

Upvotes: 1

tcooc
tcooc

Reputation: 21209

The simplest solution I can think up is to round it down (using muls and floor): i.e.

rate = Math.floor(rate * 100)/100;

Edit: After a bit of testing, I found that there is nothing wrong with the given code. This means the calculation error comes from another part of the code or from the unknown amount variable.

Upvotes: 0

Related Questions