CSC 107      Spring 2002

Lesson 5: Event-driven Programming

One of the features 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 the page, you interact with it. You click on links and buttons to change pages or to make windows pop up, or you enter information in forms and view responses based on your entries. In these and many other ways, Web pages are responsive to your actions. In other words, Web pages are "event-driven", reacting to events that you initiate such as mouse clicks or keyboard entries.

The way in which events are handled within a page is specified using JavaScript. Thus, the skills you have learned in JavaScript programming can now be applied to writing interactive Web pages. Instead of prompting the user for their grades, you can allow them to enter the grades in boxes on the page and then click a button to compute their course average. While the same JavaScript code can compute the average in either case, the event-driven page provides a more attractive and intuitive interface for the user.

In this lesson, you will begin using JavaScript as a tool for controlling event-driven Web pages. In particular, you will use buttons to initiate actions, text boxes to read in values, and text areas to display results.

Initiating actions via buttons

The simplest type of event handler in Web pages is a button. If you have done any surfing on the Web, you have no doubt run across buttons such as the following:

By clicking the mouse on the button, something happens (you are taken to a new page, a window pops up, your credit card number is stolen, etc.) Buttons are HTML elements that can be embedded in pages and used to control the behavior of the page. A button element looks like the following:

<input type="button" value="ButtonLabel" onCLick="JavaScriptCode">

The VALUE attribute of a button specifies the label that will appear on the button (for example, the button pictured above has value="Click here for free money!". The ONCLICK attribute specifies what is to happen when the button is clicked. This can be any piece of JavaScript code enclosed in quotes. For example, onCLick="alert('Yeah, right.');" specifies that the JavaScript alert function should be called to display the message "Yeah, right.".

Note the use of single quotes for the message 'Yeah, right.'. As you may recall, JavaScript strings can be enclosed in either single quotes or double quotes. This flexibility with quotes is useful in cases such as this, where one string must be nested inside another.

Unlike other HTML elements such as IMG, which can appear anywhere in a page, button elements must always appear inside of forms. A form element is simply a grouping of buttons and other event-driven elements within a page. In the HTML document below, a button is contained in a form called ButtonForm. When loaded, this page will contain the "free money" button described above.

<html> <!-- Dave Reed button.html 10/20/01 --> <!--------------------------------------------> <head> <title> Fun with Forms</title> </head> <body> <form name="ButtonForm"> <input type="button" value="Click here for free money!" onClick="alert('Yeah, right.');"> </form> </body> </html>

EXERCISE 5.1:    Cut-and-paste the button.html text into a new HTML document and load this page in the browser to verify that it behaves as described.

Once you have done this, modify the page so that the button is labeled "Click for Lucky Number", and the alert message displays a message of the form: "The lucky number for the day is X", where X is a random integer between 1 and 100. Note: the lucky number should be different every time the button is clicked.

Input/output via text boxes

A button provides a simple mechanism for the user to interact with the page. By clicking on the button, they can initiate some action. Other form elements allow the user to provide information that can be used in performing those actions. For example, a text box allows the user to enter a single line of input. A text box element looks like the following:

<input type="text" name="TextBoxName" size=NumChars value="InitialText">

The NAME attribute of a text box specifies the name by which that box will be referred. The SIZE attribute specifies the size of the box in terms of the number of characters that will fit in the box. The VALUE attribute (if present) specifies the text that will initially appear in the text box. The contents of a text box can be accessed at any time as: document.FORM-NAME.TEXT-BOX-NAME.value

For example, in the HTML document below, a text box named userName is used to read in the user's name. The contents of that text box (document.BoxForm.userName.value) are accessed by the button when it is clicked, and that text is displayed as part of the alert message.

<html> <!-- Dave Reed textbox1.html 10/20/00 --> <!----------------------------------------------> <head> <title> Fun with Forms</title> </head> <body> <form name="BoxForm"> Enter your name here: <input type="text" size=12 name="userName"> <p> <input type="button" value="Click Me" onClick="alert('Thanks, ' + document.BoxForm.userName.value + ', I needed that.');"> </form> </body> </html>

EXERCISE 5.2:    Cut-and-paste the textbox1.html text into a new HTML document and load this page in the browser to verify that it behaves as described.

Once you have done this, modify the textbox1.html page so that it has two input text boxes, one for first name and one for last name. The message displayed in the alert box should include both names.

Text boxes can be used for output as well as input. In fact, a text box is a perfect analogy for memory cells. Recall that JavaScript variables are associated with memory cells so that each reference to a variable accesses the value in its memory cell, and each assignment to that variable stores a value in the memory cell. Similarly, a text box stores a value that can be accessed and assigned a value via the name

document.FORM-NAME.TEXT-BOX-NAME.value where the FORM-NAME and TEXT-BOX-NAME vary for each text box. For example, the following page contains a text box that stores a number. When the button labeled "Double" is clicked, the value stored in that text box is accessed, doubled, and then assigned back to the text box. The result is that each click of the button doubles the contents of the box.

<html> <!-- Dave Reed textbox2.html 10/20/01 --> <!----------------------------------------------> <head> <title> Fun with Forms</title> <script language="JavaScript"> function DoubleIt() // Assumes: document.BoxForm.number contains a number // Results: the contents of the box are doubled { document.BoxForm.number.value= parseFloat(document.BoxForm.number.value) * 2; } </script> </head> <body> <form name="BoxForm"> Enter a number here: <input type="text" size=12 name="number" value=2> <p> <input type="button" value="Double" onClick="DoubleIt();"> </form> </body> </html>

Note that before doubling the contents of the text box, the parseFloat function is called. Similar to the way the prompt function works, the contents of a text box are treated as a string and must explicitly be converted using parseFloat in order to be treated as a number.

EXERCISE 5.3:    Cut-and-paste the textbox2.html text into a new HTML document and load this page in the browser to verify that it behaves as described.

If you start with a value of 1 in the text box, how many clicks does it take for the value to to reach 500? How many clicks to reach 1000? Do you see any connection between the values you obtained in the box and powers of two, e.g., 20, 21, 22, ... ?

EXERCISE 5.4:    Modify the textbox2.html page so that it has three additional buttons, labeled "Halve", "Increment", and "Decrement". When the "Halve" button is clicked, the number in the text box should be divided by 2. Similarly, the "Increment" button should cause the value in the box to have 1 added to it, and "Decrement" should cause the value to have 1 subtracted from it. Note: there should be only the one text box in the page, with all four buttons acting on the value in that box. You will probably want to define a new function corresponding to each new button.

In addition to storing user input and displaying output, text boxes can have an attribute that specifies what is to happen when the contents of the box change, i.e., when the user enters a new value. Similar to the ONCLICK attribute for buttons, the ONCHANGE attribute for text boxes is assigned JavaScript code that is executed when the contents of the box are changed (and the user subsequently clicks the mouse outside of the box). For example, the following page contains two text boxes named box1 and box2. Each text box has an ONCHANGE attribute specifying that its contents are to be copied to the other box whenever it is changed. The effect is that the two boxes will always mirror each other, no matter which is changed.

<html> <!-- Dave Reed textbox3.html 10/20/01 --> <!----------------------------------------------> <head> <title> Fun with Forms</title> </head> <body> <form name="BoxForm"> <input type="text" name="box1" size=10 value="" onChange="document.BoxForm.box2.value = document.BoxForm.box1.value;"> &nbsp; <----> &nbsp; <inpt type="text" name="box2" size=10 value="" onChange="document.BoxForm.box1.value = document.BoxForm.box2.value;"> </form> </body> </html>

EXERCISE 5.5:    Cut-and-paste the textbox3.html text into a new HTML document and load this 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 convert.html page (from Lesson 4). The new version should have two text boxes labeled "Temperature in Fahrenheit" and "Temperature in Celsius". Whenever the user enters a temperature in one of the boxes, the converted temperature should automatically appear in the other box.

EXERCISE 5.6:    Reimplement your grade.html page from Lesson 3 using text boxes. The page should have a text box for each of the individual grades (lesson average, lab average, discussion average, test1, test2, and final exam), and a single button to compute the course average. When the user clicks on the button, a function should be called to compute the average and display it in another text box.

Input/output via text areas

While text boxes provide a natural means of inputting and displaying values in a Web page, the fact that text boxes can only contain one line of text is often limiting. An alternative is a text area, which can contain any number of lines of text. A text area element looks like the following:

<textarea name="TextAreaName" rows=NumRows cols=NumCols wrap="virtual"> Initial Text </textarea>

The NAME attribute of a text area specifies the name by which that area will be referred. The number of rows and columns of text are specified by the attributes ROWS and COLS. The attribute assignment wrap="virtual" ensures that text will wrap from one line to the next as needed, as opposed to running off the edge of the text area. The initial text that is to appear in the text area (if any) is enclosed between the <textarea ...> and </textarea> tags.

For example, in the HTML document below, numbers are entered into two text boxes. At the click of the button, the compareMessage function is called to compare the two numbers and construct a message identifying the max and min. This message is then displayed in the text area. Note that the text that appears in the text area cannot contain HTML tags. Instead, the special character sequence '\n' can be used to specify a line break (similar to the <BR> tag).

<html> <!-- Dave Reed textarea.html 10/20/01 --> <!----------------------------------------------> <head> <title> Fun with Forms</title> <script language="JavaScript"> function compare() // Assumes: document.AreaForm.number1 and // document.AreaForm.number2 contain numbers // Results: writes the max and min in document.AreaForm.output { var num1, num2; num1 = parseFloat(document.AreaForm.number1.value); num2 = parseFloat(document.AreaForm.number2.value); document.AreaForm.output.value = "The maximum of the two is " + Math.max(num1, num2) + "\n" + "The minimum of the two is " + Math.min(num1, num2); } </script> </head> <body> <form name="AreaForm"> Numbers: <input type="text" size=3 name="number1"> <input type="text" size=3 name="number2"> <p> <input type="button" value="Compare the Numbers" onClick="compare()"> <p> <textarea name="output" rows=2 cols=40 wrap="virtual"> Enter numbers and click the button to compare. </textarea> </form> </body> </html>

EXERCISE 5.7:    Cut-and-paste the textarea.html text into a new HTML document and load this 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 Lesson 2. The page should have a text box for each of the words to be entered by the user, along with a label (e.g., color: ) to identify the type of word expected. When the user clicks on a button, the story that contains all of those words should appear in the text area.

EXERCISE 5.8:    Reimplement your Magic 8-ball page, magic.html, from Lesson 4. The page should contain a text area where the user can enter their question, and a button to submit that question. When the user clicks on the button, a random response should be generated (as before) and displayed in a text box. Note: this page is interesting in that it receives input from the user (the text area) and then completely ignores it. Of course, the user will not know this - they may think the Magic 8-ball has considered their question carefully before responding!

Lesson Summary

Additional (optional) exercises Solutions to odd numbered exercises