Fake chocolate store example

Today's example program implements part of the check-out process for an imaginary chocolate shop. On this page we will pretend that a customer has already selected some delectable items and generated an order subtotal, and they now need to enter some final order details before advancing to the payment page.

The HTML select element

Today's example will make use of another new HTML element, the <select> element. This element presents the user with a menu of choices that they can make a selection from.

Here is the select element that the page uses to present the user with a list of options for shipping:

<select class="form-control" id="shipping">
    <option value="store">Store Pickup</option>
    <option value="ground">Ground Shipping</option>
    <option value="express">Express Shipping</option>
</select>

A <select> is a container for a list of <option> elements. Each <option> has some content text: this is the text the user will see in the menu. Each <option> also has a value attribute. When the user makes a selection from the menu, we will use JavaScript to fetch the value from the menu.

JavaScript for this example

The JavaScript file for this example starts by declaring a variable that holds the one piece of initial data we start with, the order subtotal:

var subtotal = 24.95; // A fake subtotal value to work with

Much like the first example program we studied, this program has a setup function that attaches an event handler function to the "Compute Total" button:

function setup() {
    var subtotalSpan, computeButton;
    
    subtotalSpan = document.getElementById('subtotal');
    subtotalSpan.textContent = '$' + subtotal;
    
    computeButton = document.getElementById('compute');
    computeButton.addEventListener('click',computeHandler,false);
}

window.addEventListener('load',setup,false);

Most of the action in this example takes place in the computeHandler function, which is the event handler function for the "Compute Total" button. The purpose of these notes is to explain the code that does the computations in that function.

Basic data manipulations

Today's example is the first program we will encounter that needs to do basic computations, including arithmetic. This section of the notes will cover the basic mechanics of arithmetic and other simple data manipulations in JavaScript.

Arithmetic operations

JavaScript uses the following symbols for the four basic arithmetic operations.

operatormeaning
+addition
-subtraction
*multiplication
/division

For example, to apply a 10% discount to the initial subtotal we multiply the subtotal by 0.90:

total = 0.90 * subtotal;

In another example we charge $8.95 for ground shipping by adding this amount to the total due:

total = total + 8.95;

This last example may seem strange to you if you are used to conventional mathematical notation. In conventional mathematical notation the = symbol stands for equality. In JavaScript the = operator stands for the assignment command: this is a command to compute the new quantity on the right hand side of the = and then assign it to the variable that appears on the left hand side of the =. When used this way, the = operator is used to update the value of a variable (often using its old value as one of the inputs).

Text data and the concatenation operation

We saw in the first example program that JavaScript can work with text. There are two ways to get text data into a JavaScript variable. One method is to read some text the user has typed into a text field. In today's example I set up an input element where the user could enter a discount code.

<input type="text" class="form-control" id="discount" />

To read the text the user entered and store that text in a variable we could use the following JavaScript code:

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

Another way to get text into a variable is by assigning a text literal value to it.

discountCode = 'none';

Any text inside single or double quotes in a JavaScript program is a text literal.

The one operation that text data in JavaScript supports is the text concatenation operation. In this operation we use the + operator to 'glue together' several pieces of text to make a new text string. We used the text concatenation operator in the first example program to paste together a greeting string containing the user's name:

greeting = 'Hello, ' + name + '. Welcome to JavaScript!';

Magic code

Occasionally in these code examples I will need to use a more advanced technique to solve a problem. Often these advanced techniques will make use of concepts that we have not yet had a chance to fully explore, so the code in question will be beyond your present ability to comprehend.

In today's example I will need to take the total that the computation produces and format it properly for display. This will mean rounding the dollar amount of the total to the nearest penny and formatting it with the leading $ symbol and exactly two digits after the decimal point. To do this I use the following code:

// Create a number formatter.
formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
  minimumFractionDigits: 2,
});
  
// Present the result
dollarAmount = formatter.format(total);
resultText.textContent = 'Your total is ' + dollarAmount + '.';

This snippet of code makes use of a more advanced concept, the number formatter object. By passing the total to that object's format method we can successfully convert the number value in the total variable to an appropriate text value for display.

Even though you may not fully understand how a particular bit of magic code works, you often will know enough about what it does to be able to copy and paste that code into your own projects. The first JavaScript assignment coming up will require you to format a dollar value for display, so you are welcome to copy and paste this code to help you with that.

The if-else statement

The basic construct in JavaScript for making decisions and acting on different cases is the if-else statement. The basic form of the if-else statement is this:

if(<test>)
{
  // Statements to execute if <test> is true
}
else
{
  // Statements to execute if <test> is false
}

The if-else statement begins by performing a test whose outcome can be either true or false. If the outcome of the test is true, the set of statements inside the first pair of curly braces gets executed. Otherwise, the statements in the second pair of statements will get executed. Once the statements in the selected branch have run, execution continues with the next statement after the if-else.

The most common way to form tests for an if-else statement is by using comparison operators. Here is a table of the available comparison operators.

operatormeaning
==is equal to
!=is not equal to
<is less than
>is greater than
<=is less than or equal to
>=is greater than or equal to

Note especially the == comparison test. A very common mistake that beginning programmers will make is to us = in place of == in a test. = means 'set the thing on the left to the value on the right' and not 'compare the thing on the left with the thing on the right.'

Here is an example from today's example page. In this example we have to compute the final amount due for an online transaction starting from a subtotal of items ordered. The first thing that may affect the total due is whether or not the user has entered a valid discount code. The following if-else statement does that check and updates the total appropriately:

if(discountText.value == 'SWEET10') {
  // 10% discount for entering a discount code
  total = 0.90 * subtotal;
} else {
  // No discount to the subtotal
  total = subtotal;
}

Variant Forms

JavaScript also allows the if-else statement to be constructed in a variety of variant forms. The first variant is that if a branch of the if-else statement contains a single statement the curly braces are optional. If we were willing to leave off the comments, the last example could be simplified to read

if(discountText.value == 'SWEET10')
  total = 0.90 * subtotal;
else
  total = subtotal;

(Please note that if you have more than one statement in one of the branches you must use the curly braces. If you don't you will probably generate a nasty and hard-to-find logic error in your script.)

Another variant is that if the else part of the if-else is empty you can leave it off completely. This makes it possible to rewrite the example above as

total = subtotal;
if(discountText.value == 'SWEET10')
  total = 0.90 * total; // Apply a 10% discount to the total

Nested if-else statements

In some situations we will need to ask multiple questions to fully resolve a situation. The most common example of this situation happens when more than two cases can apply in the situation. For example, in the today's example customers can pick from three different shipping methods: in-store pickup, ground shipping, or express shipping.

By placing one if-else construct inside another we can ask more than one question and thus resolve which category applies. Here is a nested if-else construct that can resolve the shipping cost problem:

if(shippingSelector.value == 'ground') {
  // Ground shipping is 8.95
  total = total + 8.95;
} else {
  if(shippingSelector.value == 'express') {
    // Express shipping is 14.95
    total = total + 14.95;
  }
}

The nested if-else construct most often gets rewritten by applying the "optional curly braces" rule. Since an if-else statement is technically a single, large statement, the curly braces on the else branch of the outer if-else above are optional:

if(shippingSelector.value == 'ground') {
  // Ground shipping is 8.95
  total = total + 8.95;
} else
  if(shippingSelector.value == 'express') {
    // Express shipping is 14.95
    total = total + 14.95;
  }

This in turn makes it possible to reformat the construct as

if(shippingSelector.value == 'ground') {
  // Ground shipping is 8.95
  total = total + 8.95;
} else if(shippingSelector.value == 'express') {
    // Express shipping is 14.95
    total = total + 14.95;
}

This latter form is commonly called a chained if-else construct.