Velocity Reviews > Help ! Shopping Cart Problem

# Help ! Shopping Cart Problem

Phil McKraken
Guest
Posts: n/a

 10-29-2005
I am having a problem putting together a shopping cart with the below
script. Everything displays fine, adds totals fine, and works perfect
EXCEPT if you choose the 9.95 item #5 BY ITSELF the total displayed is
\$9.94 ! If you add ANYTHING else the total is correct, 9.95 plus
whatever you add. That is the only price in these samples that is
doing that. All the others display properly. If you change the 9.95 to
ANY other number it displays correct. If you put 9.95 in any other
position (Item number 1 instead of 5 etc. it does the same thing)

TIA

(This is the entire html page you can paste it and view in a browser
to see the problem with the 9.95 item.)

<script language="JavaScript">
<!-- hide contents from old browsers

var Cost, Grand_Total;

function tally()
{
Cost = 0;
if (document.orderform.Item1.checked) { Cost = Cost + 119.95;
}
if (document.orderform.Item2.checked) { Cost = Cost + 75.00; }
if (document.orderform.Item3.checked) { Cost = Cost + 14.95; }
if (document.orderform.Item4.checked) { Cost = Cost + 50.00; }
if (document.orderform.Item5.checked) { Cost = Cost + 9.95; }
if (document.orderform.Item6.checked) { Cost = Cost + 4.95; }
if (document.orderform.Item7.checked) { Cost = Cost + 50.00; }
if (document.orderform.Item8.checked) { Cost = Cost + 7.95; }
if (document.orderform.Item9.checked) { Cost = Cost + 1.00; }

Cost = dollar(Cost);
Grand_Total = parseFloat(Cost)
Grand_Total = dollar(Grand_Total);

document.orderform.GrandTotal.value = "\$" + Grand_Total;
}

function dollar (amount)
{
amount = parseInt(amount * 100);
amount = parseFloat(amount/100);
if (((amount) == Math.floor(amount)) && ((amount - Math.floor
(amount)) == 0))
{
amount = amount + ".00"
return amount;
}
if ( ((amount * 10) - Math.floor(amount * 10)) == 0)
{
amount = amount + "0";
return amount;
}
if ( ((amount * 100) - Math.floor(amount * 100)) == 0)
{
amount = amount;
return amount;
}
return amount;
}

//-->
</script>
<body><center>

<form method="post" name="orderform" action="(E-Mail Removed)"
enctype="text/plain">
<table bgcolor="#EFEFEF" border="0" cellspacing="0"
<tr><td valign="top"><font face="verdana" size="2"
color="#000000"><b>
<p><input name="Item1" value="AcceleratedHighSpeedAnnual"
onclick="tally()" type="checkbox">Accelerated Dial-Up Internet Access
1 Year Pre-Pay (\$119.95)
</p><p><input name="Item2" value="Item2_chosen" onclick="tally()"
type="checkbox"> Accelerated Dial Up Internet Access Semi-Annual
Pre-Pay (\$75.00)
</p><p><input name="Item3" value="Item3_chosen" onclick="tally()"
type="checkbox"> Accelerated Dial Up Internet Access Monthly Billing
(\$14.95)
</p><p><input name="Item4" value="Item4_chosen" onclick="tally()"
type="checkbox"> Regular Dial Up Internet Access Semi-Annual Billing
(\$50.00)
</p><p><input name="Item5" value="Item5_chosen" onclick="tally()"
type="checkbox"> Regular Dial Up Internet Access Monthly Billing
(\$9.95)
</p></td><td valign="top"><font face="verdana" size="2"
color="#000000"><b>
</p><p><input name="Item6" value="Item6_chosen" onclick="tally()"
type="checkbox"> Add 3 Email Monthly Billing (\$4.95)
</p><p><input name="Item7" value="Item7_chosen" onclick="tally()"
type="checkbox"> Add 3 Email 1 Year Pre-Pay (\$50.00)
</p><p><input name="Item8" value="Item8_chosen" onclick="tally()"
type="checkbox"> 10 Email Only Monthly Billing Only (7.95)
</p><p><input name="Item9" value="Item9_chosen" onclick="tally()"
type="checkbox"> Mail Invoice for Payment by Check (\$1.00)
<br><br><font color="red">Total Due: <input name="GrandTotal"
value="\$0" size="8" type="text"></font>
</p></td></tr></table><br><br>
<center><input value="Send Order" type="submit"><input value="Reset
Order" type="reset"></center>
</form>
</body></html>

RobG
Guest
Posts: n/a

 10-29-2005
Phil McKraken wrote:
> I am having a problem putting together a shopping cart with the below
> script. Everything displays fine, adds totals fine, and works perfect
> EXCEPT if you choose the 9.95 item #5 BY ITSELF the total displayed is
> \$9.94 ! If you add ANYTHING else the total is correct, 9.95 plus
> whatever you add. That is the only price in these samples that is
> doing that. All the others display properly. If you change the 9.95 to
> ANY other number it displays correct. If you put 9.95 in any other
> position (Item number 1 instead of 5 etc. it does the same thing)
>

The problem is your dollar() function, here is a link to some 'to money'
conversion stuff:

<URL:http://www.merlyn.demon.co.uk/js-maths.htm#Money>

Or search the group for money conversion functions, I'm sure there are a
couple of good ones that have been posted. There is an extensive thread
here:

Converting strings to numbers and back using multiplication may result
in a rounded value that is not what you started with - 9.95 being a
'magic' number for your dollar function.

Use string manipulation for formatting numbers if you want to ensure
that they don't get modified.

[...]

--
Rob

Phil McKraken
Guest
Posts: n/a

 10-29-2005

>The problem is your dollar() function, here is a link to some 'to money'
>conversion stuff:

I tried the links you posted but, (: no luck. I am sure I am just
doing it wrong. I got this sample from one of those javascript web
repositories and I am not competent to change it to make it work. I am
still learning and am not really a js writer, only a "cut n paste"
trial & error modifier of what's there already.

Can someone tell me what to do to fix this a little more specifically.

Thanks for the responses. I really appreciate it. This is the way you
learn I guess.

When I tried the links, I screwed it up so bad it doesn't work at all
now. (Yes I have a backup that works the same as the original with the
"9.95" problem)

Thanks again.

Randy Webb
Guest
Posts: n/a

 10-29-2005
Phil McKraken said the following on 10/29/2005 12:03 PM:
>>The problem is your dollar() function, here is a link to some 'to money'
>>conversion stuff:

>
>
> I tried the links you posted but, (: no luck. I am sure I am just
> doing it wrong. I got this sample from one of those javascript web
> repositories and I am not competent to change it to make it work. I am
> still learning and am not really a js writer, only a "cut n paste"
> trial & error modifier of what's there already.
>
> Can someone tell me what to do to fix this a little more specifically.

You are trying to round by multiplying by 100 and then dividing by 100.
That introduces the error you see because computers cannot represent
9.95 exactly in Base 2. So you get the error.

The way around that error is to convert your Number to a whole number,
Operations*. Meaning, you do not divide by 100, you convert it to a
String and then add the decimal.

--
Randy
comp.lang.javascript FAQ - http://jibbering.com/faq & newsgroup weekly

Lee
Guest
Posts: n/a

 10-29-2005
Phil McKraken said:
>
>I am having a problem putting together a shopping cart with the below
>script. Everything displays fine, adds totals fine, and works perfect
>EXCEPT if you choose the 9.95 item #5 BY ITSELF the total displayed is
>\$9.94 ! If you add ANYTHING else the total is correct, 9.95 plus
>whatever you add. That is the only price in these samples that is
>doing that. All the others display properly. If you change the 9.95 to
>ANY other number it displays correct. If you put 9.95 in any other
>position (Item number 1 instead of 5 etc. it does the same thing)
>

That's really just horrible code, and should be thrown away,
but the simplest fix to your problem is to remove the line
indicated below. Every time you call that ridiculous dollar()
function you introduce more error, so don't call it without
any reason. There's also no reason to use either parseFloat()
or parseInt() in this code, but at least they're not causing
the problem.

>function tally()
> {
> Cost = 0;
> if (document.orderform.Item1.checked) { Cost = Cost + 119.95;
>}
> if (document.orderform.Item2.checked) { Cost = Cost + 75.00; }
> if (document.orderform.Item3.checked) { Cost = Cost + 14.95; }
> if (document.orderform.Item4.checked) { Cost = Cost + 50.00; }
> if (document.orderform.Item5.checked) { Cost = Cost + 9.95; }
> if (document.orderform.Item6.checked) { Cost = Cost + 4.95; }
> if (document.orderform.Item7.checked) { Cost = Cost + 50.00; }
> if (document.orderform.Item8.checked) { Cost = Cost + 7.95; }
> if (document.orderform.Item9.checked) { Cost = Cost + 1.00; }
>
> Cost = dollar(Cost); // REMOVE THIS LINE
> Grand_Total = parseFloat(Cost)
> Grand_Total = dollar(Grand_Total);
>
> document.orderform.GrandTotal.value = "\$" + Grand_Total;
> }
>

Phil McKraken
Guest
Posts: n/a

 10-29-2005
On 29 Oct 2005 11:05:04 -0700, Lee <(E-Mail Removed)> wrote:

>That's really just horrible code, and should be thrown away,
>but the simplest fix to your problem is to remove the line
>indicated below. Every time you call that ridiculous dollar()
>function you introduce more error, so don't call it without
>any reason. There's also no reason to use either parseFloat()
>or parseInt() in this code, but at least they're not causing
>the problem.

I appreciate the help and the sentiment regarding the code. I guess I
will have to find another one. I DID remove the line you suggested but
ALSO had to remove the "dollar" reference in the 2nd line down, with
Grand_Total.

Doing that caused the 9.95 and other **.95 items to display and add
ok. BUT, when you add ANY **.95 item to anything else (resulting in a
total that ends in "0" it drops off the "0".

I'm just not understanding enough of js yet to trouble shoot this.

Anyone know a better one ?

Thanks

Dr John Stockton
Guest
Posts: n/a

 10-29-2005
01.iinet.net.au>, dated Sat, 29 Oct 2005 23:44:47, seen in
news:comp.lang.javascript, RobG <(E-Mail Removed)> posted :
>
>The problem is your dollar() function, here is a link to some 'to money'
>conversion stuff:
>
> <URL:http://www.merlyn.demon.co.uk/js-maths.htm#Money>

<URL:http://www.merlyn.demon.co.uk/js-round.htm> is a more general
reference; and then there's the code in the FAQ.

--
Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
The Big-8 newsgroup management is attempting to legitimise its questionable
practices while retaining its elitist hegemony. Read <URL:news:news.groups>.

Dr John Stockton
Guest
Posts: n/a

 10-29-2005
JRS: In article <(E-Mail Removed)>, dated
Sat, 29 Oct 2005 12:36:50, seen in news:comp.lang.javascript, Phil
McKraken <(E-Mail Removed)> posted :
>I am having a problem putting together a shopping cart with the below
>script. Everything displays fine, adds totals fine, and works perfect
>EXCEPT if you choose the 9.95 item #5 BY ITSELF the total displayed is
>\$9.94 ! If you add ANYTHING else the total is correct, 9.95 plus
>whatever you add. That is the only price in these samples that is
>doing that. All the others display properly. If you change the 9.95 to
>ANY other number it displays correct.

You have tried all other numbers? For me, 19.65 gives 19.64.

> If you put 9.95 in any other
>position (Item number 1 instead of 5 etc. it does the same thing)
>

Read the newsgroup FAQ and what it cites.

Your conversion method, as well as being wrong, appears unnecessarily
large and slow. Delete your function "dollar"; euthanasia is the
kindest treatment for it.

Most scripts in Web repositories are trash; many are also bloatware.

--
<URL:http://www.jibbering.com/faq/> JL/RC: FAQ of news:comp.lang.javascript
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.

RobG
Guest
Posts: n/a

 10-30-2005
Phil McKraken wrote:
>>The problem is your dollar() function, here is a link to some 'to money'
>>conversion stuff:

>
>
> I tried the links you posted but, (: no luck. I am sure I am just
> doing it wrong. I got this sample from one of those javascript web
> repositories and I am not competent to change it to make it work. I am
> still learning and am not really a js writer, only a "cut n paste"
> trial & error modifier of what's there already.
>
> Can someone tell me what to do to fix this a little more specifically.

You really need to understand what the functions are doing and how they
work, else you will get errors like you have now. I hope you are
validating everything back at the server and only using the shopping

Anyhow, here's a couple of functions that may suit. They do no
validation at all and expect you to pass them suitable input. The first
expects to get dollars and never more than two decimal places, the
second expects integer cents.

<script type="text/javascript">

// This function expects to get dollars as either an integer
// or a float but never more than 2 decimal places
function toDollars(amt)
{
if (0 == amt) return '0.00';
amt += ''; // Convert amt to string
amt = amt.split('.');
if (1 == amt.length) amt[1]='00';
if (0 == amt[1].length) amt[1] += '00';
if (1 == amt[1].length) amt[1] += '0';
return amt.join('.');
}

// This function expects to get only integer cents
function centsToDollars(amt)
{
amt += ''; // Convert amt to string
if (1 == amt.length) return '0.0'+ amt;
if (2 == amt.length) return '0.'+ amt;
var dollars = amt.substring(0,amt.length-2);
var cents = amt.substring(amt.length-2);
return dollars + '.' + cents;
}

</script>
Play with toDollars<br>
<input type="text" onblur="
this.value = toDollars(this.value);
"><br>
Play with centsToDollars<br>
<input type="text" onblur="
this.value = centsToDollars(this.value);
">

</body></html>

[...]

--
Rob

Dr John Stockton
Guest
Posts: n/a

 10-30-2005
JRS: In article <(E-Mail Removed)>, dated Sat, 29 Oct
2005 13:45:09, seen in news:comp.lang.javascript, Randy Webb
<(E-Mail Removed)> posted :
>
>You are trying to round by multiplying by 100 and then dividing by 100.
>That introduces the error you see because computers cannot represent
>9.95 exactly in Base 2. So you get the error.

Non sequitur.

If the representation of 9.95, while not exact, had sufficient zeroes at
the end of the mantissa, then the multiplication would be exact, and the
division would be exact and would give the original value. There,
"sufficient zeroes" is a sufficient, but probably not entirely
necessary, condition.

If 9.95 being represented inexactly were the only criterion, then ISTM
that one would expect more wrong results than the OP's code actually
gives.

The real problem is that the OP's type of method effectively truncates
to cents using an inexact input; the input must be rounded to exact
cents, which has to be done into a representation where all such values
can be rendered exactly.

The ordinary conversions of a general Number to a String do that
rounding, as does the obvious one of the conversions to an integer Cent
number.

Note that one should always multiply or divide by 100 in preference to
dividing or multiplying by 0.01, since 100 is represented exactly but
0.01 is not.

--
Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
The Big-8 newsgroup management is attempting to legitimise its questionable
practices while retaining its elitist hegemony. Read <URL:news:news.groups>.