CONTENTS
Working with forms is the cornerstone of many of the JavaScript
programs currently available on the World Wide Web. From simple
spreadsheets to conversion calculators and color-pickers, many
scripts use forms and their associated properties, methods, and
event handlers to produce sophisticated interactive programs.
In order to effectively use forms in JavaScript, you need to understand
the form object and its properties
and methods and to have a firm command of the events generated
by different form elements.
In this chapter, you will learn this through the following topics:
- The form object, its
properties, and methods
- Event handlers for form elements
- More about the Math object
- The forms[] array
- The elements[] array
- Limitations of event handlers
The form object is one of
the most heavily used objects in JavaScript scripts written for
Navigator. As a programmer, by using the form
object, you have at your disposal information about the elements
in a form and their values and can alter many of these values
as needed.
A separate instance of the form
object is created for each form in a document. As you learn later
in the section about the forms[]
array, forms all have a numeric index. They can also be referred
to by name.
Table 6.1 outlines the properties available with the form
object.
Table 6.1. Properties of the form
object.
Property | Description
|
action
| String containing the value of the ACTION attribute of the FORM tag
|
elements
| Array containing an entry for each element in the form (such as checkboxes, text fields, and selection lists)
|
encoding
| String containing the MIME type used for encoding the form contents sent to the server. Reflects the EncTYPE attribute of the
|
FORM tag.
| |
name |
String containing the value of the NAME attribute of the FORM tag
|
target
| String containing the name of the window targeted by a form submission
|
As you learn later in the section on the elements[]
array, each of the elements of the form is itself an object with
associated properties and methods. Elements can be referred to
by name, as well as through their numeric index in the elements[]
array.
The action Property
With this property, you can ascertain the action specified in
the form definition. For instance, in a form defined with the
following
<FORM METHOD=POST ACTION="/cgi-bin/test.pl">
the action property has a
value of "/cgi-bin/test.pl".
The elements Property
This property is covered in more depth later in the section about
the elements[] array.
The encoding Property
The encoding property reflects
the MIME type, which is used to encode the data submitted from
a form to the server. In practical terms, this means that the
property reflects the EncTYPE
attribute of the FORM tag,
and you can set the encoding of a form by changing the value of
this property.
This is useful when you want to upload a file to be processed
by a CGI script on the server. More details about form-based file
upload is available in the Internet Engineering Task Force's
Request for Comments document number 1867 at the following
site:
http://www.ics.uci.edu/pub/ietf/html/rfc1867.txt
The name Property
This property provides the programmer with the name specified
in the form definition. In a form defined with the tag
<FORM METHOD=POST ACTION="/cgi-bin/test.pl"
NAME="thisform">
the name property has a value
of "thisform".
Note |
Using named forms is especially useful in documents with multiple forms where the JavaScript scripts must work with all the forms in the document.
|
The target Property
The target property is similar
to the action and name
properties and makes the content of the TARGET
attribute available to the programmer. In the FORM
definition
<FORM METHOD=POST ACTION="/cgi-bin/test.pl"
NAME="thisform" TARGET="thatframe">
the target property has a
value of "thatframe".
Note |
The TARGET attribute is particularly useful in the context of frames, which we discuss in Chapter 8, "Frames, Documents, and Windows."
|
It is possible to dynamically change the target of a form by assigning
a new value to the target property. In the preceding example,
the target could be changed from thatframe
to anotherframe by using
document.thisform.target = "anotherframe";
It is important to note that target can only be assigned a string
literal. It cannot be assigned an expression or a variable.
There is only one method available with the form object: submit().
As mentioned in Chapter 5, "Events
in JavaScript," this method emulates a click on the submit
button of a form without invoking the onSubmit
event handler.
For instance, in the following script, the form has no submit
button and can be submitted when the user enters the correct value
in the text field. The onSubmit
event handler, which returns false,
ensures that the form is not submitted if the user hits Return
in the text entry field.
<HTML>
<HEAD>
<TITLE>submit() Example</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!-- HIDE FROM OTHER BROWSERS
function checkValue(form) {
if (form.answer.value == "100")
form.submit();
else
form.answer.value = "";
}
// STOP HIDING FROM OTHER BROWSERS -->
</SCRIPT>
</HEAD>
<BODY>
<FORM METHOD=POST ACTION="/cgi-bin/correct.pl" onSubmit="return
false;">
What is 10 * 10? <INPUT TYPE="text" NAME="answer"
onChange="checkValue(this.form);">
</FORM>
</BODY>
</HTML>
Just as it has only one method, the form
object has only a single event handler associated with it: onSubmit.
This event handler is invoked when the user submits a form. For
instance, in the following script, when the user submits the form,
she is thanked for doing so.
<HTML>
<HEAD>
<TITLE>onSubmit Example</TITLE>
</HEAD>
<BODY>
<FORM METHOD=POST ACTION="/cgi-bin/test.pl"
onSubmit="alert('Thanks
for taking the test.');">
What is 10 * 10? <INPUT TYPE="text" NAME="answer">
<BR>
<INPUT TYPE="submit">
</FORM>
</BODY>
</HTML>
Forms are made up of a variety of elements that enable users to
provide information. Traditionally, the content (or value) of
these elements is passed to programs on the server through an
interface known as the Common Gateway Interface, or CGI for short.
Using JavaScript, though, you can write scripts into your HTML
documents to work with form elements and their values. You already
saw a basic example of this in Chapter 5,
in Listing 5.3 where you produced an extremely simple calculator
that calculated the value of a JavaScript expression and displayed
the result.
In this section, you will take a look at each type of form element
in detail and see what properties and methods and event handlers
are available for each.
Table 6.2 outlines the elements that make up forms. Each element
has a corresponding object.
Table 6.2. Form elements.
Form Element | Description
|
button
| A new element that provides a button other than a submit or reset button (<INPUT TYPE="button">)
|
checkbox
| A checkbox (<INPUT TYPE="checkbox">)
|
FileUpload
| A file upload element that allows the user to provide a file as input for a form submission (<INPUT TYPE="file">)
|
hidden
| A hidden field (<INPUT TYPE="hidden">)
|
password
| A password text field in which each keystroke appears as an asterisk (*) (<INPUT TYPE="password">)
|
radio |
A radio button (<INPUT TYPE="radio">)
|
reset |
A reset button (<INPUT TYPE="reset">)
|
select
| A selection list (<SELECT><OPTION>option1</OPTION><OPTION> option2</OPTION></SELECT>)
|
submit
| A submit button (<INPUT TYPE="submit">)
|
text |
A text field (<INPUT TYPE="text">)
|
textArea
| A multiline text entry field (<TEXTAREA>default text</TEXTAREA>)
|
Each of these elements can be named and referred to by name in
a JavaScript script. Each also has properties and methods associated
with it.
Before looking at each of the form element objects, let's take
a look at the type property.
Each of the form element objects has a type
property, which is a string value reflecting the type of input
element such as a button, a text field, or a checkbox.
The strings reflected by the various type
properties for each form element are
- Text field: "text"
- Radio button: "radio"
- Checkbox: "checkbox"
- Hidden field: "hidden"
- Submit button: "submit"
- Reset button: "reset"
- Password field: "password"
- Button: "button"
- Select list: "select-one"
- Multiple select lists: "select-multiple"
- Textarea field: "textarea"
In standard HTML forms, only two buttons are available-submit
and reset-because the data contained in a form must be sent to
some URL (usually a CGI-BIN script) for processing or storage.
A button element is specified using the INPUT
tag:
<INPUT TYPE="button" NAME="name"
VALUE="buttonName">
In the above INPUT tag, a
button named name is created.
The VALUE attribute contains
the text that the Navigator browser displays in the button.
The button element has two properties: name
(as specified in the INPUT
tag) and value, which is
also specified in the INPUT
tag.
There is a single event handler for the button element: onClick.
Associated with this is a single method: click().
The addition of the button element enables JavaScript programmers
to write JavaScript code to be executed for additional buttons
in a script.
For instance, in Listing 5.3, instead of using the onChange
element, you could alter the script as shown in Listing 6.1 to
evaluate the supplied expression when a button is pressed.
Listing 6.1. Evaluating a form using the button
element.
<HTML>
<HEAD>
<TITLE>button Example</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!-- HIDE FROM OTHER BROWSERS
function calculate(form) {
form.results.value = eval(form.entry.value);
}
// STOP HIDING FROM OTHER BROWSERS -->
</SCRIPT>
</HEAD>
<BODY>
<FORM METHOD=POST>
Enter a JavaScript mathematical expression:
<INPUT TYPE="text" NAME="entry" VALUE="">
<BR>
The result of this expression is:
<INPUT TYPE=text NAME="results"
onFocus="this.blur();">
<BR>
<INPUT TYPE="button" VALUE="Calculate"
onClick="calculate(this.form);">
</FORM>
</BODY>
</HTML>
Checkboxes are toggle switches in an HTML form. They are used
to select or deselect information. Checkboxes have more properties
and methods available than buttons do, as outlined in Table 6.3.
Table 6.3. Properties and methods for the checkbox
element.
Method or Property | Description
|
checked
| Indicates the current status of the checkbox element (property)
|
defaultChecked
| Indicates the default status of the element (property)
|
name |
Indicates the name of the element as specified in the INPUT tag (property)
|
value |
Indicates the current value of the element as specified in the INPUT tag (property)
|
click()
| Emulates a click in the checkbox (method) |
As you might expect, there is a single event handler for checkboxes:
onClick.
For example, you can use checkboxes to produce an alternative
to the double and square exercise (Exercise 3) from Chapter 5.
Instead of three fields, you can have an entry text field, a checkbox
to indicate squaring (doubling will be the default action), and
a results text field.
The resulting script would look like Listing 6.2.
Listing 6.2. Doubling and squaring with checkboxes.
<HTML>
<HEAD>
<TITLE>checkbox Example</TITLE>
<SCRIPT>
<!-- HIDE FROM OTHER BROWSERS
function calculate(form,callingField) {
if (callingField == "result") {
if (form.square.checked) {
form.entry.value = Math.sqrt(form.result.value);
} else {
form.entry.value = form.result.value
/ 2;
}
} else {
if (form.square.checked) {
form.result.value = form.entry.value
* form.entry.value;
} else {
form.result.value = form.entry.value
* 2;
}
}
}
// STOP HIDING FROM OTHER BROWSERS -->
</SCRIPT>
</HEAD>
<BODY>
<FORM METHOD=POST>
Value: <INPUT TYPE="text" NAME="entry"
VALUE=0
onChange="calculate(this.form,this.name);">
<BR>
Action (default double): <INPUT TYPE=checkbox NAME=square
onClick="calculate(this.form,this.name);">
Square
<BR>
Result: <INPUT TYPE="text" NAME="result"
VALUE=0
onChange="calculate(this.form,this.name);">
</FORM>
</BODY>
</HTML>
 |
In this script, you see an example of how to use the onClick event handler as well as how the checked property is a Boolean value that can be used as the condition for an if
else statement.
|
You have added a checkbox named square to the form. If the checkbox
is checked, the program will square the value. If it isn't, then
the default action will be to double the value. The onClick
event handler in the checkbox definition (<INPUT
TYPE=checkbox NAME=square onClick="calculate(this.form,this.name);">)
ensures that when the user changes the desired action, the form
recalculates (as well as if the user changes the value of the
entry field).
To take advantage of the checkbox, you also changed the calculate()
function, as follows:
function calculate(form,callingField)
{
if (callingField == "result") {
if (form.square.checked) {
form.entry.value = Math.sqrt(form.result.value);
} else {
form.entry.value = form.result.value
/ 2;
}
} else {
if (form.square.checked) {
form.result.value = form.entry.value
* form.entry.value;
} else {
form.result.value = form.entry.value
* 2;
}
}
}
In this function, you use the Boolean property checked
to determine the correct action. If form.square.checked
is true, then you should
be squaring; if the value is false,
you should be doubling the value in the entry field.
The file upload field in a form provides a way in which users
can specify a file to be included in a form submission. File upload
elements are reflected in JavaScript with the FileUpload
object.
The FileUpload object has
only two properties associated with it: name
and value, both of which
are string values like other objects. There are no methods or
event handlers for the FileUpload
object.
The hidden element is unique
among all the form elements in that it is not displayed by the
Web browser. Hidden fields can be used to store values that need
to be sent to the server along with a form submission but that
shouldn't be displayed in the page. They can also be used in JavaScript
to store values used throughout a script and for calculations
within a form.
The hidden object has only
two properties associated with it: name
and value, both of which
are string values like other objects. There are no methods or
event handlers for the hidden
object.
The password element is a
unique type of text entry field in that any keystrokes are displayed
as an asterisk (*). This makes the password
element ideal for accepting input of confidential information,
such as account passwords or bank account personal identification
numbers (PINs).
The password object has three
properties, similar to text fields: defaultValue,
name, and value.
Unlike the previous two elements, the password fields include
more methods (focus(), blur(),
and select()) and the corresponding
event handlers: onFocus,
onBlur, and onSelect.
We will discuss these methods and event handlers in more detail
in the section on the text
element.
The radio element is similar
to toggle checkboxes, except that several radio buttons are combined
into a group and only a single button can be selected at any given
time. For instance, the following lines produce a group of three
radio buttons named test,
similar to those in Figure 6.1.
Figure 6.1 : Web a group of radio buttons, only one element can be selected at any given time.
<INPUT TYPE="radio" NAME="test"
VALUE="1" chECKED>1<BR>
<INPUT TYPE="radio" NAME="test" VALUE="2">2<BR>
<INPUT TYPE="radio" NAME="test" VALUE="3">3<BR>
The group of radio buttons is formed by using a consistent name
in all the INPUT tags.
The radio element is accessible
in JavaScript through the radio
object, which has several properties for checking the current
status of a radio button group. Table 6.4 outlines the properties
and methods available with the radio
object.
Table 6.4. Properties and methods for the radio
object.
Method or Property | Description
|
checked
| Indicates the current status of the radio element (property)
|
defaultChecked
| Indicates the default status of the element (property)
|
index |
Indicates the index of the currently selected radio button in the group
|
length
| Indicates the number of radio buttons in a group
|
name |
Indicates the name of the element as specified in the INPUT tag (property)
|
value |
Indicates the current value of the element as specified in the INPUT tag (property)
|
click()
| Emulates a click in the radio button (method)
|
As with checkboxes, the single event handler, onClick,
is available for radio buttons.
The index and length
properties haven't appeared in any of the form elements we have
looked at so far in this chapter. Because a radio button group
contains multiple elements, the radio
object maintains an array of the radio buttons with indexes starting
at zero. In the example of a radio button group named "test"
above, if the group were part of a form named "testform",
you could reference the second radio button as testform.test[1],
and you could check the current status of the button with testform.test[1].checked.
To illustrate usage of the radio
object, you can rewrite Listing 6.2, used to demonstrate heckboxes,
using radio buttons instead.
Listing 6.3. Doubling and squaring with radio buttons.
<HTML>
<HEAD>
<TITLE>radio button Example</TITLE>
<SCRIPT>
<!-- HIDE FROM OTHER BROWSERS
function calculate(form,callingField) {
if (callingField == "result") {
if (form.action[1].checked) {
form.entry.value = Math.sqrt(form.result.value);
} else {
form.entry.value = form.result.value
/ 2;
}
} else {
if (form.action[1].checked) {
form.result.value = form.entry.value
* form.entry.value;
} else {
form.result.value = form.entry.value
* 2;
}
}
}
// STOP HIDING FROM OTHER BROWSERS -->
</SCRIPT>
</HEAD>
<BODY>
<FORM METHOD=POST>
Value: <INPUT TYPE="text" NAME="entry"
VALUE=0
onChange="calculate(this.form,this.name);">
<BR>
Action:<BR>
<INPUT TYPE="radio" NAME="action" VALUE="twice"
onClick="calculate(this.form,this.name);">
Double<BR>
<INPUT TYPE="radio" NAME="action" VALUE="square"
onClick="calculate(this.form,this.name);">
Square <BR>
Result: <INPUT TYPE=text NAME="result" VALUE=0
onChange="calculate(this.form,this.name);">
</FORM>
</BODY>
</HTML>
 |
In this example, the changes from the checkbox version are subtle. Instead of one checkbox, you now have a pair of radio buttons with different values: double and square.
|
You know that the individual radio buttons are accessible through
an array so that the double button is action[0]
and the square button is action[1].
In this way, you need to change only the references in the calculate()
function from form.square.checked
to form.action[1].checked.
Using the reset object in
JavaScript, you can react to clicks on the Reset button. Like
the button object, the reset
object has two properties (name
and value) and one method
(click()). The onClick
event handler is also available.
Note |
A bug in Navigator 2 results in odd behavior with the Reset button: When text fields are cleared by the Reset button, this isn't reflected into the corresponding element until the field is given focus.
|
Although most programmers do not find a need to use the onClick
event handler for reset buttons or need to check the value of
the button, the reset object
can be used to clear the form to some value other than the default.
Listing 6.4. demonstrates how the Reset button can be used to
clear a form to values other than the default.
Listing 6.4. Clearing a form to new values with Reset.
<HTML>
<HEAD>
<TITLE>reset Example</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!-- HIDE FROM OTHER BROWSERS
function clearForm(form) {
form.value1.value = "Form";
form.value2.value = "Cleared";
}
// STOP HIDING FROM OTHER BROWSERS -->
</SCRIPT>
</HEAD>
<BODY>
<FORM METHOD=POST>
<INPUT TYPE="text" NAME="value1"><BR>
<INPUT TYPE="text" NAME="value2"><BR>
<INPUT TYPE="reset" VALUE="Clear Form"
onClick="clearForm(this.form);">
</FORM>
</BODY>
</HTML>
 |
This script is fairly simple. You have created a form with two text fields and a Reset button. The Reset button has an onClick event handler, which calls clearForm() when the button is clicked.
|
The clearForm() function
takes the form object as
an argument and proceeds to place two new values in the two text
fields of the form.
Selection lists in HTML forms appear as drop-down menus or scrollable
lists of selectable items. Lists are built using two tags: SELECT
and OPTION. For instance,
the following code snippet
<SELECT NAME="test">
<OPTION SELECTED>1
<OPTION>2
<OPTION>3
</SELECT>
creates a three-item, drop-down menu with the choices 1, 2, and
3. Using the SIZE attribute
you can create a scrollable list with the number of elements visible
at one time indicated by the value of the SIZE
attribute. To turn your drop-down menu into a scrollable menu
with two visible items you could use the following:
<SELECT NAME="test" SIZE=2>
<OPTION SELECTED>1
<OPTION>2
<OPTION>3
</SELECT>
In both of these examples, the user can make only one choice.
Using the MULTIPLE attribute,
you can enable the user to select more than one choice in a scrollable
selection list:
<SELECT NAME="test" SIZE=2
MULTIPLE>
<OPTION SELECTED>1
<OPTION>2
<OPTION>3
</SELECT>
Selection lists are accessible in JavaScript through the select
object. This object bears some similarity to both the buttons
you have seen, as well as with radio buttons.
As with radio buttons, the list of options is maintained as an
array with indexes starting at zero. In this case, the array is
a property of the select
object called options.
Both selection option and the individual option elements have
properties. In addition to the options
array, the select object
has the selectedIndex property,
which contains the index number of the currently selected option.
Each option in a selection list also has several properties. defaultSelected
indicates whether the option is selected by default in the OPTION
tag. The index property contains
the index value of the current option in the options
array. Again, as you might expect, selected
indicates the current status of the option, text
contains the value of the text displayed in the menu for the specific
option, and value contains
any value indicated in the OPTION
tag.
The select object has no
available methods. However, the select
object has three event handlers that don't correspond to the available
event emulating method. These are onBlur,
onFocus, and onChange-the
same as for the text object.
Note |
In the current version of JavaScript, the onChange event handler is not invoked immediately after the user changes his selection. Rather, once the user leaves the selection list (that is, removes focus from the list), then the onChange
event handler works.
|
For example, if you have the following selection list:
<SELECT NAME="example" onFocus="react();">
<OPTION SELECTED VALUE="Number One">1
<OPTION VALUE="The Second">2
<OPTION VALUE="Three is It">3
</SELECT>
then when the list is first displayed, you would have access to
the following information:
example.options[1].value = "The
Second"
example.options[2].text = "3"
example.selectedIndex = 0
example.options[0].defaultSelected = true
example.options[1].selected = false
If the user then clicks on the menu and selects the second option,
the onFocus event handler
would execute (the react()
function would be called), and then the values of these same properties
would be as follows:
example.options[1].value = "The
Second"
example.options[2].text = "3"
example.selectedIndex = 1
example.options[0].defaultSelected = true
example.options[1].selected = true
Modifying Select Lists
In Navigator 3.0, it is possible to change the content of a select
list from inside JavaScript by assigning new values to the list
entries' text property.
For instance, in the example earlier where you created the following
selection list,
<SELECT NAME="example" onFocus="react();">
<OPTION SELECTED VALUE="Number One">1
<OPTION VALUE="The Second">2
<OPTION VALUE="Three is It">3
</SELECT>
it would be possible to change the text displayed for the second
entry to "two" with
example.options[1].text = "two";
New options can be added to the list using the Option()
constructor object with the syntax:
newOptionName
= new Option(optionText, optionValue, defaultSelected,
selected);
selectListName.options[index] = newOptionName;
This creates an option object
with the specified text and the defaultSelected
and selected states for the
option specified as Boolean values. This object is then assigned
to an entry in the selection list specified by index.
Options can be deleted from the option list by assigning null
to the option object for the particular entry:
selectListName.options[index] = null;
The Submit button is another special-purpose button like the Reset
button. This button submits the current information from each
field of the form to the URL specified in the ACTION
attribute of the FORM tag
using the METHOD indicated
in the FORM tag.
Like with the button object
and the reset object, you
have name and value
properties available to you, along with a click()
method and an onClick event
handler.
text elements are among the
most common entry fields used in HTML forms. Similar to the password
field you looked at earlier, text fields enable a single line
of text entry, but unlike the password element, the text is displayed
as normal type rather than as asterisks.
The text object has three
properties: defaultValue,
name, and value.
Three methods emulate user events: focus(),
blur(), and select()
(which selects the text in the entry field). Four event handlers
are available: onBlur, onFocus,
onChange, and onSelect
(for when the user selects some of the text in the field).
Table 6.5 outlines the properties and methods for the text
element.
Table 6.5. Properties and methods for the text
object.
Method or Property | Description
|
defaultValue
| Indicates the default value of the element as specified in INPUT tag (property)
|
name |
Indicates the name of the element as specified in the INPUT tag (property)
|
value |
Indicates the current value of the element (property)
|
focus()
| Emulates giving focus to the text field (method)
|
blur()
| Emulates removing focus from the text field (method)
|
select()
| Emulates selecting text in the text field (method)
|
It is important to note that the content of a text field can be
changed by assigning values to the value
property. Thus, in the following example, text entered in the
first field is echoed in the second field, and any text entered
in the second field is echoed in the first field. By itself, this
has little value, but the ability to use data from a text field
and to dynamically update and change data in a text field is a
powerful feature of JavaScript as shown in Listing 6.5.
Listing 6.5. Dynamically updating text fields.
<HTML>
<HEAD>
<TITLE>text Example</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!-- HIDE FROM OTHER BROWSERS
function echo(form,currentField) {
if (currentField == "first")
form.second.value = form.first.value;
else
form.first.value = form.second.value;
}
// STOP HIDING FROM OTHER BROWSERS -->
</SCRIPT>
</HEAD>
<BODY>
<FORM>
<INPUT TYPE=text NAME="first" onChange="echo(this.form,this.name);">
<INPUT TYPE=text NAME="second" onChange="echo(this.form,this.name);">
</FORM>
</BODY>
</HTML>
Note |
In versions of Navigator 2.0, the onChange event handler is not invoked as soon as the user types a change. Rather, it is invoked when focus leaves the field and the text has changed.
|
The TEXTAREA tag provides
a custom size multiple-line text entry field defined by a container.
The example in this code
<TEXTAREA NAME="fieldName"
ROWS=10 COLS=25>
Default Text Here
</TEXTAREA>
creates a text entry field of 10 rows with 25 characters on each
line. The words Default Text Here
would appear in the field when it is first displayed.
Like the text element, JavaScript
provides you with the defaultValue,
name, and value
properties, the focus(),
blur(), and select()
methods and the onBlur, onFocus,
onChange, and onSelect
event handlers.
Now that we have taken a detailed look at the form
object, its elements, properties, and methods, you are ready to
use this information to build a somewhat more complicated script.
In this example, you will build a simple mathematical calculator
using forms. That is, each number and the four mathematical functions
(addition, subtraction, multiplication, and division) will each
be a button. You will also have two other buttons: one to clear
the running total and the other to clear the current entry.
In order to make your calculator appear more organized, you will
make use of HTML tables. For those without experience using tables,
tables are contained in the TABLE
container tag and consist of rows contained in the TR
tag and column elements contained in the TD
tag. In addition, the COLSPAN
attribute causes a cell to cover two columns. Similarly, ROWSPAN
makes a cell two rows deep.
For instance, the HTML code in Listing 6.6 produces a simple table.
Listing 6.6. A simple table.
<TABLE BORDER=1>
<TR>
<TD COLSPAN=2>This is a table</TD>
</TR>
<TR>
<TD>One</TD>
<TD>Two</TD>
</TR>
<TR>
<TD>Three</TD>
<TD>Four</TD>
</TR>
</TABLE>
The output from Listing 6.6 looks like the one in Figure 6.2.
Figure 6.2 : HTML tables contain rows and columns of cells.
Using tables, then, you are ready to work on developing your calculator.
In terms of behavior, your calculator should work the way a simple
electronic calculator does: When a user enters a number, it is
immediately displayed to the right of previously entered digits.
Mathematical functions are executed in the order entered (no precedence
here), and the effects of operations are cumulative until the
clear button is pressed. Listing 6.7 is the source code for this
calculator.
Listing 6.7. Creating a calculator with tables.
<HTML>
<HEAD>
<TITLE>Example 6.7</TITLE>
<SCRIPT>
<!-- HIDE FROM OTHER BROWSERS
var total = 0;
var lastOperation = "+";
var newnumber = true;
function enterNumber(digit) {
var form = digit.form;
if (newnumber) {
clearNumber(form);
newnumber = false;
}
form.display.value = form.display.value + digit.name;
}
function clear(form) {
total = 0;
lastOperation = "+";
form.display.value = "";
}
function clearNumber(form) {
form.display.value = "";
}
function calculate(operation) {
var form = operation.form;
var expression = total + lastOperation + form.display.value;
lastOperation = operation.value;
total = eval(expression);
form.display.value = total;
newnumber = true;
}
// STOP HIDING FROM OTHER BROWSERS -->
</SCRIPT>
</HEAD>
<BODY>
<FORM>
<TABLE BORDER=1>
<TR>
<TD COLSPAN=4>
<INPUT TYPE=text NAME=display VALUE="" onFocus="this.blur();">
</TD>
</TR>
<TR>
<TD>
<INPUT TYPE=button NAME="7" VALUE=" 7 "
onClick="enterNumber(this);">
</TD>
<TD>
<INPUT TYPE=button NAME="8" VALUE=" 8 "
onClick="enterNumber(this);">
</TD>
<TD>
<INPUT TYPE=button NAME="9" VALUE=" 9 "
onClick="enterNumber(this);">
</TD>
<TD>
<INPUT TYPE=button NAME="+" VALUE=" + "
onClick="calculate(this);">
</TD>
</TR>
<TR>
<TD>
<INPUT TYPE=button NAME="4" VALUE=" 4 "
onClick="enterNumber(this);">
</TD>
<TD>
<INPUT TYPE=button NAME="5" VALUE=" 5 "
onClick="enterNumber(this);">
</TD>
<TD>
<INPUT TYPE=button NAME="6" VALUE=" 6 "
onClick="enterNumber(this);">
</TD>
<TD>
<INPUT TYPE=button NAME="-" VALUE=" - "
onClick="calculate(this);">
</TD>
</TR>
<TR>
<TD>
<INPUT TYPE=button NAME="1" VALUE=" 1 "
onClick="enterNumber(this);">
</TD>
<TD>
<INPUT TYPE=button NAME="2" VALUE=" 2 "
onClick="enterNumber(this);">
</TD>
<TD>
<INPUT TYPE=button NAME="3" VALUE=" 3 "
onClick="enterNumber(this);">
</TD>
<TD>
<INPUT TYPE=button NAME="*" VALUE=" * "
onClick="calculate(this);">
</TD>
</TR>
<TR>
<TD>
<INPUT TYPE=button NAME="0" VALUE=" 0 "
onClick="enterNumber(this);">
</TD>
<TD>
<INPUT TYPE=button NAME="C" VALUE=" C "
onClick="clear(this.form);">
</TD>
<TD>
<INPUT TYPE=button NAME="CE" VALUE="CE"
onClick="clearNumber(this.form);">
</TD>
<TD>
<INPUT TYPE=button NAME="/" VALUE=" / "
onClick="calculate(this);">
</TD>
</TR>
</TABLE>
</FORM>
</BODY>
</HTML>
This script produces results like those in Figure 6.3.
Figure 6.3 : Tables make the calculator look appealing, and JavaScript makes it work.
 |
Several interesting techniques are used in this script. Let's take a look at selected parts of the script sequentially from the start.
|
var total = 0;
var lastOperation = "+";
var newnumber = true;
Here you declare the global variables to keep track of information.
The total variable contains
the current running total of the user's calculations. This is
the same as the last displayed value before the user began entering
a new number. lastOperation
is used to keep track of the operation last entered by the user
to be performed on the running total and the newly entered number.
newnumber is used to keep
track of when user input should be treated as a new number or
part of the currently displayed number.
The initial values of these variables require some explanation.
Obviously, total starts with
a zero value. However, as you will see later in the calculate()
function, you need a lastOperation
value to perform on every number entered. By assigning the value
"+" to lastOperation,
the first number entered by the user will be added to the initial
total of zero.
function enterNumber(digit) {
var form = digit.form;
if (newnumber) {
clearNumber(form);
newnumber = false;
}
form.display.value = form.display.value + digit;
}
You pass the currently clicked button object to enterNumber()
as the argument digit. The
line var form = digit.form;
provides you with reference to the form containing the current
button in much the same way as when you pass this.form
to a function.
Because each new digit is added to the right side of the number,
you can treat the digits as strings to concatenate.
function calulate(operation) {
var form = operation.form;
var expression = total + lastOperation + form.display.value;
lastOperation = operation.value;
total = eval(expression);
form.display.value = total;
newnumber = true;
}
The calculate() function
is where the real work of the calculator script is done. The function
is invoked when the user clicks on one of the operator buttons.
When this happens, the line var expression
= total + lastOperation + form.display.value; builds
an expression in the form of a string.
You then use the eval() function
to evaluate the expression you have just built. This value becomes
the new value of total, is
displayed in the text field, and the operation the user has just
clicked is assigned to lastOperation.
One component of this calculator that is lacking is an equal (
= ) button. To implement
it would require changing the logic of the calculate()
function.
As mentioned in the section on the properties of the form
object, all the elements in a form can also be referenced by the
elements[] array. For instance,
you could create the following form:
<FORM METHOD=POST NAME=testform>
<INPUT TYPE="text" NAME="one">
<INPUT TYPE="text" NAME="two">
<INPUT TYPE="text" NAME="three">
</FORM>
You can refer to the three elements as document.testform.elements[0],
document.testform.elements[1],
and document.testform.elements[2]
in addition to the obvious document.testform.one,
document.testform.two, document.testform.three.
This can be useful in situations where the sequential relationship
of form elements is more important than their names.
In this example, you will take advantage of the elements[]
array to build a simple dynamic multiplication table. The form
will have 11 elements. The user fills in the first field to specify
which multiplication table to calculate, and the rest of the fields
provide the 1 to 10 multiplication table for that number.
Listing 6.8. Using the elements[]
array in a multiplication table.
<HTML>
<HEAD>
<TITLE>Example 6.8</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!-- HIDE FROM OTHER BROWSERS
function calculate(form) {
var num=1;
var number=form.number.value;
form.elements[num].value = number * num++;
form.elements[num].value = number * num++;
form.elements[num].value = number * num++;
form.elements[num].value = number * num++;
form.elements[num].value = number * num++;
form.elements[num].value = number * num++;
form.elements[num].value = number * num++;
form.elements[num].value = number * num++;
form.elements[num].value = number * num++;
form.elements[num].value = number * num++;
}
// STOP HIDING FROM OTHER BROWSERS -->
</SCRIPT>
</HEAD>
<BODY>
<FORM METHOD=POST>
Number: <INPUT TYPE=text NAME="number" VALUE=1
onChange="calculate(this.form);"><BR>
x 1: <INPUT TYPE=text NAME="1" VALUE=1 onFocus="blur();"><BR>
x 2: <INPUT TYPE=text NAME="2" VALUE=2 onFocus="blur();"><BR>
x 3: <INPUT TYPE=text NAME="3" VALUE=3 onFocus="blur();"><BR>
x 4: <INPUT TYPE=text NAME="4" VALUE=4 onFocus="blur();"><BR>
x 5: <INPUT TYPE=text NAME="5" VALUE=5 onFocus="blur();"><BR>
x 6: <INPUT TYPE=text NAME="6" VALUE=6 onFocus="blur();"><BR>
x 7: <INPUT TYPE=text NAME="7" VALUE=7 onFocus="blur();"><BR>
x 8: <INPUT TYPE=text NAME="8" VALUE=8 onFocus="blur();"><BR>
x 9: <INPUT TYPE=text NAME="9" VALUE=9 onFocus="blur();"><BR>
x 10: <INPUT TYPE=text NAME="10" VALUE=10 onFocus="this.blur();"><BR>
<ITEM TYPE=button NAME="calculcate" VALUE="Calculate"
onClick="calculate(this.form);">
</FORM>
</BODY>
</HTML>
Listing 6.8 produces results similar to those in Figure 6.4.
Figure 6.4 : Using the elements[ ] array, you can reference each field in order.
 |
Notice in this script that you can refer to form elements by number. Because the elements[] array starts with an index of zero, you have made the first element (index zero) the entry field and have started the multiplication table with element two
(which has an index value of one).
|
In the function calculate(),
you use the variable num
as a counter which starts at one. You use the following command
10 times to build the multiplication table:
form.elements[num].value = number * num++;
What this line tells you to do is assign the value of number
* num to the current element and then increase num
by one. This provides an excellent example of how to use the unary
increment operator (++) to
return the value of an expression and then increase it by one.
Typically, you would not write the calculate()
function the way you have here. Instead, you would use a for
loop:
function calculate(form) {
var number=form.number.value;
for(num = 1; num <= 10; num++) {
form.elements[num].value = number * num;
}
}
for loops are covered in
Chapter 7, "Loops."
While event handlers are generally designed to work with individual
forms or fields, at times, it is useful to be able to reference
forms in relationship to other forms on a page.
This is where the document.forms[]
array comes into play. It would be possible to have multiple identical
forms on the same page and have information in a single field
match in all three forms. This could be more easily achieved using
the document.forms[] array
than with form names. In this script, you have two text entry
fields in separate forms. Using the forms[]
array, you keep the value of the fields in each form the same
when the user changes a value in one form.
<HTML>
<HEAD>
<TITLE>forms[] Example</TITLE>
</HEAD>
<BODY>
<FORM METHOD=POST>
<INPUT TYPE=text onChange="document.forms[1].elements[0].value
= this.value;">
</FORM>
<FORM METHOD=POST>
<INPUT TYPE=text onChange="document.forms[0].elements[0].value
= this.value;">
</FORM>
</BODY>
</HTML>
In addition to referring to forms numerically in the forms[]
array, they can also be refereed to by name. Using the NAME
attribute of the FORM tag,
you can assign a name to a form:
<FORM METHOD=POST NAME="name">
Then, this form can be referred to as document.forms["name"]
or as document.name.
Now you are going to put together some of the skills you have
learned in this chapter in a different type of interactive form.
Usually, text entry forms consist of field names followed by fields.
What you want to do is produce forms where the field name (that
is, the prompt for the field) is the initial value of the field.
This should look like the example in Figure 6.5.
Figure 6.5 : Prompt information as a field's default value looks less cluttered on landegg Academy's home page.
If the user clicks in an unchanged field, the field clears and
the user enters information. If he moves the focus out of the
field and hasn't entered any information, the original content
reappears.
At the same time, if the user clicks in a field that contains
data entered by the user, the field is not cleared.
This can be done by developing a general-purpose set of functions,
such as those in Listing 6.9.
Listing 6.9. An interactive entry form.
<HTML>
<HEAD>
<TITLE>Listing 6.9</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!-- HIDE FROM OTHER BROWSERS
function clearField(field) {
// Check if field contains the default value
if (field.value == field.defaultValue) {
// It does, so clear the field
field.value = "";
}
}
function checkField(field) {
// Check if user has entered information in the field
if (field.value == "") {
// User has not entered anything
field.value = field.defaultValue;
}
}
// STOP HIDING FROM OTHER BROWSERS -->
</SCRIPT>
</HEAD>
<BODY>
<FORM METHOD=POST>
<INPUT TYPE=text NAME="name" VALUE="Name"
onFocus="clearField(this);"
onBlur="checkField(this);">
<BR>
<INPUT TYPE=text NAME="email" VALUE="E-mail
Address"
onFocus="clearField(this);"
onBlur="checkField(this);">
<BR>
<INPUT TYPE=text NAME="phone" VALUE="Phone Number"
onFocus="clearField(this);"
onBlur="checkField(this);">
</FORM>
</BODY>
</HTML>
This script produces a form with three text entry fields that
looks like Figure 6.6. If a user clicks in the "E-mail"
field, the result is similar to Figure 6.7.
Figure 6.6 : A form with prompt information as the default value for each field.
Figure 6.7 : The clearField() function clears the content of a field if needed.
 |
In Listing 6.9, you highlight the use of the defaultValue property. By using this, you are able to build two simple functions, clearField() and checkField(), to handle all the work.
|
clearField() is called when
the user places focus in a field. By comparing the current value
of the field with the default value, the function decides whether
it should clear the field before the user starts entering information.
Similarly, checkField() is
called when the focus leaves a field. If the content of the field
is blank, then the default value is reassigned to the field.
In this chapter, you have taken the major step from simple scripts
to complex, interactive Web page development using JavaScript.
By working with form elements and event handlers, you can write
scripts that enable sophisticated user interaction. For instance,
you can develop simple spreadsheets, complex calculators, and
can perform error checking before sending forms to a server for
processing by CGI scripts.
Event handlers are specified HTML tags. Event handlers take as
their values JavaScript code, usually in the form of a function
call.
In order to step beyond the bounds of the simple sort of processes
you have been scripting up to this point, in Chapter 7,
you will take a detailed look at loops, which provide you with
increased control over the flow of a program.
Command/Extension | Type
| Description |
blur()
| JavaScript method | Emulates removing focus from a form element
|
form.action
| JavaScript property | String containing the value of the ACTION attribute of the FORM tag
|
form.elements
| JavaScript property | Array containing an entry for each element in the form (such as checkboxes, text fields, and selection lists)
|
form.encoding
| JavaScript property | String containing the MIME type used when submitting form data to the server
|
form.name
| JavaScript property | String containing the value of the NAME attribute of the FORM tag
|
form.target
| JavaScript property | String containing the name of the window targeted by a form submission
|
form.submit()
| JavaScript method | Emulates the submission of an HTML form
|
type |
JavaScript property | Reflects the type of a form element as a string
|
onSubmit
| Event handler | Event handler for the submission of an HTML form
|
button
| HTML attribute | Type attribute for HTML buttons (<INPUT TYPE=button>)
|
checkbox
| HTML attribute | Type attribute for checkbox toggle switches (<INPUT TYPE=checkbox>)
|
password
| HTML attribute | Type attribute for password text entry fields (<INPUT TYPE=password>)
|
radio |
HTML attribute | Type attribute for radio button toggle switches in forms (<INPUT TYPE=radio>)
|
reset |
HTML attribute | Type attribute for reset buttons (<INPUT TYPE=reset>)
|
SELECT
| HTML tag | Container tag for selection lists
|
OPTION
| HTML tag | Indicates options in a selection list (<SELECT><OPTION>Option 1<OPTION>Option 2</SELECT>)
|
submit
| HTML attribute | Type attribute for submit buttons (<INPUT TYPE=submit>)
|
text |
HTML attribute | Type attribute for text fields in forms (<INPUT TYPE=text>)
|
TEXTAREA
| HTML tag | Container tag for multiline text entry field (<TEXTAREA>default text</TEXTAREA>)
|
name |
JavaScript property | String containing the name of an HTML element (button, checkbox, password, radio button, reset, submit, text, text area)
|
value |
JavaScript property | String containing the current value of an HTML element (button, checkbox, password, radio button, reset, selection list, submit, text, text area)
|
click()
| JavaScript method | Emulates clicking on a form element (button, checkbox, radio button, reset, selection list, submit)
|
onClick
| JavaScript property | Event handler for a click event (button, checkbox, radio button, reset, submit)
|
checked
| JavaScript property | Boolean value indicating if a choice is checked (checkbox, radio button)
|
defaultChecked
| JavaScript property | Boolean value indicating if a choice is checked by default (checkbox, radio button)
|
defaultvalue
| JavaScript property | String containing the default value of an HTML element (password, text, text area)
|
focus()
| JavaScript method | Emulates giving focus to an element (password, text, text area)
|
blur()
| JavaScript method | Emulates removing focus from an element (password, text, text area)
|
select()
| JavaScript method | Emulates selecting text in a field (password, text, text area)
|
onFocus
| Event handler | Event handler for a focus event (password, selection list, text, text area)
|
onBlur
| Event handler | Event handler for a blur event (password, selection list, text, text area)
|
onChange
| Event handler | Event handler for when the value of a field changes (password, selection list, text, text area)
|
onSelect
| Event handler | Event handler for when the user selects text in a field (password, text, text area)
|
index |
JavaScript property | Integer indicating the current choice from a group of choices (radio button, selection list)
|
length
| JavaScript property | Integer indicating the number of choices in a group of choices (radio button)
|
defaultSelected
| JavaScript property | Boolean value indicating if a choice is selected by default (selection list)
|
options
| JavaScript property | Array of options in a selection list
|
text |
JavaScript property | Text displayed for a menu item in a selection list
|
TABLE |
HTML tag | Container tag for HTML tables
|
TR |
HTML tag | Container tag for rows of an HTML table
|
TD |
HTML tag | Container tag for cells of an HTML table
|
COLSPAN
| HTML attribute | Attribute of the TD tag to indicate if a cell spans multiple columns
|
ROWSPAN
| HTML attribute | Attribute of the TD tag to indicate if a cell spans multiple rows
|
BORDER
| HTML attribute | Attribute of the TABLE tag to indicate the width of the borders in a table
|
document.forms[]
| JavaScript property | Array of form objects with an entry for each form in a document
|
string.substring()
| JavaScript method | Returns a portion of the string based on being passed the indexes of the first and last character as arguments
|
Math.floor()
| JavaScript method | Returns the next integer value less than the argument
|
string.length
| JavaScript property | Integer value indicating the index of the last character in a string
|
Note |
The Math.floor() and string.substring() methods will be used in the exercises later in this chapter. More details about the use of these methods will be discussed at that time.
|
Q | Can I dynamically change the text in a button or on a drop-down SELECT list by assigning values to properties such as button.value?
|
A | Yes and No. Select lists can be changed dynamically by assigning new values to the text property of each list entry. However, in Navigator 2, once buttons are rendered, their appearance is fixed and cannot be changed. In
Navigator 3, new values can be assigned to the value property of a button object to change the text label displayed in the button.
|
Q | Is it possible to have an event handler, maybe onChange, invoked with each keystroke as a user enters data in a text field?
|
A | No, the onChange event handler is invoked only when focus leaves the field. Currently, there is no way to trap and react to individual keystrokes.
|
This capability is expected to be included in the next release
of Netscape Navigator.
- Which of these HTML tags are valid?
a. <FORM METHOD=POST
onClick="go();">
b. <BODY
onLOAD="go();">
c. <INPUT
TYPE=text onChange="go();">
d. <INPUT
TYPE=checkbox onChange="go();">
e. <BODY
onUnload="go();">
f. <INPUT
TYPE=text onClick="go();">
- Take the script from Listing 6.7 (the calculator program)
and extend it to add the following:
- A positive/negative toggle button (that is, click on the button
and the currently entered number changes sign).
- A decimal point button so that the user can enter floating
point numbers.
- Check for errors as the user performs actions-specifically,
check that the user is not trying to divide by zero and the user
does not enter two decimal points. (If the user divides by zero,
display a warning, and don't perform the action; if the user enters
a second decimal point, ignore it.)
- Extend the functionality of Listing 6.9 to check optionally
whether entered information is in a specific numeric range and,
if not, to warn the user.
- The following are valid: (c) and (e). Example (a) is not valid
because onClick is not a
valid event handler for the BODY
tag; (b) is wrong because JavaScript is case sensitive and the
correct form is onLoad; (d)
is incorrect because checkboxes have the onClick
event handler only; and (f) is incorrect because the onClick
event handler is not available for text fields.
- In the following script, you can add three functions to implement
the additional features:
Listing 6.10. Adding features to the calculator.
<HTML>
<HEAD>
<TITLE>Exercise 6.2</TITLE>
<SCRIPT>
<!-- HIDE FROM OTHER BROWSERS
var total = 0;
var lastOperation = "+";
var newnumber = true;
function enterNumber(digit) {
var form = digit.form;
if (newnumber) {
clearNumber(form);
newnumber = false;
}
form.display.value = form.display.value + digit.name;
}
function clear(form) {
total = 0;
lastOperation = "+";
form.display.value = 0;
}
function clearNumber(form) {
form.display.value = 0;
}
function calculate(operation) {
var form = operation.form;
if (checkErrors(form)) {
var expression = total + lastOperation
+ form.display.value;
lastOperation = operation.value;
total = eval(expression);
form.display.value = total;
newnumber = true;
} else {
alert("You cannot divide by zero!");
form.display.value = "";
}
}
function changeSign(form) {
var num = eval(form.display.value);
form.display.value = -num;
if (newnumber)
total = -num;
}
function decimalPoint(form) {
if (Math.floor(form.display.value) == form.display.value)
{
form.display.value += ".";
}
}
function checkErrors(form) {
noErrors = true;
if ((lastOperation == "/") && (form.display.value
== 0))
noErrors = false;
return noErrors;
}
// STOP HIDING FROM OTHER BROWSERS -->
</SCRIPT>
</HEAD>
<BODY>
<FORM>
<TABLE BORDER = 1>
<TR>
<TD COLSPAN=4>
<INPUT TYPE=text NAME=display VALUE="0" >
</TD>
</TR>
<TR>
<TD>
<INPUT TYPE=button NAME="7" VALUE=" 7 "
onClick="enterNumber(this);">
</TD>
<TD>
<INPUT TYPE=button NAME="8" VALUE=" 8 "
onClick="enterNumber(this);">
</TD>
<TD>
<INPUT TYPE=button NAME="9" VALUE=" 9 "
onClick="enterNumber(this);">
</TD>
<TD>
<INPUT TYPE=button NAME="+" VALUE=" + "
onClick="calculate(this);">
</TD>
</TR>
<TR>
<TD>
<INPUT TYPE=button NAME="4" VALUE=" 4 "
onClick="enterNumber(this);">
</TD>
<TD>
<INPUT TYPE=button NAME="5" VALUE=" 5 "
onClick="enterNumber(this);">
</TD>
<TD>
<INPUT TYPE=button NAME="6" VALUE=" 6 "
onClick="enterNumber(this);">
</TD>
<TD>
<INPUT TYPE=button NAME="-" VALUE=" - "
onClick="calculate(this);">
</TD>
</TR>
<TR>
<TD>
<INPUT TYPE=button NAME="1" VALUE=" 1 "
onClick="enterNumber(this);">
</TD>
<TD>
<INPUT TYPE=button NAME="2" VALUE=" 2 "
onClick="enterNumber(this);">
</TD>
<TD>
<INPUT TYPE=button NAME="3" VALUE=" 3 "
onClick="enterNumber(this);">
</TD>
<TD>
<INPUT TYPE=button NAME="*" VALUE=" * "
onClick="calculate(this);">
</TD>
</TR>
<TR>
<TD>
<INPUT TYPE=button NAME="0" VALUE=" 0 "
onClick="enterNumber(this);">
</TD>
<TD>
<INPUT TYPE=button NAME="C" VALUE=" C "
onClick="clear(this.form);">
</TD>
<TD>
<INPUT TYPE=button NAME="CE" VALUE="CE"
[ic:ccc] onClick="clearNumber(this.form);">
</TD>
<TD>
<INPUT TYPE=button NAME="/" VALUE=" / "
onClick="calculate(this);">
</TD>
</TR>
<TR>
<TD>
<INPUT TYPE=button NAME="sign" VALUE="+/-"
ÂonClick="changeSign(this.form);">
</TD>
<TD>
</TD>
<TD>
<INPUT TYPE=button NAME="decimal" VALUE=" . "
ÂonClick="decimalPoint(this.form);">
</TD>
<TD>
</TD>
</TR>
</TABLE>
</FORM>
</BODY>
</HTML>
This script produces a calculator that looks like the one in Figure
6.8.
Figure 6.8 : Two buttons and three functions added to the calculator.
 |
There are several points worth noting in this new version of the calculator program. First, you make use of the unary negation operation (-) in the changeSign() function.
|
In the decimalPoint() function,
you check whether the number is currently a floating point value
by using the Math.floor()
method. Only an integer evaluates to itself using Math.floor()
and only integers lack a decimal point (in this particular case).
It is important to note that this method isn't foolproof. A user
could still enter two decimal points in a row.
You can handle this by using the substring()
method of the string object
to check if the last character of the display field is already
a decimal point. The substring()
method takes two arguments as follows:
stringname.substring(firstCharacter,lastCharacter)
where firstCharacter and
lastCharacter are the numeric
offset of the desired characters from the start of a string. The
numeric offset is calculated based on the first character being
number zero. So, if you have a variable called testString
with the value "JavaScript",
then testString.substring(1,4)
returns a value of "avaS".
Of course, in this example, you don't know the numeric offset
of the last character in form.display.value.
You can find this out by using the string.length
property. Now you can test whether the last character is a decimal
point using the expression:
(form.display.value.substring(form.display.value.length,
form.display.value.length)
== ".")
Then, the decimalPoint()
function would look like this:
function decimalPoint(form) {
var lastChar = form.display.value.length;
var display = form.display.value;
if ((Math.floor(form.display.value) == form.display.value)
||
(display.substring(lastChar,lastChar)
== ".")) {
form.display.value += ".";
}
}
The last function you added to your script is checkErrors().
In this script you simply check whether the last operation is
divide and the current value is zero, and then you alert the user
and disallow the operation.
- In order to extend the functionality to include the optional
range checking and alert, you need to add an additional function:
function checkRange(field,low,high,message)
{
if (field.value != "") {
if ((field.value < low) || (field.value
> high)) {
alert(message);
field.value="";
field.focus();
}
} else {
checkField(field);
}
}
This function first checks whether the user has entered
information. If she has, it checks the range; if the information
is outside the range, the function alerts the user, clears the
field, and returns focus to the field.
If there is no data entered, the function calls checkField(),
which displays the default value in the field.