Reputation: 11
I am new to javascript and am trying to create a simple price calculator in javascript for my website (cupcake shop website). first, i have the user choose from a list of flavor choices and post that to a textarea, when the user selects vegan flavors, i would add $3.50 to the end when posting to the textarea, and when the user selects non vegan, the price is $2.75. everything posted to the textarea are strings. so for the calculator, I extract the last 5 characters (which is the price) and add them up to get a subtotal. I used a loop to go thru the list in the textarea to extract the numbers one by one and add them up, however, the calculation came out wrong. Can anyone tell me what is wrong with it???
function addOption(selectbox,text,value )
{
var optn = document.createElement("OPTION");
optn.text = text;
optn.value = value;
selectbox.options.add(optn);
}
function addOption_list(selectbox){
var flavors = new Array("blueberry vegan","butterscotch","cappuccino vegan","carrot
cake","carrot vegan","chocolate walnut vegan",
"chocolate peanut butter vegan","green tea & chocolate","keylime","lavender
vegan","lemon","lemon cream vegan","mandarin orange",
"mint chocolate","mocha","peanut butter & double chocolate","raspberry swirl","red
velvet","sesame","sesame oreo",
"strawberry","strawberry 2 vegan","tangerine","thia tea","triple
chocolate","vanilla","very berry","vietnamese coffee","yuzu");
for (var i=0; i < flavors.length;++i){
addOption(document.drop_list.flavors_list, flavors[i], flavors[i]);
}
}
var $ = function (id){
return document.getElementById(id);
}
var cart = [];
var update_cart = function(){
if(cart.length == 0){
$("flavor_name").value = "";
} else{
var list = "";
for(var i in cart){
list += (parseInt(i) +1) + ". " + cart[i] + /*": $3.50" + */ "\n";
}
$("flavor_name").value = list;
var sum = 0;
for(var i = 0; i < cart.length; i++){
var price = parseFloat(list.substring(list.length - 5));
sum += parseFloat( price.toFixed(2) );
}
$("subtotal").value = sum;
var tax = parseFloat(($("subtotal").value * .08875).toFixed(2));
$("sales_tax").value = tax;
var total = parseFloat(price + tax).toFixed(2);
$("total").value = total;
}
}
var selectDropdown = function(){
var dropdownValue=document.getElementById("flavors_list").value;
// alert("You selected : " + dropdownValue);
if(dropdownValue == "blueberry vegan" || dropdownValue == "cappuccino vegan" ||
dropdownValue == "carrot vegan" || dropdownValue == "carrot vegan" ||
dropdownValue == "chocolate walnut vegan" || dropdownValue == "chocolate peanut
butter vegan" || dropdownValue == "lavender vegan" || dropdownValue == "lemon
cream vegan" || dropdownValue == "strawberry 2 vegan"){
alert("Adding " + dropdownValue + " to cart.");
cart[cart.length] = dropdownValue + ": $3.25";
update_cart();
} else{
alert("Adding " + dropdownValue + " to cart.");
cart[cart.length] = dropdownValue + ": $2.75";
update_cart();
}
}
HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Home-Little Sweetie Cupcakes</title>
<link href="little_sweetie_styles.css" rel="stylesheet" type="text/css" />
<link rel="Shortcut Icon" href="favicon.ico" />
<script type="text/javascript" src="invoice.js"></script>
</head>
<body onLoad="addOption_list()";>
<div class="cart_content">
<span class="content_title">
Price Calculator
</span>
<p class="bodytext">To place an order, please enter the desired flavor from
the dropdown list:</p>
<FORM name="drop_list" action="yourpage.php" method="POST" >
<SELECT NAME="flavors_list" id="flavors_list"
onchange="selectDropdown()">
<Option value="" >Flavors List</option>
</SELECT>
</form>
<div>
<!--<textarea id="shopping_cart" rows="5" cols="50"></textarea>-->
<table id="invoice">
<tr>
<td width="150"><textarea id="flavor_name" rows="10" cols="40"
disabled="disabled" /></textarea></td>
<td> </td>
<td id="calculator">
<label class="bodytext">Subtotal: </label><input
type="text" id="subtotal" size="10" disabled="disabled"
/><br />
<label class="bodytext">Sales Tax: </label><input
type="text" id="sales_tax" size="10"
disabled="disabled" /><br />
<label class="bodytext">Total: </label><input type="text"
id="total" size="10" disabled="disabled" /><br />
</td>
</tr>
</table>
</body>
</html>
Thanks in advance
Upvotes: 1
Views: 208
Reputation: 707328
I see multiple issues in your code, but without a working example to look at where we can see the actual HTML and values, it's hard to know for sure what all the issues are. Here are some of the issues:
parseInt()
should always be passed the second parameter (the radix) otherwise it will guess what the radix is based on the content.for (x in a)
to iterate the contents of an array. That can include properties that are added to the array in addition to the array elements. It is much safer to use for (var i = 0; i < array.length; i++)
.parseInt()
nor parseFloat()
will tolerate a $
in the string so you must remove those first.In this block of code, it's unclear what you're trying to iterate. Every pass through the for
loop is just using the same value of list
. It's not iterating an array.
for(var i = 0; i < cart.length; i++){
var price = parseFloat(list.substring(list.length - 5));
sum += parseFloat( price.toFixed(2) );
}
FYI, it's much safe to extract a number from the end of your string like this:
function getNumber(str) {
var matches = str.match(/([\d\.]+)\s*$/)
if (matches) {
return (+matches[1]);
}
return(0);
}
var str = "xxx $99.45\n";
var num = getNumber(str);
Upvotes: 2
Reputation: 664513
for(var i in cart)
You should traverse the array with a for-loop and a counting variable, as you do below. Additional benefit: No need to parseInt
the property names.
I extract the last 5 characters (which is the price) and add them up to get a subtotal:
for(var i = 0; i < cart.length; i++){
var price = parseFloat(list.substring(list.length - 5));
sum += parseFloat( price.toFixed(2) );
}
Yes, for every item in cart
you get the price out of the last five characters of the (same) list
string. WTF?
What you wanted was to get the price for each item in the cart. And I'm quite sure there are not only <$10 items which have only 4 characters in their string representation. So, remove the first character (the dollar sign) of a cart item and apply parseFloat
on that:
for (var i=0; i<cart.length; i++) {
var price = parseFloat(cart[i].substring(1));
sum += price;
}
Also, you should not use parseFloat( price.toFixed(2) );
. Apart from some IE bugs, floating point maths will never be reliable, and does not get better when constantly rounding. Instead compute with the integer number of cents (although JS technically has no integers):
var price = Math.floor(parseFloat(str, 10) * 100);
Upvotes: 1