views:

529

answers:

10

Hi all, I'm not so good with JS and for some reason when I try to add two fields together it joins them rather than adding the sum together.. this is the code I'm trying to use..

    function calculateTotal() {

        var postageVal = document.getElementById('postage').value; //$68.50
        var subtotalVal = document.getElementById('subtotal').value; //$378.00

        var postage = postageVal.substr(1); //68.50
        var subtotal = subtotalVal.substr(1); //378.00
        var totalVal = postage+subtotal;

        alert(postage);
        alert(subtotal);
        alert(totalVal);

    };

The totalVal is echoing/alerting out 68.50378.00 rather than adding them together.. could someone please tell me where I've gone wrong? :( The idea is to update the "total" textfield with totalVal, but I haven't gotten that far yet!

+1  A: 

I haven't tested your code so there may be other issues but the fix below using parseFloat should stop the concatenation and add the numbers together.

function calculateTotal() {

    var postageVal = document.getElementById('postage').value; //$68.50
    var subtotalVal = document.getElementById('subtotal').value; //$378.00

    var postage = postageVal.substr(1); //68.50
    var subtotal = subtotalVal.substr(1); //378.00
    var totalVal = parseFloat(postage)+parseFloat(subtotal);

    alert(postage);
    alert(subtotal);
    alert(totalVal);

};

HTH OneSHOT

OneSHOT
It should probably be float rather than in.
Tom Hubbard
parseInt will round to a whole number, and we are dealing with prices :)
karim79
you should use parseFloat instead of parseInt since the values are not integers
Geoff
Yeah i spotted it after i posted, i've just updated while you where all posting! cheers anyway
OneSHOT
+2  A: 

parseFloat does the trick.

var postage = parseFloat(postageVal.substr(1));
var subtotal = parseFloat(subtotalVal.substr(1));
maisteri
+9  A: 

Try converting the numbers to floats:

function calculateTotal() {

    var postageVal = document.getElementById('postage').value; //$68.50
    var subtotalVal = document.getElementById('subtotal').value; //$378.00

    var postage = parseFloat(postageVal.substr(1)); //68.50
    var subtotal = parseFloat(subtotalVal.substr(1)); //378.00
    var totalVal = postage+subtotal;

    alert(postage);
    alert(subtotal);
    alert(totalVal);

};
karim79
+2  A: 

It's treating postage and subtotal as strings and concatenating them. You could try something like this:

var totalVal = 0+postage+subtotal;

That should force it into number mode.

However this could lead to problems if the values do not end up being numbers. You should run it through the proper number parsing functions and add checks to make sure they parsed correctly or else you will end up with NaN.

Tom Hubbard
+14  A: 

You need to convert your values to a float before adding them:

var totalVal = parseFloat(postage) + parseFloat(subtotal);

EDIT: Here's a complete example that includes a check for NaN:

function calculateTotal() {

    var postageVal = document.getElementById('postage').value; //$68.50
    var subtotalVal = document.getElementById('subtotal').value; //$378.00

    var postage = parseFloat(postageVal.substr(1)); //68.50
    var subtotal = parseFloat(subtotalVal.substr(1)); //378.00
    var postageAsFloat = isNaN(postage) ? 0.0 : postage;
    var subtotalAsFloat = isNaN(subtotal) ? 0.0 : subtotal;
    var totalVal = postageAsFloat + subtotalAsFloat;

    alert(postage);
    alert(subtotal);
    alert(totalVal);

};
Ray Vernagus
ended up using your code, thank you muchly (and to everyone else too!) :D
SoulieBaby
it might be better to use `Number()` and not `parseFloat()` as the former is less forgiving (e.g. won't ignore trailing non-numeric characters) or even use a regular expression to manually validate the input
Christoph
+1  A: 

You need to parse the number first. This should work.

function calculateTotal() {

    var postageVal = document.getElementById('postage').value; //$68.50
    var subtotalVal = document.getElementById('subtotal').value; //$378.00

    var postage = parseFloat( postageVal.substr(1) ); //68.50
    var subtotal = parseFloat( subtotalVal.substr(1) ); //378.00
    var totalVal = postage+subtotal;

    alert(postage);
    alert(subtotal);
    alert(totalVal);

};
Babar
A: 

Thanks for all the answers! I'll try them out, I'm sure they're better than my solution:

<script type="text/javascript">
function calculateTotal() {

   var postageVal = document.cart.postage.value;
   var subtotalVal = document.cart.subtotal.value;

   var postage = postageVal.substr(1);
   var subtotal = subtotalVal.substr(1);
   var totalVal = Number(postage)+Number(subtotal);

   document.cart.total.value = "$"+totalVal.toFixed(2);

};
</script>
SoulieBaby
+4  A: 

Everyone else has the right idea with parseFloat.

I just wanted to mention that I prefer to clean up numeric values like this (as opposed to parsing with substr):

var postageVal = document.getElementById('postage').value; //$68.50

var postage = parseFloat(postageVal.replace(/[^0-9.]/g, ''));

That replace call will remove any characters from the string except 0-9 and . (period). Not the /g at the end of the regex. That's important because, without it, only the first matching occurrence will be replaced.

Mark Biek
ahh thank you, will use that instead am relatively new to javascript so I don't know all the ins and outs :S
SoulieBaby
You may want to change that pattern to: /[^0-9.]*/ otherwise it only matches the first character.
Ray Vernagus
And even then it only matches when there's a non-digit character at the start of the string. My preference in this case is to stay away from regular expressions and just let javascript try to parse the number. parseFloat is rather robust and it can handle input such as "1abc" (parseFloat simply returns 1). The answer I offer above avoids the perils of regular expressions. ;)
Ray Vernagus
@Ray, actually that's a negated character class. It will match any non 0-9. characters throughout the entire string. The carat ^ only refers to the start of the string when it's outside []. http://www.regular-expressions.info/charclass.html
Mark Biek
It's also worth mentioning that parseFloat will fail if the string contains a "$" or "," in it.
Mark Biek
Not to drag this on, Mark, but when I run replace with the regex you posted above on the string "1abc", I get "1bc" returned. I'm probably doing something wrong.
Ray Vernagus
@Ray, you're absolutely right. I left off the /g at the end of the regex which makes it replace all occurrences. I've fixed it in the post. Thanks for catching that!
Mark Biek
Aha! That helps me, thanks much!
Ray Vernagus
+1  A: 

Unary plus should work:

var totalVal = (+postage) + (+subtotal);

But you probably intended your postage and subtotal variables to be numbers rather than strings, so...

var postage = +postageVal.substr(1); //68.50
var subtotal = +subtotalVal.substr(1); //378.00
var totalVal = postage+subtotal;
Nosredna
A: 

Having had the same sort of trouble I examined the JS parseFloat and parseInt functions and found them to be badly developed.

So therefore I prevent the whole problem by multiplying the element's value's * 1 before adding them. This forces JS to treat the result as numeric even if the value's were empty, so that it can be properly handled. As follows:

var TEMP = (1 * el_1.value) + (1 * el_2.value); document.getElementById("el_tot").value = TEMP;

Assuming you see that "el_1" et al are the fieldnames in the form.

Good luck !

Jan.

Jan