Forum Moderators: open

Message Too Old, No Replies

Sum and NaN problem

Bypass variable if value isNaN

         

Notawiz

1:43 pm on Feb 14, 2005 (gmt 0)

10+ Year Member



I have a form with several amount input fields, and a field displaying the total amount (triggered by onkeyup in the detail amount fields).

The called function is someting like:


function amounttotal() {
var myTotal;
myTotal=parseInt(myTotal,10);
myTotal='';
if (document.getElementById('first_amount')) {
myTotal = parseInt(myTotal) + parseInt(document.getElementById('first_amount').value);
}
if (document.getElementById('second_amount')) {
myTotal = parseInt(myTotal) + parseInt(document.getElementById('second_amount').value);
}
if (document.getElementById('third_amount')) {
myTotal = parseInt(myTotal) + parseInt(document.getElementById('third_amount').value);
}
document.getElementById('general_total').value = parseInt(myTotal);
}

As long as not ALL the detail fields are filled, I get a NaN in the general total.

I would get rid of that, especially since a user must NOT enter an amount in all the detail fields to get his total displayed.

I want the general total to be calculated and displayed even if only a part of the detail amount fields have a value filled in.

OK, so I searched the Internet, and found that I could test each detail value with something like:


if (isNaN(document.getElementById('first_amount'))==false) {
myTotal = parseInt(myTotal) + parseInt(document.getElementById('first_amount').value);
}

but in that case, the function does not work any longer, and no total is calculated or displayed.

By the way, I had to add the parseInt thing because otherwise I only had a concatenation, even if only numbers were entered.

Any idea what I missed in this code to make it work, even if only 1 of the detail fields receives a value?

Bernard Marx

1:55 pm on Feb 14, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Something not quite right here:

[color=brown]// myTotal declared (not set)[/color]
var myTotal;
[color=brown]// myTotal = parseIn(*undefined*,10) // --> NaN[/color]
myTotal=parseInt(myTotal,10);
[color=brown]// line above was pointless, because now..[/color]
myTotal='';

and since

parseInt('',10) [color=brown]--> Nan[/color]

..it's all over from then on!

Bernard Marx

2:07 pm on Feb 14, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Assuming:
- The elements have these strings as ids, not names.
- All such elements exist.

*! Replace ¦¦ in code with unbroken pipes (or it'll go wrong)

function amounttotal()
{
var total = 0, D = document;
var fieldIDs = ['first_amount','second_amount','third_amount'];

for(var k=0;k<fieldIDs.length;k++)
{
[color=brown]// if p(value) is 0 or Nan, then 0 is added[/color]
total += parseInt( D.getElementById(fieldIDs[k]).value,10) [red]¦¦[/red] 0;
}

D.getElementById('general_total').value = total; [color=brown]// implicit: number -> string[/color]
}

[edited by: Bernard_Marx at 2:10 pm (utc) on Feb. 14, 2005]

Notawiz

2:09 pm on Feb 14, 2005 (gmt 0)

10+ Year Member



Hello Bernard,

Your reply is not very clear to me. When I enter amounts in ALL the detail fields, the total field displays the correct sum.

I understand that I'm creating an *undefined* variable at the top of the script, but when I delete the line:


myTotal=parseInt(myTotal,10);

I have just the same NaN showing up in the total field as long as not all detail fields receive a value.

And as I said, I want the total to be calculated even if only part of the details are entered.

In conclusion, the *undefined* starting value declaration is not affecting the script.

Any other ideas?

Bernard Marx

2:13 pm on Feb 14, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



In conclusion, the *undefined* starting value declaration is not affecting the script.

It certainly isn't. You could set the variable to

"BANANAS"
and it wouldn't make any difference, because after that you have this statement:

myTotal='';

Notawiz

2:19 pm on Feb 14, 2005 (gmt 0)

10+ Year Member



Oops Bernard, I was replying on your first comment when you already made a second one.

The reason why I have the "if variable exist" statements all over the script, is because this form is generated on the fly depending on selections on earlier pages.
Thus I don't know in advance which amount detail fields I'll have (I just named them "first", "second" for my post here, but they have other names AND ID's in reality), and there could be about 12 of them.

Bernard Marx

2:25 pm on Feb 14, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



OK. We'll need a swift change then.

Do you know what the names might be?
or do you need to iterate through all the form's text fields in a more generic fashion.

PS see sticky

------

This should do it, if you know the full set of field ids that can appear:

function amounttotal()
{
var total = 0, D = document;
var fieldIDs = ['first_amount','second_amount','third_amount'];
var [color=brown]field[/color];

for(var k=0;k<fieldIDs.length;k++)
{
field = D.getElementById(fieldIDs[k]);
if(field) total += parseInt( field.value ,10 ) ¦¦ 0;
}

D.getElementById('general_total').value = total;
}

Bernard Marx

2:41 pm on Feb 14, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



If it is possible, you could identify all the relevent fields by giving them
all the same class attribute. This way, their ids may no longer be needed
(keep the names for the server script).

This function totals all the amounts from any field with the className, 'amount';

The function requires that you pass a reference to the form itself.
eg: onsubmit = "ammounttotal(this)"

function amounttotal(form)
{
var fieldClass = "amount";
var fields = form.elements, field, k=0;
var total = 0;

while(field=fields[k++])
{
if(field.className==fieldClass)
total += parseInt( field.value ,10 ) ¦¦ 0;
}

D.getElementById('general_total').value = total;
}

Notawiz

3:02 pm on Feb 14, 2005 (gmt 0)

10+ Year Member



Bernard,

Thanx, the version with the array worked terrific.


var fieldIDs = ['first_amount','second_amount','third_amount'];
var field;

Jan