Simple Price Calculator

I am trying to learn Javascript (I’m a PHP developer) and I’ve written a simple script that I believe is most of the way to what I need.

Its very basic, I have 3 option inputs, first is quantity then 2 add-ons which both default to 0. Then a subtotal would populate beneath based on user input. Default is first option of quantity (25 in this case).

I defined arrays for the 3 option inputs, then assigned a variable to each one via getElementbyID … then I would simply add them together and here I know my syntax is off. (It’s the syntax of JS that I haven’t been able to get my head around)

If someone can give me a quick logic guideline as to how and WHY … that’s what I’m looking for. Thx.

My code is below:

 <script>
 var card_qty = new Array();
 card_qty["25"]=65.00;
 card_qty["50"]=120.00;
 card_qty["75"]=150.00;

  var return_address_qty = new Array();
 return_address_qty["0"]=0.00;
 return_address_qty["25"]=12.00;
 return_address_qty["50"]=20.00;
 return_address_qty["75"]=30.00;

 var liners_qty = new Array();
 liners_qty["0"]=0.00;
 liners_qty["25"]=12.00;
 liners_qty["50"]=20.00;
 liners_qty["75"]=30.00;

 var qty = document.getElementById('card_qty')
 var ret_add = document.getElementById('return_qty')
 var liners = document.getElementById('liners_qty')

 function calculatesubtotal() {}
 var subtotal = qty + ret_add + liners; // this is clearly wrong!!

    var amount = document.getElementById('subtotal');
    amount.style.display='block';
    amount.innerHTML = "Subtotal: $"  ++subtotal ++; // and how to reference the subtotal dynamcally is my other question ...

 }
 </script>

 <div id="price_calculator">
    <h2>PRICE CALCULATOR</h2>
    <label>Choose Qty:
   <select id="qty" name="qty">
        <option value="25">25@$65.00</option>
        <option value="50">50@$120.00</option>
        <option value="75">75@$170.00</option>
    </select></label><br>
   <label>Add return address printing:&nbsp;
   <select id="option1qty" name="option1_qty">
        <option value="0"></option>
        <option value="25">25@$12.00</option>
        <option value="50">50@$22.00</option>
        <option value="75">75@$30.00</option>
    </select></label><br>
    <label>Add assembled liners:
      <select id="option2qty" name="option2_qty">
        <option value="0"></option>
        <option value="25">25@$25.00</option>
        <option value="50">50@$50.00</option>
        <option value="75">75@$75.00</option>
    </select></label><br><br>
    <h5>Subtotal: <span id="subtotal">$101.00</span></h5>
</div>

There are a number of problems, so let’s go through them step by step.

The calculatesubtotal() function doesn’t currently run, so you need to run it whenever one of the fields gets changed, and also when the page first loads. In order to do that most easily, move the script to the end of the body, just before the </body> tag. Putting your script at the bottom is a best-practice to help speed up the loading of your page, and it also allows the script to most easily work with the elements on the page.


<html>
<head>
    ...
</head>
<body>
    ...
    <script type="text/javascript" src="script.js"></script>
</body>
</html>

Once it’s there, you need to tell your price calculator to calculate the subtotal whenever something changes. You can also trigger that onchange event when the page first starts, so that it updates the subtotal then too.


var priceCalculator = document.getElementById('price_calculator');
priceCalculator.onchange = calculatesubtotal;
priceCalculator.onchange();

Next, the arrays aren’t needed at all. You can instead place the price in the option value attribute, so that the script can obtain what it needs directly from there.


<option value="65">25@$65.00</option>
<option value="120">50@$120.00</option>
<option value="170">75@$170.00</option>

How the script does that, is to get the quantity, return address, and the assembled liners, as the first part of the calculatesubtotal function.

Because they are strings, and we want to use them as numbers, we can retrieve the value from the selected option and convert it to a number. If it doesn’t result in a valid number we can instead use a default value of 0.


function calculatesubtotal() {
    var qty = Number(document.getElementById('card_qty').value) || 0;
    var ret_add = Number(document.getElementById('return_qty').value) || 0;
    var liners = Number(document.getElementById('liners_qty').value) || 0;

With that preparation in place, the subtotal can be easily worked out.


var subtotal = qty + ret_add + liners;

I don’t follow why you set the subtotal element to a block layout. In testing, that seems to break things, so you should be able to do without that part completely.

This part too doesn’t seem to make sense:

amount.innerHTML = "Subtotal: $"  ++subtotal ++;

Because the “Subtotal:” label is not a part of the span that contains the amount:


<h5>Subtotal: <span id="subtotal">$101.00</span></h5>

So the amount can instead be easily produced by adding a dollar symbol on to the calculated subtotal. You can even use the .toFixed() method to ensure that the displayed value is shown at two decimal places.


amount.innerHTML = "$" + subtotal.toFixed(2);

It took a couple of days for me to get back to this part of my project but I really appreciate the response and the level of detail in it.

I’m grasping the logic of what you did. First retrieving the value, then converting it into a number. And I see that var subtotal should be set to the correct value.

But then it needs to be inserted into the subtotal id - doesn’t it? With my element set as:

<h5>Subtotal: <span id="subtotal">$101.00</span></h5>

the line of code:

amount.innerHTML = "$" + subtotal.toFixed(2);

only defines the value of var subtotal within the script. The final step is to get the element again …

document.getElementById('subtotal') =

but

document.getElementById('subtotal') = amount.innerHTML = "$" + subtotal.toFixed(2);

is not working for me. Shouldn’t the placement of the .innerHTML be at the end of the getElementById … ?

It’s the final step, right?

The first part of that shouldn’t be there,

It should instead be:


amount.innerHTML = "$" + subtotal.toFixed(2);

Which will work due to the amount variable being declared as being the appropriate element earlier on in the code.

That’s where I got confused because what I read from your first post … the script I put together was:

var priceCalculator = document.getElementById('price_calculator');
priceCalculator.onchange = calculatesubtotal;
priceCalculator.onchange();

function calculatesubtotal() {
    var qty = Number(document.getElementById('card_qty').value) || 0;
    var ret_add = Number(document.getElementById('return_qty').value) || 0;
    var liners = Number(document.getElementById('liners_qty').value) || 0;

    var subtotal = qty + ret_add + liners;
    amount.innerHTML = "$" + subtotal.toFixed(2);
    }

So I didn’t see where you declared amount earlier …

My post was only indicating changes to your code. It wasn’t prescribing full complete changes.

Here is the line from your original code:


 function calculatesubtotal() {}
 var subtotal = qty + ret_add + liners; // this is clearly wrong!!
 
    [color="green"]var amount = document.getElementById('subtotal');[/color]
    amount.style.display='block';
    amount.innerHTML = "Subtotal: $"  ++subtotal ++; // and how to reference the subtotal dynamcally is my other question ...

 }

doh! Sorry … Thx again!!