Jump to content
Larry Ullman's Book Forums

Shopping Calculator


Recommended Posts

Hi everyone

 

I am working through the book again and am really having trouble getting my head round the shopping calculator (shopping.html, page 103), so would be grateful if you would review my comments to say if I have understood it correctly:.......

 

*****MY COMMENTS ARE LIKE THIS*************

 

--------------------------------------------------------------------------------------------------------------------------------------

*****THIS IS LARRY'S HTML - 'shopping.html'*********

<!doctype html>

<html lang="en">

<head>

<meta charset="utf-8">

<title>Shopping Calculator</title>

<!--[if lt IE 9]>

<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>

<![endif]-->

<link rel="stylesheet" href="css/styles.css">

</head>

<body>

<!-- shopping.html -->

*****THE COMMAND '<form action=' WILL SEND AN ARRAY, ON SUBMITTING OF THE FORM, OF THE 5 VARIABLES, EACH WITH ITS VARIABLE NAME (E.G. "quantity, 4") BY METHOD "POST" WHICH WILL BE "INTERCEPTED" BY THE JS SCRIPT**********

<form action="" method="post" id="theForm">

<fieldset>

<p>Use this form to calculate the order total.</p>

<div><label for="quantity">Quantity</label><input type="number" name="quantity" id="quantity" value="1" min="1" required></div>

<div><label for="price">Price Per Unit</label><input type="text" name="price" id="price" value="1.00" required></div>

<div><label for="tax">Tax Rate (%)</label><input type="text" name="tax" id="tax" value="0.0" required></div>

<div><label for="discount">Discount</label><input type="text" name="discount" id="discount" value="0.00" required></div>

<div><label for="total">Total</label><input type="text" name="total" id="total" value="0.00"></div>

<div><input type="submit" value="Calculate" id="submit"></div>

</fieldset>

</form>

****NOW CALL THE JAVASCRIPT********

<script src="js/shopping1.js"></script>

</body>

</html>

 

 

 

******THIS IS NOT THE JS USED BY THE HTML BUT IS ESSENTALLY IDENTICAL EXCEPT WITH MORE OF LARRY'S COMMENTS.*************

// Script 4.2 - shopping.js

// This script calculates an order total.

 

// Function called when the form is submitted.

// Function performs the calculation and returns false.

******THIS STARTS THE FUNCTION THAT WILL BE CALLED AT THE END BY THE VARIABLE 'theForm' (MORE ABOUT THAT LATER).**********

function calculate() {

'use strict';

 

// For storing the order total:

******'total' IS A SIMPLE VARIABLE TO STORE THE DECIMAL NUMBER THAT WILL RESULT FROM THE CALCULATION***********

var total;

******MOVE THE VARIABLES FROM "POST" TO JS***************

// Get references to the form values:

var quantity = document.getElementById('quantity').value;

var price = document.getElementById('price').value;

var tax = document.getElementById('tax').value;

var discount = document.getElementById('discount').value;

 

// Add validation here later!

 

// Calculate the initial total:

total = quantity * price;

 

// Make the tax rate easier to use:

tax /= 100;

tax++;

 

// Factor in the tax:

total *= tax;

 

// Factor in the discount:

total -= discount;

 

// Display the total:

document.getElementById('total').value = total;

 

// Return false to prevent submission:

return false;

 

} // End of calculate() function.

*****NOW WRITE THE LISTENER*********

// Function called when the window has been loaded.

// Function needs to add an event listener to the form.

function init() {

'use strict';

 

// Add an event listener to the form:

*****AND THIS IS WHERE I HAVE A PROBLEM........WHY ARE WE CALLING ALL OF THE DATA AGAIN BY WAY OF 'theForm'? IS 'document.getElementById('theForm')' CALLING THE WHOLE POST ARRAY AND WHY?

var theForm = document.getElementById('theForm');

*****CALL THE "calculate" FUNCTION*****

theForm.onsubmit = calculate;

 

} // End of init() function.

*****THIS CALLS THE "init" FUNCTION WHEN THE WINDOW LOADS******

// Assign an event listener to the window's load event:

window.onload = init;

 

---------------------------------------------------------------------------------------------------

 

The only other possibility that I can think of is that "var theForm = document.getElementById('theForm');" calls an array from POST that includes all of the variables stated above, and then passes them to the "calculate" function as required.

 

To put the question another way, is the variable e.g. "quantity" - the actual number - received directly from POST or secondarily from the array "theForm"?

 

I imagine the variable "the.Form" to look like this:

 

quantity,4

price,45.67

tax,20

discount,10.00

total,0.00

 

 

Any comments and advice would be greatly appreciated.

 

Regards

 

Max

Link to comment
Share on other sites

Hi Max,

 

JavaScript is NOT reading the POST array, since that is sent to the server and JS is all happening on the client side. JS is getting the values by referencing the form elements when the function calculate() is called:

function calculate() {
'use strict';

///// This is where the form element values are read by JS /////
// For storing the order total:
var quantity = document.getElementById('quantity').value;
var price = document.getElementById('price').value;
var tax = document.getElementById('tax').value;
var discount = document.getElementById('discount').value;

///// snipping off the last part of the function /////
}

 

The function is not called until the onsubmit event occurs. onsubmit() is a method of the object form. The line var theForm=document.getElementById('theForm') is simply assigning a varaible name to the form object with an id of 'theForm.' You could have more than one form on the page with different id's, but the listener is set to only listen for that one form object.

 

The listener could also have been written as:

document.getElementById('theForm').onsubmit = calculate;

 

Hope that helps clarify it for you.

  • Upvote 1
Link to comment
Share on other sites

Hi there

 

Sorry - but another problem with shopping1.js! As a learning process, I decided to mess about with the script so that the discount can be expressed as a percentage instead of an amount.

All works well except that if I put in the following line (marked with asterisks below) the script crashes, by which I mean that js just fills the windows with zeros:....

 

total = total.toFixed(2);

 

I even included the line 'total = total * 1' in case js was looking at total as a string variable but it still crashes.

 

The command 'document.getElementById('total').value = total.toFixed(2)' works fine.

 

Totally baffled!!!!!

 

-------------------------------------------------------------------------------------------

// Script 4.2 - shopping.js

// This script calculates an order total.

 

// Function called when the form is submitted.

// Function performs the calculation and returns false.

function calculate() {

'use strict';

 

// For storing the order total:

var total;

 

// Get references to the form values:

var quantity = document.getElementById('quantity').value;

var price = document.getElementById('price').value;

var tax = document.getElementById('tax').value;

var discount = document.getElementById('discount').value;

 

// Add validation here later!

 

// Calculate the initial total:

total = quantity * price;

 

//Calculate the discount:

discount /= 100;

 

// Factor in the discount:

total = total - (total * discount);

 

// Make the tax rate easier to use:

tax /= 100;

tax++;

 

// Factor in the tax:

total *= tax;

 

// Format the total:

total = total * 1;

****Crashes here:....**** total = total.toFixed(2);

 

// Display the total:

****This works:-----****document.getElementById('total').value = total.toFixed(2);

 

// Return false to prevent submission:

return false;

 

} // End of calculate() function.

 

// Function called when the window has been loaded.

// Function needs to add an event listener to the form.

function init() {

'use strict';

 

// Add an event listener to the form:

var theForm = document.getElementById('theForm');

theForm.onsubmit = calculate;

 

} // End of init() function.

 

// Assign an event listener to the window's load event:

window.onload = init;

 

-------------------------------------------------------------------------------------------

 

Would appreciate an explanation.

 

From confused of Spain.

Link to comment
Share on other sites

Hi Larry

'With total = total.toFixed(2);' included in the script, the results (irrespective of what you enter) are:

Quantity: 1

Price per unit: 1.00

Tax Rate (%): 0.0

Discount (%): 0.00

Total: 0.00

It does this in IE8, Chrome and Firefox 11.

I have attached the actual js file for you to try.

 

Best regards

Max

 

shopping1.js:......

// Script 4.2 - shopping.js

// This script calculates an order total.

// Function called when the form is submitted.

// Function performs the calculation and returns false.

function calculate() {

'use strict';

 

// For storing the order total:

var total;

 

// Get references to the form values:

var quantity = document.getElementById('quantity').value;

var price = document.getElementById('price').value;

var tax = document.getElementById('tax').value;

var discount = document.getElementById('discount').value;

// Add validation here later!

 

// Calculate the initial total:

total = quantity * price;

 

//Calculate the discount:

discount /= 100;

 

// Factor in the discount:

total = total - (total * discount);

 

// Make the tax rate easier to use:

tax /= 100;

tax++;

 

// Factor in the tax:

total *= tax;

// Format the total:

total = total * 1;

total = total.toFixed(2);

 

// Display the total:

document.getElementById('total').value = total.toFixed(2);

 

// Return false to prevent submission:

return false;

 

} // End of calculate() function.

// Function called when the window has been loaded.

// Function needs to add an event listener to the form.

function init() {

'use strict';

// Add an event listener to the form:

var theForm = document.getElementById('theForm');

theForm.onsubmit = calculate;

} // End of init() function.

// Assign an event listener to the window's load event:

window.onload = init;

Link to comment
Share on other sites

The error is because you're calling the toFixed method twice. You call it once on the following line:

total = total.toFixed(2);

 

And then you take total (which is equal to the string '1.00' after the above line), and run the toFixed method on that string, which is not possible because the toFixed method is a Number method. Change the following line and you should be fine:

document.getElementById('total').value = total.toFixed(2); -> document.getElementById('total').value = total;

 

Please lemme know if that works.

Link to comment
Share on other sites

Hi HartleySan

 

Many thanks - I came to the same conclusion by reading the book again vis:....

 

Hi Larry

 

I think that I have resolved it.

 

I think it is because when you assign 'tofixed(n)' to a variable it becomes a string (1st para, page 154).

 

If I change:.......

 

// Display the total:

document.getElementById('total').value = total.toFixed(2);

 

...to:.....

 

// Display the total:

document.getElementById('total').value = total;

 

....then it works!

 

Again, many thanks

 

Max

Link to comment
Share on other sites

 Share

×
×
  • Create New...