A Balanced Introduction to Computer Science and Programming

David Reed
Creighton University

Copyright © 2004 by Prentice Hall



Chapter 9: Event-driven Programming


One feature of the World Wide Web that makes it so popular is its interactive nature. When you access a Web page, you don't just view it-you interact with it. You click links and buttons to access new pages or make new windows appear, or you enter information and view responses based on your input. In these and many other ways, Web pages respond to your actions. We refer to such Web pages as "event-driven," in that they react to user-initiated events such as mouse clicks or keyboard entries.

Programmers can use JavaScript code to specify the way in which Web pages handle various events. Thus, you can now apply your JavaScript programming skills to writing event-driven Web pages. For example, instead of prompting users to enter their grades, you can design a page in which users type grades in boxes and then click a button to compute their course average. Although the same JavaScript code can compute the average in either case, the event-driven page provides a more attractive and easy-to-use interface for the user.

In this chapter, you will begin using JavaScript as a tool for controlling event-driven Web pages. The first section demonstrates the use of buttons to initiate actions. Then, we introduce text boxes and text areas, elements that accept user input and display output. At the end of the chapter, you will learn how to define events that cause different images to appear in a page.


Initiating Actions via Buttons

An event-handler is an HTML element that can be programmed (using JavaScript) to react to actions taken by the user. The simplest type of event handler that can appear in Web pages is a button. If you have done any surfing on the Web, you have no doubt run across buttons like the one shown in Figure 9.1.

Figure 9.1: An HTML button.


Buttons are HTML elements that can be embedded in Web pages, just like images or tables. Unlike these static elements, however, buttons can be associated with JavaScript code in order to react when the user clicks on them. For example, the button above might have JavaScript code associated with it so that when the user clicks on the button, they are taken to a new page or window. The following represents a generalized button element:

<input type="button" value="BUTTON_LABEL" onClick="JAVASCRIPT_CODE" />

A button's VALUE attribute specifies the text label that appears on the button. For example, the button in Figure 9.1 has the following attribute assignment: value="Click here for free money!". The ONCLICK attribute specifies the action taken when a user clicks the button. This attribute can be assigned any JavaScript statement or sequence of statements, enclosed in quotes.

Unlike HTML elements that can appear anywhere in a page, button elements must always be placed inside form elements. A form is a grouping of buttons and other event-driven elements within a page, delimited by the tags <form name="FORM_NAME"> and </form>. Forms are commonly used by Web developers to collect information from users, such as purchase and mailing details concerning an online purchase, which is then transmitted over the Internet. We will not utilize this aspect of forms in this text, however, so we can think of them as just being necessary wrapping for buttons and boxes.

In the Web page in Figure 9.2, a form named LuckyForm contains a button with the label "Click Here for Lucky Number". Once this page has been loaded, clicking the button will call the DisplayNumber function to pick a lucky number-specified as a random integer between 1 and 100-and display it in an alert box (Figure 9.3).

<html> <!-- lucky.html Dave Reed --> <!-- This page displays a lucky number at the click of a button. --> <!-----------------------------------------------------------------> <head> <title> Fun with Forms </title> <script language="JavaScript" src="http://www.creighton.edu/~csc107/random.js"> </script> <script type="text/javascript"> function DisplayNumber() // Results: displays random number in an alert box { var luckyNum; luckyNum = RandomInt(1, 100); alert("Your lucky number is: " + luckyNum); } </script> </head> <body> <div style="text-align:center"> <h2>Lucky Dave's Gift To You</h2> <p>Numbers rule our lives. If you would like the benefit of Lucky Dave's amazing powers of prognostication, click on the button below to receive your guaranteed lucky number for the day!</p> <form name="LuckyForm"> <input type="button" value="Click Here for Lucky Number" onClick="DisplayNumber();" /> </form> </div> </body> </html>

Figure 9.2: Simple Web page containing a button.

button example

Figure 9.3: Appearance of the Web Page from Figure 9.2.



EXERCISE 9.1:    Enter the lucky.html text from Figure 9.2 into a new Web page, then load the page in the browser to verify that it behaves as described.

Once you have done this, save a copy of the page under the name lotto.html and modify it so that it predicts the winner of a PICK-4 lottery. You should update the page's text appropriately and modify the button so that its label reads "Click for Today's PICK-4 Winner". The DisplayNumber function, instead of displaying a single number, should pick 4 random numbers from the range 0 to 9 and display them in an alert box, separated by dashes. Figure 9.4 depicts an example of an alert box containing a PICK-4 winning number.

alert box

Figure 9.4: Sample of a PICK-4 alert box.



Input/Output via Text Boxes

A button provides a simple mechanism through which users can interact with a Web page. By clicking the button, the user initiates some action. Although an alert box is sufficient for displaying a simple message, most tasks require more elaborate forms of user interaction, such as where the user enters several inputs and then views the results of a computation. Fortunately, programmers can accomplish these more complex tasks using another HTML form element, called a text box. A text box, as its name suggests, is a box that can contain text (words or phrases). Unlike an alert box or prompt box, however, a text box is an HTML element that appears within the page itself. When the user enters input in a text box, that input is directly accessible via JavaScript code; similarly, JavaScript statements can cause text to be displayed in text boxes. Thus, a text box can be used both to receive user input and to display the results of computations within the page.

The following represents a generalized text box element:

<input type="text" name="TEXTBOX_NAME" size=NUM_CHARS value="INITIAL_TEXT" />

A text box's NAME attribute specifies the name used to identify that box. The SIZE attribute specifies the size of the box, which is measured by the number of characters it can contain. The VALUE attribute (if present) specifies the text that initially appears in the text box. Like buttons, text boxes are form elements and therefore must appear inside form tags.

A text box is a perfect analogy for a memory cell. Recall that every JavaScript variable is associated with a specific memory cell -- each reference to a variable accesses the value in its memory cell, and each assignment to the variable stores a value in that same memory cell. As you will see in the following sections, a text box similarly stores a value that can be accessed and assigned. The main difference between a variable and a text box is that the contents of a text box are visible in the page, while the values of variable are hidden.


Text Boxes for Displaying Output

Using JavaScript code, programmers can display a message in a text box by encapsulating the message as a string and assigning the string to the box's VALUE attribute. When you assign a value to a text box, you must specify the absolute name of the box: starting with the word "document", followed by the name of the form containing the box and the text box name (all separated by periods). The full, absolute name is required since it is conceivable that a page might contain multiple forms, each with its own text boxes. The following represents a generalized assignment to a text box:

document.FORM_NAME.TEXTBOX_NAME.value = STRING_TO_BE DISPLAYED;

For example, Figure 9.5 depicts a modified version of the lucky.html page, which uses a text box, rather than a separate alert box, to display the lucky number. The text box, named number, is four characters wide and initially appears blank (i.e., its initial contents consist of an empty string ""). When the user clicks on the button labeled "Click Here for Lucky Number", the DisplayNumber function is called to pick a random number between 1 and 100, as in Figure 9.3. However, instead of displaying the number in an alert box as in Figure 9.3, the function displays the number in the text box via the assignment: document.LuckyForm.number.value = luckyNum.

<html> <!-- lucky.html Dave Reed --> <!-- This page displays a lucky number in a text box. --> <!------------------------------------------------------> <head> <title> Dave's Lucky Number </title> <script language="JavaScript" src="random.js"></script> <script language="JavaScript"> function DisplayNumber() // Assumes: document.LuckyForm.number exists in the page // Results: displays random number in the text box { var luckyNum; luckyNum = RandomInt(1, 100); document.LuckyForm.number.value = luckyNum; } </script> </head> <body> <div style="text-align:center"> <h2>Lucky Dave's Gift To You</h2> <p>Numbers rule our lives. If you would like the benefit of Lucky Dave's amazing powers of prognostication, click on the button below to receive your guaranteed lucky number for the day!</p> <form name="LuckyForm"> <input type="button" value="Click Here for Lucky Number" onClick="DisplayNumber();" /> <br/><br/> <hr/><br/> Your lucky number is: <input type="text" name="number" size=3 value="" /> </form> </div> </body> </html>

Figure 9.5: Web page that displays a number in a text box.

text box example

Figure 9.6: Appearance of the Web page from Figure 9.5.


EXERCISE 9.2:    Enter the revised lucky.html text from Figure 9.5 into a Web page, then load the page in the browser to verify that it behaves as described.

Make similar modifications to your lotto.html page, causing it to display the winning PICK-4 lottery numbers in a text box. This means that your DisplayWinner function must generate the four random numbers, concatenate them so that they are separated by hyphens, and assign the resulting string to the text box.


Common errors to avoid...

Although form elements such as buttons and text boxes must appear within form tags, it is not necessary to separate each form element in its own form. In most cases, you can enclose every form element in a page within a single set of form tags. It is not an error to include multiple forms in a page, but this practice can lead to unnecessary confusion, since you must be sure to associate each element with its correct form name.

Like variables, form elements must have unique names so that they can be identified. If you mistakenly use the same name to represent multiple form elements, no error will occur. However, the name will be associated with the last element you defined, and all subsequent accesses will refer to that element.


Text Boxes for Accessing Input

Whereas some text boxes are used to display output, others are employed to handle user input. When a text box is intended to accept input, users can enter data by clicking the mouse pointer within the box and typing. JavaScript code then accesses the text box' s contents using the absolute name of the text box (where FORM_NAME nad TEXTBOX_NAME will vary for each text box):

document.FORM_NAME.TEXTBOX_NAME.value

A text box is a perfect analogy for a memory cell. Recall that every JavaScript variable is associated with a specific memory cell -- each reference to a variable accesses the value in its memory cell, and each assignment to the variable stores a value in that same memory cell. Similarly, a text box stores a value that can be accessed and assigned via the text box's absolute name. The main difference between a variable and a text box is that the contents of a text box are visible in the page, while the values of variable are hidden.

For example, the Web page in Figure 9.7 is an event-driven version of the temperature conversion page from Chapter 7. The page contains a text box named fahrBox, which accepts user input. The user enters a Fahrenheit temperature in fahrBox and then clicks the button labeled "Convert to Celsius". When the button is clicked, the Convert function accesses the value entered by the user and computes the corresponding Celsius temperature. The result of the computation is then assigned to a text box named celsiusBox, which displays the converted temperature in the page.

<html> <!-- convert.html Dave Reed --> <!-- This page converts temperatures from Fahrenheit to Celsius. --> <!-----------------------------------------------------------------> <head> <title>Temperature Conversion Page</title> <script language="JavaScript"> function FahrToCelsius(tempInFahr) // Assumes: tempInFahr is a temperature in Fahrenheit // Returns: the equivalent temperature in Celsius { return (5/9) * (tempInFahr - 32); } function Convert() // Assumes: document.TempForm.tempBox contains degrees Fahrenheit // Results: assigns document.TempForm.celsiusBox the equiv. temperature { var tempF, tempC; tempF = parseFloat(document.TempForm.fahrBox.value); tempC = FahrToCelsius(tempF); document.TempForm.celsiusBox.value = tempC; } </script> </head> <body> <h2>Temperature Conversion Page</h2> <hr/><br/> <form name="TempForm"> Enter a temperature in degrees Fahrenheit: <input type="text" name="fahrBox" size=10 value="" /> <br/><br/> <input type="button" value="Convert to Celsius" onClick="Convert();" /> <br/><br/> Equivalent temperature in degrees Celsius: <input type="text" name="celsiusBox" size=10 value="" /> </form> </body> </html>

Figure 9.7: Web page that uses text boxes for input and output.

text box example

Figure 9.8: Appearance of the Web page from Figure 9.7.


Common errors to avoid...

Note that, in the example from Figure 9.7, we called the parseFloat function before performing a computation on the text box's contents. Like input returned by the prompt function, a value read in from a text box is initially treated as a string. Therefore, you must use parseFloat to explicitly convert text box values before treating the values as numbers.

In this example, forgetting to parseFloat the value from the text box would not affect the behavior of the page, because applying the subtraction operator would automatically convert the text box value to a number. However, in cases where the text box value is added to another value, the browser would interpret the '+' operator as specifying concatenation involving the string value. To avoid problems such as this, you should always call parseFloat whenever you plan to treat the value in a text box as a number.



EXERCISE 9.3:    Enter the revised convert.html text from Figure 9.7 into a new Web page, then load the page in the browser to verify that it behaves as described.

In EXERCISE 7.2 of Chapter 7, you expanded your temperature conversion page so that it could convert in both directions. Make similar modifications to the page in Figure 9.7, using text boxes for input and output. The page should include your FahrToCelsius and CelsiusToFahr functions, as well as two text boxes, one for Fahrenheit and one for Celsius. If users enter a temperature in the Fahrenheit box and click a button labeled "Fahr --> Celsius", then the corresponding temperature should appear in the Celsius box. Likewise, if they enter a temperature in the Celsius box and click the button labeled "Fahr <-- Celsius", the corresponding temperature should appear in the Fahrenheit box. Your page should look similar to the one depicted in Figure 9.9.

text box example

Figure 9.9: Sample of temperature conversion page.


Designer secrets...

It is important to recognize that the programming skills you learned in previous chapters are still applicable to developing event-driven pages. Most of the pages you wrote involved the same basic steps: (1) obtain inputs from the user via prompts, (2) perform some computations on those inputs, then (3) display the results using write statements. You placed the code for carrying out these steps within SCRIPT tags in the body of the page, and the browser executed the code when the page loaded.

In an event-driven page, the interface between the user and the code is different: the user enters inputs directly into text boxes, and code is executed when the user clicks a button. However, the underlying algorithm for solving problems remains the same: (1) obtain inputs from the user by accessing text boxes, (2) perform some computations on those inputs, then (3) display the results by assigning to text boxes.

If you compare the code from Chapter 7's convert.html page (Figure 7.2) with the even-driven version in Figure 9.7, you will see that the two pages are very similar. Although the event-driven page uses text boxes to handle input and output, the function triggered by the button performs the same tasks that the code from the BODY of the original page does.


EXERCISE 9.4:    Reimplement your grade.html page from Chapter 5 (EXERCISE 5.6) using text boxes and a button. Your new page should include text boxes in which users can enter each individual grade (lesson average, lab average, discussion average, test average, and final exam), as well as a single button to compute the course average. When the user clicks the button, the program should call a function to compute the average and display it in another text box.

Hint: This page should look a lot like the convert.html page from Figure 9.7, except that grade.html will contain four text boxes for inputs. Instead of converting an entered temperature, your button will trigger the calculation of a weighted average. Once the function executes, the result will be displayed in a separate text box.


Text Boxes for Handling Both Input and Output

It is not uncommon for a particular sequence of JavaScript statements to employ the same variable in multiple ways. For example, a program might initially use a variable to store a user input, then later assign the result of some computation to that same variable. If we continue our analogy between text boxes and variables, it follows that the same text box can be used both to obtain user input and to display the results of a computation.

Consider, for example, the JavaScript function in Figure 9.10. Assuming a text box named number appears in the page (inside a form named NumForm), this function will access the number in the text box, multiply that number by two, and assign the result back to the box. Thus, every time the function is called, the current value of the text box is doubled. A user can enter any number in the text box, then click the button repeatedly to display updated values in the box.

function DoubleIt() // Assumes: document.NumForm.number contains a number // Results: the number in the box is doubled { var num; num = parseFloat(document.NumForm.number.value); document.NumForm.number.value = 2 * num; }

Figure 9.10: JavaScript function that doubles the contents of a text box.


EXERCISE 9.5:    Create a Web page named double.html that includes the DoubleIt function in the HEAD. The page should contain a text box with an initial value of 1 and a button labeled "Double It". When the user clicks the button, the DoubleIt function should be called to double the contents of the text box.

If you start with a value of 1 in the text box, how many times must you click for the value to exceed 500? How many times to exceed 1000?



Input/Output via Text Areas

Although text boxes provide a convenient method of inputting and displaying values in Web pages, the fact that text boxes can contain only one line of text often limits their usefulness. An alternative is a text area, which is similar to a text box but can contain any number of text lines. The following represents a generalized text area element:

<textarea name="TEXTAREA_NAME" rows=NUM_ROWS cols=NUM_COLS wrap="virtual"> INITIAL TEXT </textarea>

A text area's NAME attribute specifies the name used to identify that area. The number of rows and columns in the text area are specified by the attributes ROWS and COLS, respectively. The attribute assignment wrap="virtual" ensures that text will wrap from one line to the next as needed, instead of running off the edge of the text area. The initial text that appears in the text area (if any) is enclosed between the <textarea> and </textarea> tags.

The Web page in Figure 9.11 contains two text boxes, each of which is 15 characters wide, and a text area containing four rows of 40 characters. The page asks users to enter their first and last names in the text boxes. Once the user enters the names and clicks the button, the program accesses the contents of the text boxes and incorporates the names in a greeting, which displays in the text area. Note that there is no text between the opening and closing TEXTAREA tags, so the text area initially appears empty.

<html> <!-- greetbox.html Dave Reed --> <!-- This page displays a personalized greeting in a text area. --> <!----------------------------------------------------------------> <head> <title> Long Greeting </title> <script language="JavaScript"> function Greet() // Assumes: document.NameForm.firstName and // document.NameForm.lastName contain names // Results: writes a message with those names in document.NameForm.message { var firstName, lastName, greeting; firstName = document.NameForm.firstName.value; lastName = document.NameForm.lastName.value; greeting = "Hello " + firstName + " " + lastName + ", or may I just call you " + firstName + "? You wouldn't be related to the " + lastName + "s of Park Avenue, would you?"; document.NameForm.message.value = greeting; } </script> </head> <body> <form name="NameForm"> Enter your first name: <input type="text" size=15 name="firstName" /> <br/> Enter your last name: <input type="text" size=15 name="lastName" /> <br/><br/> <input type="button" value="Click for Greeting" onClick="Greet();" /> <br/><br/> <textarea name="message" rows=4 cols=40 wrap="virtual"></textarea> </form> </body> </html>

Figure 9.11: Web page that uses a text area for output.

textarea example

Figure 9.12: Appearance of the Web page from Figure 9.11.


Common errors to avoid...

As we saw in Chapter 2, the browser interprets HTML tags and displays the appropriate page elements as the page is loaded. Because the contents of a text box can be updated repeatedly after the page has loaded, the browser does not process the text in a text box. As such, HTML tags cannot be used to format text in a text box. If you mistakenly enter HTML tags within a text box, they will be treated like any other sequence of characters and will be displayed exactly as typed. If you enter extra spaces in the text, they will also appear exactly as you typed them.

If you want to force a line break within a text area, you can include the character sequence   \n   within the text. Inserting this special sequence causes subsequent text to begin on a new line, producing the same effect that <br /> does in HTML.


EXERCISE 9.6:    Enter the greetbox.html text from Figure 9.11 into a new Web page, then load the page in the browser to verify that it behaves as described.

Once you have done this, modify the page so that it acts as an event-driven version of your madlib.html page from Chapter 4. The page should incorporate text boxes in which the user can enter the story's missing words, and each text box should be accompanied by a label (such as color: or noun:) to identify the type of word expected. Include a button that, when clicked, causes the story containing the user's words to appear in the text area.



EXERCISE 9.7:    Reimplement your Magic 8-Ball page, magic.html, from Chapter 7 (EXERCISE 7.9). The page should contain a text area in which the user can enter a question, as well as a button to submit that question. When the user clicks the button, the program should generate a random response (as before) and display this response in a text box.

Note: This page is unique in that it completely ignores the input it receives from the user. Of course, users may not realize this -- some may think that the Magic 8-Ball has considered their questions carefully before responding!



Dynamic images

In Chapter 2, you learned how to insert images in Web pages using the IMG element. For example, suppose happy.gif is an image file displaying a happy face. The following tag, when embedded in a Web page, would cause the happy.gif image to appear in the page:

<img name="photo" src="happy.gif" alt="Happy Face" />

This chapter has already demonstrated that user-initiated events can change the contents of text boxes and text areas. However, you can also use events to access and modify IMG elements within a Web page. You can design a page in which different images appear when the user clicks a button or enters a value in a text box. In such cases, the event triggers JavaScript statements that assign a new file to the IMG element's SRC attribute. For example, the following assignment would replace the image of the author with an image stored in the file sad.gif:

document.images.photo.src = "sad.gif";

Note that the assignment to the IMG element is similar to earlier assignments to text boxes and text areas. There are two notable distinctions, however. First, images do not need to be embedded in forms. Instead, all images in a Web page are grouped under the name images, which appears in the assignment immediately after the word document to identify the element as an image. Second, images do not contain values in the way that text boxes and text areas do. Instead, an IMG element is associated with a source file, so the assignment is made to the SRC attribute of the image (as opposed to a VALUE attribute of a text box or text area).

The Web page in Figure 9.13 contains a single IMG element, which is initially assigned the source file happy.gif (assumed to reside in the same directory that the page does). When the user clicks the button labeled "I feel sad", the source for the image is changed to sad.gif, which displays a sad face. Likewise, when the user clicks the button labeled "I feel happy", the source is reset back to happy.gif, which displays a happy face.

<html> <!-- pics.html Dave Reed --> <!-- This page allows the user to select from among two images. --> <!-----------------------------------------------------------------> <head> <title> Picture Fun </title> <script type="text/javascript"> function ChangeImage(picFile) // Assumes: picFile is the name of an image file // Results: changes the source of pic to picFile { document.images.face.src = picFile; } </script> </head> <body> <div style="text-align:center"> <h2>How do you feel today?</h2> <img name="face" src="happy.gif" alt="face image" /> <br /><br /> <form name="PicForm"> <input type="button" value="I feel happy" onClick="ChangeImage('happy.gif');" /> &nbsp;&nbsp; <input type="button" value="I feel sad" onClick="ChangeImage('sad.gif');" /> </form> </div> </body> </html>

Figure 9.13: Web page that demonstrate dynamic images.

dynamic image example

Figure 9.14: Appearance of the Web page in Figure 9.13.


Common errors to avoid...

If you are using an older version of the Netscape browser (i.e., version 4.7 or earlier), you might notice something odd when you load the previous example. Early versions of Netscape Navigator associate an IMG element with specific dimensions when the page loads. Any subsequent assignment will resize the new image to fit the old source's dimensions, and this may warp the image.

Internet Explorer and later versions of Netscape automatically adjust the image dimensions to fit the new source.



EXERCISE 9.8:    Enter the pics.html text from Figure 9.13 into a new Web page and modify the page so that it contains at least three buttons. Each button should assign a new file to the SRC attribute of the IMG. You may choose any images you wish, but remember that you must either download the images to your local directory or list the images' full Web URLs. Be sure that the labels on the buttons provide accurate descriptions of the images they control.



EXERCISE 9.9:    Create a Web page named newpics.html that is similar to pics.html, but which contains only one button controlling the image. When a user clicks this button, a function (with no inputs) should be called to randomly select among several images.

For example, the following JavaScript statement, when executed, would randomly choose from among four image file names (happy.gif, sad.gif, scared.gif, and bored.gif) and assign the chosen file name to the SRC attribute of an image named face:

document.images.face.src = RandomOneOf(["happy.gif", "sad.gif", "scared.gif", "bored.gif"]);



Lesson Summary


Supplemental (optional) material and exercises Solutions to odd numbered exercises