Chapter 8
Making Choices in JavaScript
In This Chapter
Considering when to make a decision
Using the if structure to make decisions
Using the switch structure to make decisions
Decisions, decisions — life is all about decisions. Because applications mimic real life in many respects, your application needs to make lots of decisions too. However, unlike the impromptu decisions you make, applications require preprogrammed decisions. You decide in advance which decisions the application makes and for what reasons. In addition, you decide under what conditions the application makes the decisions and what happens when a certain decision path is taken. The only variable is the data used to make the decision — you can’t easily control the data, which is why you need a decision-making technique in the first place.
Application decisions are expressed as statements. A statement consists of a keyword, which is followed by an expression that defines the decision to make. Following the statement is a code block that contains one or more tasks to perform when an expression is true. The combination of the statement and the code block is called a structure. Consequently, when you discuss the if
statement, you're talking about the combination of keywords and expression that makes the decision. On the other hand, when you discuss the if
structure, you mean the combination of the statement and the code block that follows.
Understanding the Reasons for Applications to Make Decisions
In a perfect world, the data your application receives would never change, and you would create a precise procedure for handling it that never varies. In such a situation, you’d never need to make a decision because everything would be straightforward and never vary. Unfortunately, real data will change, which means your application must provide a flexible means for dealing with it. Applications commonly make decisions for the following reasons:
Address a go-or-no-go scenario where the data is either inside or outside the expected range
Test whether a condition has occurred
Handle a number of data range selections where each data range requires a different procedure
Enable the user to choose a specific action
Create a menu where the user can choose from a number of actions
Determine when an error has occurred
Handle environmental conditions that are neither good nor bad, but which do require the application to react in specific ways
Provide a randomized environment for training or other purposes
As in life, many application decisions are black and white — either/or situations where you choose one thing or another. The if
statement is commonly used to make these sorts of decisions. Something is true or it isn't — there's no middle ground. In some cases, the developer needs only to address a situation that's true, such as when an error occurs. In other cases, the developer needs to provide two separate courses of action depending on whether the expression is true or not.
Sometimes a decision isn't black and white. In this case, you can combine if
statements to create a series of small black-and-white decisions that ultimately end up choosing a shade of gray, or you can use the switch
statement. The switch
statement is a kind of menu; based on the data the application receives, it can choose from a number of potential courses of action. The switch
statement helps your application handle shades of gray situations.
Deciding When to Use the if Statement
The if
statement appears a number of times in previous chapters, which should tell you something about working with the if
statement — you really can't escape using it. The if
statement is commonly used for testing whether something has happened or not, whether the data is in range or not, or whether the user wants to perform a specific task. The following sections describe the if
statement in more detail and help you understand the full range of tasks it can perform.
Creating a simple if statement
One of the most common uses of the if
statement is to make a simple selection. When the user takes a particular action, something happens. In the following example, when the user clicks OK in the confirm dialog box, the application displays the secret message. (You can find complete code for this example in the Chapter 08IfStatement
folder of the downloadable code as SimpleIf.HTML
.)
// Create an expression that results in true or false.
var Answer = confirm(
"Do you want to display the secret message?");
nbps;
// Test the expression using the if statement.
if (Answer)
{
// Display the secret message when the user
// clicks OK.
document.getElementById("Result").innerHTML =
"This is the secret message!";
}
In this case, Answer
can contain only true
or false
because confirm()
doesn't output any other values. As a consequence, you don't need to perform any sort of value checks on Answer
— all you need to do is determine the truth value of Answer
to make the decision.
Deciding what else to do
As noted in the previous section, you use the if
statement in situations when an application needs to do something when the user responds correctly, but ignore the input when the response is incorrect. However, there are times when you must do something when the input is correct and something else when it's incorrect. In this case, you add the else
clause to the if
statement as shown in the following example. (You can find complete code for this example in the Chapter 08IfStatement
folder of the downloadable code as SimpleIfElse.HTML
.)
// Create an expression that results in true or false.
var Answer = confirm(
"Do you want to display the secret message?");
nbps;
// Test the expression using the if statement.
if (Answer)
{
// Display the secret message when the user
// clicks OK.
document.getElementById("Result").innerHTML =
"This is the secret message!";
}
else
{
// Perform an alternative task.
alert("Click OK next time to see the message!");
}
Nesting if statements
There are many reasons why you might nest if
statements — that is, place one if
statement within another. The following example shows one situation, which leads into the switch
statement examples later in the chapter. In this case, the user selects an option onscreen, CheckChoice()
performs a check of that option, and then CheckChoice()
displays the correct result onscreen. (You can find complete code for this example in the Chapter 08IfStatement
folder of the downloadable code as NestedIf.HTML
.)
function CheckChoice(option)
{
// Verify that the input is a number.
if (typeof(option) != "number")
{
// Display an error dialog.
alert("Please provide numeric input!");
// Return without doing anything more.
return;
}
// Ensure that option is actually an integer.
var Select = Math.round(option);
// Verify that the input is in range.
if ((Select < 1) || (Select > 3))
{
// Display an error dialog.
alert("The value supplied is out of range!");
// Return without doing anything more.
return;
}
// Make a selection.
if (Select == 1)
{
document.getElementById("Result").innerHTML =
"You chose Item A.";
}
else
{
if (Select == 2)
{
document.getElementById("Result").innerHTML =
"You chose Item B.";
}
else
{
document.getElementById("Result").innerHTML =
"You chose Item C.";
}
}
}
This example doesn’t rely on a known source of input, so it begins by performing various checks of the data. The first check verifies that the caller has supplied a numeric value. After all, the caller could provide a string or a Boolean value instead. For that matter, the input could be a pointer to another function or anything else that JavaScript supports — you just don’t know.
At this point, you know you have a number and that the number is an integer, but you don't know whether the number is in the correct range. A failure to range-check input values is the cause of many woes in JavaScript applications. CheckChoice()
is expecting integer values in the range of 1 to 3, so the range check looks for these values.
The nested if
statement is almost anticlimactic at this point. You know that Select
contains 1
, 2
, or 3
. The first if
statement checks for a value of 1 and displays a message when it finds that value. When the value is something other than 1, the else
clause takes over. Within the else
clause is a nested if
statement. This if
statement checks Select
for a value of 2
and displays the appropriate message when it is. When Select
is 3
, the else
clause of this second, nested, if
statement displays the appropriate message. Figure 8-1 shows typical output from this example.
Figure 8-1: The example provides a number of buttons to test various conditions.
Switching Between Choices
Although the if
statement is commonly used for simple choices, the switch
statement is used to handle a range of choices. A switch
provides an elegant way to handle variable data. The following sections describe two forms of switch
statement. The first provides the means for working with a predefined range of choices, and the second provides the means for working with data that could contain unexpected information. This second form makes the switch
statement particularly useful because users are unpredictable, and this second form can take such users into account.
Creating a basic switch
Many developers prefer switch
statements over nested if
statements because the switch
statements are easier to understand. A switch
statement also requires less typing to obtain the same result. The following example replicates the example shown in the Nesting if statements section, earlier in this chapter. (You can find complete code for this example in the Chapter 08SwitchStatement
folder of the downloadable code as SimpleSwitch.HTML
.)
function CheckChoice(option)
{
// Verify that the input is a number.
if (typeof(option) != "number")
{
// Display an error dialog.
alert("Please provide numeric input!");
// Return without doing anything more.
return;
}
// Ensure that option is actually an integer.
var Select = Math.round(option);
// Verify that the input is in range.
if ((Select < 1) || (Select > 3))
{
// Display an error dialog.
alert("The value supplied is out of range!");
// Return without doing anything more.
return;
}
// Make a selection.
switch (Select)
{
case 1:
document.getElementById("Result").innerHTML =
"You chose Item A.";
break;
case 2:
document.getElementById("Result").innerHTML =
"You chose Item B.";
break;
case 3:
document.getElementById("Result").innerHTML =
"You chose Item C.";
break;
}
}
Some people have a hard time understanding where the truth value lies in the switch
statement. The switch
statement requires a variable, which is Select
in this case. Each case
clause performs a comparison against the variable. Consequently, you could see the first case
clause as saying, case Select == 1
.
When working with switch
statements, you must also include a break
statement at the end of each processing segment. The break
statement simply says that the case
has been evaluated and handled.
Using the default option
The switch
statement includes another clause, the default
clause. The default
clause is like the else clause for the if
statement. When none of the case
clauses are true, the code executes the code in the default
clause. The following example uses the default
clause to modify the way in which the example in the preceding section works. This version is much easier to understand and use. (You can find complete code for this example in the Chapter 08SwitchStatement
folder of the downloadable code as DefaultSwitch.HTML
.)
function MakeAChoice()
{
// Ask the user to provide input.
var Selection = prompt("Type a menu option.");
// Convert the string to a number.
var IntSelect = parseInt(Selection);
// Verify the user has provided a number.
if (isNaN(IntSelect))
{
// Display an error dialog.
alert("Please provide numeric input!");
// Return without doing anything more.
return;
}
// Call the selection function.
CheckChoice(IntSelect);
}
Instead of providing myriad buttons, this example relies on the prompt()
dialog box to obtain input from the user. The result is the cleaner interface shown in Figure 8-2. When the user clicks Choose a Menu Item, the application displays a prompt()
dialog box, where the user can enter a value.
Figure 8-2: This example provides a cleaner interface.
You might think that this is a recipe for disaster, but the application performs the same checks for input validity as before, but it uses a different technique.
In this case, the application uses partInt()
to verify that the input is a number and to convert the number to an integer value. When the input is incorrect, IntSelect
is set to Not a Number (NaN
). The example detects this issue by using the isNaN()
function. When a user does provide a numeric input, the application calls CheckChoice()
, which is shown in the following code:
function CheckChoice(option)
{
// Make a selection.
switch (option)
{
case 1:
document.getElementById("Result").innerHTML =
"You chose Item A.";
break;
case 2:
document.getElementById("Result").innerHTML =
"You chose Item B.";
break;
case 3:
document.getElementById("Result").innerHTML =
"You chose Item C.";
break;
default:
// Display an error dialog.
alert("The value supplied is out of range!");
break;
}
}
You may be wondering where the rest of the code is, but this is all you need. The switch
statement checks for values of 1
, 2
, or 3
. When the values are outside that range, the code uses the default clause, which contains the out-of-range error message. As you can see, these two functions make the tasks of working with the menu a lot simpler for both developer and user.