Javascript M TRL
Javascript M TRL
Javascript M TRL
You're about to begin a journey into the depths of JavaScript, one of the hottest new languages
for Web page development. JavaScript enables Web pages to be interactive and intelligent, and
can add excitement to an otherwise dreary page.
If you've worked with HTML-the language of the Web-and have a basic idea of the concepts of
programming, you should have no trouble understanding JavaScript. It's a simple and flexible
language. This chapter starts with an introduction to JavaScript: its history, its features, and its
limitations.
What Is JavaScript?
An explanation of exactly what JavaScript is has to begin with Java. Java is a new kind of Web
programming language developed by Sun Microsystems. A Java program, or applet, can be
loaded by an HTML page and executed by the Java Interpreter, which is embedded into the
browser.
Java is a complex language, similar to C++. Java is object-oriented and has a wide variety of
capabilities; it's also a bit confusing and requires an extensive development cycle. That's where
JavaScript comes in.
JavaScript is one of a new breed of Web languages called scripting languages. These are simple
languages that can be used to add extra features to an otherwise dull and dreary Web page.
While Java is intended for programmers, scripting languages make it easy for nonprogrammers to
improve a Web page.
JavaScript was originally developed by Netscape Corporation for use in its browser, Netscape
Navigator. It includes a convenient syntax, flexible variable types, and easy access to the
browser's features. It can run on the browser without being compiled; the source code can be
placed directly into a Web page.
You can program in JavaScript easily; no development tools or compilers are required. You can
use the same editor you use to create HTML documents to create JavaScript, and it executes
directly on the browser (currently, Netscape or Microsoft Internet Explorer).
JavaScript was originally called LiveScript, and was a proprietary feature of the Netscape
browser. JavaScript has now been approved by Sun, the developer of Java, as a scripting
language to complement Java. Support has also been announced by several other companies.
Although useful in working with Java, you'll find that JavaScript can be quite useful in its own
right. It can work directly with HTML elements in a Web page, something Java can't handle. It is
also simple to use, and you can do quite a bit with just a few JavaScript statements. You'll see
examples of the power of JavaScript throughout this guide.
History of JavaScript
As mentioned before, the history of JavaScript begins with Java. Java was originally developed
by Sun Microsystems for use in "real-time embedded systems"-in other words, consumer
electronics. Java has now become the de facto standard for advanced Internet programming, but
you may still see it running your cellular phone someday.
Java was designed to operate on a virtual machine-a piece of software that interprets the Java
code and acts on it as if it were a computer in itself. The virtual machine was designed to be
simple so it could be implemented easily in a device. This is what makes it easy to implement in
Web browsers.
Java was originally supported only by HotJava, an experimental Web browser developed by Sun
for that purpose. Recognizing its potential, Netscape integrated it into its Web browser, Netscape
Navigator. Because Navigator is the most popular browser, this greatly increased the publicity for
Java.
In 1995, Java became the hottest new buzzword for the Internet, but few people actually knew
how to program it. Netscape Communications recognized the need for a simple, clear language
for Web pages and introduced LiveScript, the first of the Web scripting languages.
LiveScript had a syntax based on Java, but was more concise and easier to learn. It was also a
directly interpreted language rather than a compiled language like Java. Netscape built LiveScript
into the beta versions of Netscape Navigator. Support for LiveScript began with version 2.0b1,
released in June 1995.
Later in 1995, Netscape reached an agreement with Sun. Sun also recognized that a simple
scripting language was a good idea, so they officially endorsed LiveScript. Thus, the connection
with Java became official, and the name changed to the one you're familiar with: JavaScript.
At this writing, JavaScript is still being developed and continues to improve. Netscape's support
for JavaScript is expected to be finalized by the end of 1996, and other companies-most notably,
Microsoft-are rushing to release competing products. Microsoft Internet Explorer (MSIE) 3.0,
currently in beta, supports basic JavaScript, along with Microsoft's answer to JavaScript,
VBScript.
The <SCRIPT> tag, an extension of HTML supported by Netscape, enables you to include one or
more JavaScript functions in the page. Listing 1.1 is a very small JavaScript script embedded
directly within HTML. You take a more detailed look at the syntax of these tags later in this
chapter.
Listing 1.1. (SIMPLE.asp) A simple JavaScript program within an HTML document.
<HTML><HEAD> <TITLE>Simple JavaScript Example </TITLE> </HEAD> <BODY> HTML Text
goes here. <SCRIPT LANGUAGE="JavaScript"> document.write("Here is my output.")
</SCRIPT> </BODY></HTML>
An alternate option called an event handler enables you to specify a JavaScript action that will be
performed when an event occurs. For example, a button on the page might have an action
performed when it is pressed. This provides a more dynamic method of accessing JavaScript.
Instead of the <SCRIPT> tag, an event handler is added as an attribute to an HTML tag. As an
example, the following HTML code defines a link with an event handler: <A
HREF="www.netscape.com" onClick="alert('This will take you to Netscape's home page.');">
In this case, the name of the event is onClick. This particular event happens when the user clicks
on the link. The JavaScript code to perform when the link is clicked is enclosed within double
quotation marks.
Of course, when I say "browser" here, I'm talking about browsers that support JavaScript.
Netscape Navigator began supporting it in version 2.0b1, and at this writing, version 3.0b6 is the
latest version. It will also be supported by Microsoft Internet Explorer.
Note
At the time of this writing, Microsoft has released a beta version of its Web browser,
Microsoft Internet Explorer version 3.0, which includes support for JavaScript.
However, it is still under development and currently has trouble with some JavaScript
programs.
Although this is a wide range of support and should enable about 90 percent of the Web's
audience to use your script, but don't forget the other 10 percent. Whenever possible, be sure to
provide an alternative for non-JavaScript browsers.
Caution
Although JavaScript is supported on these platforms, full support is provided by a
beta version of Navigator at this writing. This means that it is still subject to bugs. See
Chapter 14, "Debugging JavaScript Programs," for further information.
Validating Forms
You've seen forms at many Web pages, and probably used them yourself. The user enters data
into the form, then presses the Submit button, and the server, using a CGI program, responds to
the information. This is useful, but it isn't very interactive-before you can receive a response, you
have to wait for the data to travel to the server and back.
Note
The biggest difference between JavaScript and CGI is that CGI works on the server
and JavaScript works on the user's own machine (the client). CGI is most useful for
sending data to the server and sending server data back to the user.
JavaScript can add instant gratification to a Web form. You still can't send the data to the server
until the Submit button is pressed, but JavaScript can act on the data in the meantime. For
example, you could fill out a loan application online and, as you fill it out, instantly get feedback
about the kind of payments the loan will require. After you're satisfied with the application, you
can then submit it to the server.
The process of developing a JavaScript application is simple. The following sections introduce the
tools you need to create and execute JavaScript scripts and describe the process of combining a
script with an HTML page. Finally, you'll learn about the hardware and software platforms that
currently support JavaScript.
Development Tools
Provided you have a version of Netscape to view your creations on, there are no tools that are
specifically required in order to develop a JavaScript script. All you need to create the scripts is a
text or HTML editor-probably the same one that you use to develop HTML pages.
Note
So far, none of the dedicated HTML editors have announced support for JavaScript;
however, you can still use them to create JavaScript programs. Several HTML editors
are included on the CD-ROM accompanying this guide.
Listing 1.2. (ALERT.asp) A script that displays a message in the text and in an alert box.
<HTML><HEAD> <TITLE>Another JavaScript Test </TITLE> </HEAD> <BODY> <SCRIPT
LANGUAGE="JavaScript"> document.write("Hello!"); window.alert("Hello again!"); </SCRIPT>
</BODY> </HTML>
This example displays the "Hello!" message as part of the HTML document. In addition, it uses
the alert() statement to display a message to the user in a dialog box.
What happens when you load this Web page in Netscape? Let's take a quick look at the inner
workings of JavaScript. Once you understand what happens and in what order, you'll find it easy
to learn the specifics-such as the JavaScript language itself.
When JavaScript is involved, the process is slightly different. After the full HTML document is
received, as in step 3 in the last section, it is examined for the <SCRIPT> tag. If a script is
included, it is processed; however, the processing depends on the type of script:
• If the script is included in the header, it is ignored unless a script later calls it.
• If the script is included directly in the body, its output will be included in the Web page-
thus, it can affect the display of the page.
• If the script is an event handler for a specific part of the page, it will be processed only
when the event happens.
All three of these are useful ways of implementing a JavaScript program; you choose one of
these methods depending on your needs. In a complicated JavaScript application, you will
probably use all three.
Security Considerations
As JavaScript has been developed, there have been several concerns about security-most of
them legitimate. The Computer Incident Advisory Committee (CIAC), an agency of the
Department of Energy that monitors computer security problems, has reported several minor
problems with JavaScript.
Because JavaScript is limited in its capabilities, there are no major problems-such as a method
for a wayward script to erase your hard drive. All the potential problems involve the owner of the
script or Web page being able to access information on your system. Here are the incidents the
CIAC has reported:
• A JavaScript script can read your URL history and report it to the remote site.
• The browser's disk cache can be read and transmitted.
• Your e-mail address can be read-and used to send an e-mail without your knowledge.
• A list of files on your hard disk can be obtained.
• URLs you visit can be logged by a script and transmitted.
All these problems are specific to Netscape's implementation of JavaScript. The good news is
that they have all been fixed by later versions of Netscape. The first two were fixed by version
2.0; the remaining ones are fixed by versions 2.01 and 2.02.
If you have the latest version of Netscape, you should be safe from these problems. However,
considering that this many problems have been discovered, there is always a chance there will be
more.
Remember that even though your source code is accessible, that doesn't mean it's free to be
copied. You legally have a copyright on any script you write.
If someone does copy your scripts, often the best solution is to send that person a friendly note
pointing out your copyright and saying that you do not want anyone else using it. You should also
clearly state this in the source code and on the Web page that contains it.
Note
If you've developed many HTML pages, you will recognize that HTML itself has this
same problem. Although there's usually no harm in copying an HTML technique from
a Web page-such as using <UL> for a list-some unscrupulous users have copied
entire Web pages and labeled them as their own. For this reason, it's always a good
idea to place a copyright notice on important Web pages-with or without JavaScript.
Missing Features
JavaScript is still being developed, so there are still a few missing features. These might be fixed
by a future version, but some may never be fixed. The following sections describe some of the
most important features that are missing from JavaScript.
Tip
Netscape has created a server-side version of JavaScript called Livewire.
Unfortunately, it works only with Netscape server software. You'll look at Livewire in
Chapter 20, "The Future of JavaScript."
cannot create graphics-for example, draw a graph. Currently, Java is the best solution when you
need to do this.
Limited Speed
The current implementation of JavaScript is a bit slow. Any complex calculation or manipulation of
HTML tends to run at a slow creep. I assume that Netscape is aware of this and will improve the
speed in future versions. Unfortunately, complex Java applets also run quite slowly, so there is no
clear solution at this time.
Don't let this scare you away from JavaScript-many of the most powerful things you can do with
JavaScript are simple and execute incredibly fast. It's only complex applications that suffer from
this limitation.
Tip
Remember that JavaScript can do many things Java can't do-including modifying
HTML during its display, validating forms, and handling user-generated events.
Common Gateway Interface (CGI) has been a standard almost as long as the Web has, and it
can be used to make Web pages interactive. You encounter CGI all over the Web-anywhere you
fill in a form and press a Submit button, you've accessed a CGI script.
CGI is not actually a language, but rather a standard interface. You can write CGI programs in
any language. The most commonly used languages for the task are Perl and C.
CGI is different from Java or JavaScript in that it executes entirely on the server. Your client
sends information to it in the request and then receives the results in the form of a Web page.
You cannot have instant results-such as a total that automatically updates as you change the
numbers entered. Combining JavaScript with CGI gives you the best of both worlds.
Like CGI, SSI is a standard, and you can use any language to program SSI. You can combine
SSI and JavaScript to make a truly dynamic page. You can even use SSI to change the
JavaScript code included in the page based on certain factors. You'll find examples of this in
Chapters 17 and 19.
Unfortunately, although most Web servers support SSI, not all systems (or system administrators)
allow their use. The main reason for this is that each Web page has to be parsed for SSI
instructions, which slows down the server. There are also security concerns. Ask your system
administrator whether you are allowed to use SSI.
1. Embed the script in the HTML page. You can use the <SCRIPT> tag to do this, or use an
event handler.
2. Test the script by viewing the document with Netscape.
Notice the strange syntax. The extra brackets and exclamation marks indicate a comment; the
entire script is marked as a comment so that older browsers will not attempt to display it.
JavaScript-aware browsers will execute it correctly.
If you use this method within the body of a Web page, the script will be executed immediately
when the page loads, and the output of the script will be included at that point in the page. You
can also use the <SCRIPT> tag within the header of a page to prevent it from executing
immediately. This can be useful for subroutines that you will call later.
Note
Because an event handler is inserted between double quotation marks, be sure to
use single quotation marks to delimit any strings within the event handler.
Note
Be sure you have the latest version of Netscape. Because JavaScript is still being
developed, there may be major differences in the results between versions of the
browser. All the examples in this guide are meant to use version 3.0 or later of
Netscape Navigator, although they may work with older versions.
Hiding JavaScript from Older Browsers
Of course, any JavaScript you write will be intended for JavaScript-compatible browsers;
however, the last thing you want is for someone using an ancient version of Mosaic to load your
page and see the actual JavaScript code all over their screen.
You can avoid this by enclosing JavaScript within HTML comments. This hides the code from
older browsers; JavaScript-aware browsers, such as Netscape, will interpret it as JavaScript.
Here's an example of a <SCRIPT> tag with HTML comments: <!-- <SCRIPT
language=JAVASCRIPT> document.write("I lost a buttonhole. "); </SCRIPT> -->
The key elements here are the comment begin and end tags: <!! and ->. These are standard
HTML 2.0, and define the start and end of a comment.
Unfortunately, things aren't always that simple. Here are a few things to watch out for:
• Some browsers will treat any greater-than sign (>) as the end of the comment. The
decrement operator (-) can also cause problems.
• Some browsers still won't recognize comments correctly, so your script may be
displayed.
Because of problems like these, there is no ideal solution. The best way to avoid these problems
is to use the <SCRIPT SRC> tag instead, although it isn't always the best solution. Another
solution is the <NOSCRIPT> tag, which indicates content that will be ignored by JavaScript
browsers. For example, this HTML will display only on non-JavaScript browsers: <NOSCRIPT>
You're using a non-JavaScript browser. Please use the <a href="nojs.asp">Non-JavaScript
version.</a> of this document. </NOSCRIPT>
For clarity, I won't use HTML comments in the examples through this guide. If you use these
techniques on a Web page of your own, you may wish to add comments to support older
browsers.
Workshop Wrap-Up
Although limited and still under development, JavaScript is a powerful tool to enhance a Web
page. It offers features that are available to no other Web language. You've learned the following
terms and concepts in this chapter:
Next Steps
Your next task is to learn more of the specifics of the JavaScript language:
Q: If JavaScript and Java are so different, why are they named similarly? Some
people even seem to use the words interchangeably.
A: It all comes down to marketing. Java was a publicity phenomenon at the time, and
simply including the word Java (or any other coffee-related word) in a product's name
was enough to get instant attention. Netscape got permission from Sun to do so, and
the rest was history. Unfortunately, this has caused many beginners-and many
columnists-to consider them identical, or at least much more similar than they really
are.
Q: Will learning JavaScript give me a head start in learning to program with Java?
A: Yes. Although the languages have significant differences, many of the basic
structures, functions, and concepts are the same. Be sure not to assume that things
will work exactly the same, though.
Q: I already know some Java. Will this make it easier to learn JavaScript?
A: Yes-many of the objects and properties in JavaScript are based on Java, and the
syntax is similar. However, don't make any assumptions that things will work exactly
the same as Java-they rarely do.
Q: Is there a way to hide my JavaScript code without forcing myself to jump
through hoops, avoiding greater-than and other essential symbols?
A: Not if the JavaScript program is embedded in an HTML file. If you keep your
JavaScript separate and use <SCRIPT SRC> to include it, you can avoid these
issues.
Q: Is there a way to hide JavaScript code from all browsers, so nobody can steal
my programs? Can <SCRIPT SRC> do this?
A: There's no way to hide JavaScript source code. Using <SCRIPT SRC> makes it a bit
more difficult to look at it, but anyone can still download your code and do so.
0
0
0
0
0
0
00
0
0
0
0
0
Chapter 2:
Working with Larger Programs and Variables
Without a way of storing data and using it repeatedly, a programming language isn't much better
than a pocket calculator. In this chapter, you explore the types of data you can use in JavaScript,
and how to define and use variables to store data. You'll also learn a bit about the structure of the
JavaScript language.
This script includes a single JavaScript statement. The document.write() command is actually part
of the document object, which you will learn about in detail later; however, you don't need to
understand objects to know that this statement simply prints the text, as if it were part of the
HTML.
A wide variety of statements are available to perform different types of tasks. A statement can
also assign a value to a variable, as you'll see later in this chapter.
Statements or functions that require a parameter, such as document.write() in the last example,
use parentheses to surround their parameters. If more than one parameter is required, they are
separated by commas. For example, this statement sends three numbers to a function called
total:
result = total(12,36,14.5);
Notice the semicolon at the end of the example statement. This is a common feature of many
languages, such as C and Java, to indicate the end of a statement. However, JavaScript isn't as
picky as those languages; you can leave out the semicolons if you desire. You may want to
include them for clarity, or to avoid developing a bad habit if you routinely program in C, Java, or
Perl.
The final punctuation marks you will need for JavaScript programs are the left and right braces:
{ and }. If you're familiar with C or Perl, you know that those languages use brackets to enclose
blocks of statements, and that all statements must be inside a set of brackets. Once again,
JavaScript isn't as strict as other languages. The only time braces are needed is when you are
defining a block of statements for a specific purpose, such as a function.
Note
JavaScript keywords, function and object names, and variable
names are case-sensitive. Be sure you use the correct
combination of upper- and lowercase when entering JavaScript
statements.
Next, let's take a look at the various components that can be included in a JavaScript program.
You will learn about these in detail in this chapter and in Chapters 3, "Working with Objects and
Events," and 4, "Using Built-In Objects and Custom Objects."
Statements
Statements are simply commands that perform a certain purpose. Several statements are built
into JavaScript; these are used to test variables, control the flow of the program, and perform
actions.
The term statement is also used to refer to any line of JavaScript code. For example, the
document.write() statement used in the examples is technically an object method, which you'll
explore in detail in Chapter 3.
Functions
A function accepts parameters and returns a value. You explore three built-in functions in the
section titled Converting and Evaluating Variables and Expressions later in this chapter:
To use a function, you simply include the function's name, followed by the parameters in
parentheses. For example, here is a simple script that uses the Add() function to print a result:
Variables
A variable is simply a name given to a value. Variables can be given different values throughout
the course of a JavaScript program. In the previous example, a variable called test is used to
store the result returned by the Add() function. You learn about variables in detail in the section
titled Data Types and Variables later in this chapter.
Expressions
An expression is something that JavaScript interprets before using it in a statement. For example,
this statement assigns a number to the variable total, using an expression:
The expression result1 + result2 is interpreted; in this case, the values are simply added together.
This value is then used as the value to assign to the total variable. Along with mathematical
expressions, expressions can include function results and conditional expressions (explained in
Chapter 3).
Using Comments
A final element you can include in a JavaScript program is a comment. These are items of text
that can be included for your information, or for others who might try to understand the script.
Comments are ignored by the JavaScript interpreter.
JavaScript supports two types of comments:
• A single-line comment begins with two slashes (//) and ends at the end of the line.
• A multiple-line comment begins with the /* delimiter and ends with the */ delimiter. This
type of comment can include any number of lines. These work like the comments in the C
language.
You can use whichever type of comment is the most convenient. The /* and */ comments are
useful for "commenting out" a block of JavaScript code to prevent it from executing temporarily.
Single-line comments are handy to provide descriptions of particular lines of code. The following
short JavaScript example includes both types of comments:
//function to return total number of cars function total(compact, subcompact,
luxury) { var temp = compact + subcompact + luxury; // we don't want to print
right now, so these are commented out. /*document.write("Compacts: ",compact,
" Subcompacts: ", subcompact); document.write("Luxury cars: ",luxury, "\n");
document.write("Total number of cars: ", temp);*/ //above lines are commented
out; nothing will be printed. return temp; }
As you can see, comments can help make your JavaScript code readable-and in some cases,
they can make it more confusing. It's generally a good idea to avoid making excessive comments,
but rather to label major sections of the program and statements that may be confusing.
Pay special attention to the comments in listings in this guide; they are used to make some
statements more clear, and occasionally to illustrate a point in the text.
Note
Do not confuse JavaScript comments with HTML comments.
You can use HTML comments to hide JavaScript commands
from non-JavaScript browsers, and they cannot be used within
the script. JavaScript comments are part of the script, and they
can be used only between the <SCRIPT> tags.
• Consider a JavaScript application to be a set of HTML files and scripts that work together
to form a useful purpose. A complete application might involve several JavaScript
programs in several different HTML files, and may even include additional functionality
through different languages, such as CGI or Java.
• As a literal or constant value, which is included directly in the JavaScript code. For
example, 54, 6.17, and "This" are all literal values.
• As a variable. As mentioned earlier in this chapter, variables are named containers that
can hold a value. You can assign them different values during the course of the program.
Variable names might include total, tax_amt, or data1.
JavaScript includes support for relatively few types of data, but you can use these to create other
types. In fact, using JavaScript's object-oriented features, you can create a wide variety of custom
types.
The four fundamental data types used in JavaScript are the following:
• Numbers, such as 3, 25, or 1.4142138. JavaScript supports both integers and floating-
point numbers.
• Boolean, or logical values. These can have one of two values: true or false.
• Strings, such as "This is a string". These consist of one or more characters of text.
• The null value, represented by the keyword null. This is the value of an undefined
variable.
Some programming languages, such as C and Java, are strongly typed. This means that
variables can hold a very specific type of value. You have to declare the type of data a variable
can hold when you define it, and you must use conversion functions when you wish to change a
variable's type. This works fine for in-depth, structured programming, but isn't really ideal for the
quick jobs for which JavaScript can be used.
By contrast, JavaScript is a loosely typed language. This means that when you declare a
variable, you don't have to define its type. You can store any allowable type of data in a variable.
Conversions between different types of data happen automatically.
Note
Another example of a loosely typed language is Perl, a popular
choice for CGI scripts and other Internet applications. Perl
variables, like JavaScript, can hold different types of data.
Because JavaScript is loosely typed, you don't need to give much thought to the type of data a
variable will hold. Nevertheless, there are special considerations for each type of data, which are
discussed in detail in the following sections.
Integers
An integer is simply a number that does not include a decimal. Integers in JavaScript can be only
positive numbers. You can use an integer as a literal in JavaScript simply by including the
number. For example, this statement prints the number 47:
document.write(47);
JavaScript considers any number without a leading zero to be a decimal (base 10) number. You
can also use data in hexadecimal (base 16) and octal (base 8). Here is a summary of the syntax
you use to specify different types of numbers with examples:
• Decimal: no leading zero (57, 5000)
• Hexadecimal: prefix with 0x (0x56, 0xFE)
• Octal: leading 0 (045, 013)
You can include integers in your programs in whichever base is convenient. For example, 42,
052, and 0x2A are all different ways of listing the decimal number 42. Because you probably think
best in base 10, decimal numbers are the easiest to use in most cases; however, there are some
situations when another format is more convenient. For example, the color codes used to specify
background and text colors in an HTML page are usually given in hexadecimal.
Note
Base 10 numbers can also use decimal fractions, as you will
learn later. Hexadecimal and octal numbers are limited to
integer values.
Floating-Point Numbers
You can also use floating-point decimal numbers in your JavaScript programs. These can be
used to represent just about any number conveniently. A simple floating-point value consists of
an integer followed by a decimal point and a fractional value, such as 2.01.
Unlike integers, floating-point values can be either positive or negative. You can specify negative
values for floating-point numbers by adding the negative sign to the beginning of the number, as
in -3.1. Any number without a negative sign is assumed to be positive.
You can also use a form of scientific notation to refer to floating-point numbers. This makes it
easy to specify very large numbers. To use this notation, you include the letter E (either upper- or
lowercase) followed by the exponent, either positive or negative.
Positive exponents move the decimal point to the right or make the number larger; negative
exponents make the number smaller. Here are a few examples of exponent notation and the
decimal numbers they represent:
Boolean Values
Boolean values are the simplest data type. They can contain one of two values: true or false.
Because they can represent an on/off or 1/0 state, these are sometimes called binary values.
Boolean values are most commonly used as flags; variables that indicate whether a condition is
true or not. For example, you might set a Boolean variable called complete to true to indicate that
the user has completed all the needed information in a form. You can then easily check this value
and act on it later.
Note
You can use the numbers 0 and 1 as synonyms for false and
true in many cases in JavaScript; however, it's best to treat
Boolean values as strictly Boolean.
Strings
Another important type of value you can work with in a JavaScript program is a string. Strings are
simply groups of characters, such as "Hello" or "I am a jelly doughnut.".
You can include strings as literals in JavaScript by enclosing them in double or single quotation
marks. Here are some examples of values that JavaScript will treat as strings:
• "This is a string."
• 'A'
• '25 pounds'
• "200"
You can use the two types of quotes interchangeably. However, you must use the same type of
quote to end the string that you used to begin it.
Tip
HTML uses double quotation marks to indicate values for some
tags. Because you will be using JavaScript within HTML
documents, and especially in event handlers, you may want to
get into the habit of using single quotation marks within
JavaScript statements. This will avoid conflicts with the HTML
codes.
Special Characters
Along with alphanumeric characters, you can use a variety of special characters in JavaScript
strings. These include carriage returns, tabs, and other nonprintable characters.
To use one of these special characters, include a backslash (\) followed by the code for that
character. The codes are as follows:
• \a: Alert (bell) character (produces a bell sound)
• \b: Backspace character (moves the cursor back one character)
• \f: Form-feed character (indicates a new page on a printer)
• \n: New line character (indicates a new line of text)
• \r: Carriage return character (moves the cursor to the beginning of the line)
• \t: Tab character (advances the cursor to the next tab stop)
You can include special characters directly in a string. For example, the following statement prints
out three separate lines of text:
document.write(" this is line 1\n this is line 2\n this is line 3");
Depending on what you're using the string for, some of these characters may or may not have a
meaning. For example, this line will only work in a predefined portion of the HTML page. Tab and
form-feed characters will not affect HTML output to the browser, but they may be useful for other
applications.
Another use for the backslash is to include quotation marks within a string. This is known as
escaping a character. For example, the following statement won't work, because it uses quotation
marks incorrectly:
document.write("Jane said, "Have you seen my wig around?"");
This is invalid because quotation marks can be used only at the beginning and end of the string.
You can escape the quotation marks within the string with the backslash character to make a
correct statement:
document.write("Jane said, \"Have you seen my wig around?\"");
The escaped quotation marks are considered as part of the literal string, so this will print the
correct result, including quotation marks. You can also use the backslash character twice to
include an actual backslash character in a string:
document.write("The DOS files are in the C:\\DOS\\FILES directory.");
Tip
Creating an Array
Many languages support arrays-numbered sets of variables. For example, scores for 20 different
students might be stored in a scores array. You could then refer to scores[1] for the first student's
score, scores[5] for the fifth student, and so on. This makes it easy to define a large number of
variables without having to give each one a name. The number in the brackets is called an index
into the array.
JavaScript does not support arrays as variables. Instead, they are handled as objects. You can
create an array by using the Array object. As an example, this statement creates an array called
scores with 20 values:
scores = new Array(20);
Once you define the array, you can access its elements by using brackets to indicate the index.
For example, you can assign values for the first and tenth scores with these statements:
scores[0] = 50; scores[9] = 85;
As you learn more about JavaScript objects, you'll learn that you can create much more
complicated structures than mere arrays. In the meantime, you can use arrays to store any
numbered set of values.
Tip
In the previous example, notice that the first student's score is
referred to as scores[0]. As in many other computer languages,
JavaScript array indices begin with 0. A five-element array
would have indices from 0 to 4.
As a result, total is now a string variable, and its value is "23 large polar bears". You should now
see how easy JavaScript is to work with-much easier than actual polar bears.
• Variable names can include letters of the alphabet, both upper- and lowercase. They can
also include the digits 0-9 and the underscore (_) character.
• Variable names cannot include spaces or any other punctuation character.
• The first character of the variable name must be either a letter or the underscore
character.
• Variable names are case-sensitive; totalnum, Totalnum, and TotalNum are separate
variable names.
• There is no official limit on the length of variable names, but they must fit within one line.
Using these rules, the following are examples of valid variable names:
total_number_of_students LastInvoiceNumber temp1 a _var39
Obviously, it's possible to use friendly, easy-to-read names or completely cryptic ones. Do
yourself a favor: use longer, friendly names whenever possible. One exception is temporary
variables that are used in a small section of code; one-letter names or single words work well for
these and save a bit of typing.
Although you can probably remember which type to use in your variables, don't count on the user
to remember. Because situations like this can happen, you'll need to be careful any time the user
enters a value.
• A variable declared within a function with the var keyword is local to that function; other
functions cannot access it. Variables used to store the function's parameters are also
local to the function.
• A variable declared outside a function, or without the var keyword in a function, is global;
all JavaScript statements in the current HTML or script file can access the value.
This means that if you define a variable called temp with the var keyword in a function, it can't be
accessed by other functions. In fact, another function can declare a local variable with the same
name, and it will have its own separate storage area. There will be no conflict between the two
temp variables.
By using the var keyword, you can make it clear that you are declaring a variable-either local
(within a function) or global (outside a function). The following example declares a variable called
keys and sets its initial value to 88:
var keys=88;
In many cases, local variables are convenient-such as for holding parameters passed to a
function or calculating a result to be displayed. You will want to declare global variables for values
that several functions within the HTML file will use.
A global variable's declaration must occur in the HTML file before any statements that use it. The
most common place to declare global variables is in the <HEAD> section of the HTML document.
This ensures that they'll come first, and also conveniently hides the JavaScript code from non-
JavaScript browsers.
Declaring Variables
To make it clear how to use variables and scope, let's look at a few examples. First of all, an
important thing to remember is that a variable is declared the first time you use it. Consider the
example in Listing 2.1.
This example includes quite a few variable declarations. (In fact, it does little else.) Let's take a
look at each one:
• teeth and arms are declared as global in the header with the var keyword.
• legs does not use the var keyword, but is still declared as global because the declaration
is outside any function.
• heads is declared as local by using the var keyword within the init function.
• eyes is declared without var, so it is global, although declared within the init function.
This should give you a good understanding of which variables will be local and global. Be sure to
use the correct syntax with your variables; incorrect syntax is one of the most common JavaScript
programming errors.
• Assignment operators are used to assign a value to a variable, or change its current
value.
• Arithmetic operators are used to perform addition, subtraction, and other math on
numeric literals or variables.
• String operators are used to manipulate string values.
• Logical operators deal with Boolean values, and are mainly used for testing conditions.
• Bitwise operators are used to manipulate individual bits of a numeric value in a Boolean
fashion.
• Comparison operators are used to test the relationship between two numeric values.
You'll learn about the various operators of each type provided by JavaScript in the next sections.
You will also explore operator precedence, the system used to determine which operation will be
performed first in a complex expression.
Assignment Operators
One assignment operator has already been used in this chapter: the equal sign (=). This is the
simplest assignment operator. It assigns the value (or expression) to the right of the equal sign to
the variable on the left. Here are some examples:
Arithmetic Operators
Arithmetic operators are used to perform mathematical operations on variables and literals.
You're already familiar with the basic arithmetic operators: addition (+), subtraction (-),
multiplication (*), and division (/). These work the way you would expect them to, and each has an
equivalent assignment operator. There are several other operators, explained in the next
sections.
This would be read as "b equals a modulo 2." Technically speaking, modulo is the remainder
when two numbers are divided. Thus, the example could be explained as "the remainder when
you divide x by 2." Here are a few literal examples:
String Operators
There is only one dedicated string operator in JavaScript: the concatenation operator (+). This
takes the string on the right and tacks it onto the string on the left. Here are three examples:
text = header + " and so forth."; sentence = subject + predicate; chars = chars +
"R";
In the first example, if the header string variable contained the text "This is a test", the value
assigned to text would be "This is a test and so forth." This makes it easy to combine strings.
The last example uses the same variable on both sides of the equal sign. Like arithmetic
operators, you can shorten this type of statement with the += operator. The following statement
does the same thing:
chars += "R";
There are actually several operations you can perform on strings, including extracting portions of
their values and comparing them. You'll look at those in detail in Chapter 4.
Caution
Because addition and concatenation use the same syntax, be
sure you know with which data type you are working. For
example, if you attempt to add numbers to a non-numeric
string, they will be concatenated instead-probably not what you
intended.
Logical Operators
Just as the arithmetic operators work on numeric values, logical operators work with Boolean
values. The following logical operators are available:
• ! (Not) returns the opposite of the variable it prefixes. This takes only one operand, similar
to the negation operator for numbers.
The main use for these logical operators is in conditional expressions. You'll learn more about
conditionals in Chapter 3.
Bitwise Operators
Bitwise operators are a category of operators that are used with binary numbers. Each of the
operands is converted into a binary number, then manipulated bit by bit. These are mostly useful
for manipulating values that have an individual meaning for each bit.
The following bitwise operators are available:
• And (&) returns one if both of the corresponding bits are one.
• Or (|) returns one if either of the corresponding bits is one.
• Xor (Exclusive Or) (^) returns one if either, but not both, of the corresponding bits is one.
• Left shift (<<) shifts the bits in the left operand a number of positions specified in the right
operand.
• Right shift (>>) shifts to the right, including the bit used to store the sign.
• Zero-fill right shift (>>>) fills to the right, filling in zeros on the left.
Note
You might think you'll have little use for binary options in
JavaScript-and you're right. One area in which they do come in
handy is working with color values.
Comparison Operators
Comparison operators are used to compare two numbers. They return a Boolean value (either
true or false) based on whether the operands match the condition. The simplest comparison
operator is the equality (==) operator; it returns true if the numbers are equal. For example, this
expression evaluates to true if a has a value of 17:
(a == 17)
Note
Be sure not to confuse the equality operator (==) with the
assignment operator (=). This is one of the most common
mistakes in JavaScript programming. You'll learn more about
this and other common mistakes in Chapter 14, "Debugging
JavaScript Programs."
You can also use the inequality operator (!=), which returns true if the numbers are not equal.
There are also several other comparison operators to examine the relationship between two
values:
• Less than (<)
• Greater than (>)
• Greater than or equal to (>=)
• Less than or equal to (<=)
The main use for conditional expressions is in conditional statements, such as the if statement.
You'll learn about those statements in detail in the next chapter.
a = b + x * 25;
As you can see, this statement could mean more than one thing. Should b be added to x before
multiplying by 25, or after? Will a be assigned to b or to the entire expression b + x * 25? A
programming language keeps a set of rules to explain situations like this. These rules are known
as operator precedence.
To explain JavaScript's operator precedence, here is a list of all the operators, with the lowest
precedence on top. Operators at the bottom of the list are evaluated first, so operators on the
bottom are considered more important:
• Comma (,), used to separate parameters
• Assignment operator (=)
• Conditional operators (?, :)
• Logical OR (||)
• Logical AND (&&)
• Bitwise OR (|)
• Bitwise XOR (^)
• Bitwise AND (&)
• Equality (==) and inequality (!=)
• Comparison operators (<, <=, >, >=)
• Bitwise shift (<<, >>, >>>)
• Addition and subtraction (+, -)
• Multiplication, division, and modulo (*, /, %)
• Negation (!, ~, -), increment (++), and decrement (--)
• Function call or array index ((), [])
Using Variables in Expressions
To explain operators and precedence further, let's look at a few examples using variables and
values. First, here's a simple expression:
a = b * 5;
There is no confusion about what this statement does; it multiplies b by 5, and stores the result in
a. Now look at this:
a = b * 5 + 1;
This is where operator precedence comes into play. Because multiplication has a higher
precedence than addition, b is multiplied by 5 before adding 1.
a = b * (5 + 1);
In this case, operator precedence is overridden by the use of parentheses, which have a very
high precedence. The numbers 5 and 1 are now added, then b is multiplied by the result (6). One
more example:
a = (b * 5) + 1;
This works exactly like the first example: b is multiplied by 5, then added to 1. In this particular
case, the parentheses don't do anything. I've included this example to make a point: when in
doubt, use parentheses. You won't get an error by using unnecessary parentheses, so you can
use them whenever you're unsure about precedence, or simply to make your code more
readable.
Converting and Evaluating Variables and Expressions
As discussed earlier, JavaScript is a loosely typed language. You don't need to declare a
variable's type when you define it, and you don't need to do anything special to store a different
type of data in a variable.
Even in a loosely typed language, there are some cases when you want to convert data to a
specific type. You can use several built-in functions of JavaScript, described in the next sections,
to handle these conversions.
parseInt() returns a special value, "NaN", (Not a Number) if it encounters a non-numeric character
at the beginning of the string. On Windows platforms, zero may be returned instead. See Chapter
14 for specifics about this and other platform-specific issues.
Caution
Because eval() will execute any statement in the string, be very
careful when using it with user-entered strings. A clever user
could enter JavaScript statements in the string and cause
problems with your program.
Workshop Wrap-Up
In this chapter, you learned more about the JavaScript language and the basic foundations of
JavaScript's structure. You also learned the following concepts:
• The components that make up a JavaScript program or application
• The way JavaScript handles various data types, whether included as a literal value or
stored in a variable
• The basics of JavaScript objects and properties
• The techniques for declaring variables, storing data in them, and using them in
expressions
Next Steps
To continue your exploration of the JavaScript language, continue with one of the following
chapters:
Q&A
Q: Can I use more than one JavaScript program in the same HTML page?
A: Yes. Just enclose each program within its own set of <SCRIPT> tags. Note that
variables you define in one program will be available to others in the same file.
Q: What is the importance of the var keyword? Should I always use it to declare
variables?
A: You only need to use var to define a local variable in a function. Outside a function,
things work the same whether you use var or not.
Q: In Perl, using the eval statement on data entered by the user can be a serious
security risk. Is this also true with JavaScript?
A: Yes and no. Although the user could enter statements and make your program behave
strangely, there would be no way to do real damage, because JavaScript has no access
to the server. The worst they could do is crash Netscape on their own machine.
Chapter 3
Working with Objects and Events
This chapter continues the discussion of JavaScript programming with some of the more
advanced aspects of the language. You will learn some of the tools you can use to create
complete, complex JavaScript applications-objects, functions and methods, forms, loops and
conditionals, and event handlers.
Tip
You'll learn more about the String object, including its methods,
in the Built-In Objects section of Chapter 4 "Using Built-In
Objects and Custom Objects."
The String object has a single property called length. As you might have guessed, the length
property indicates the current length of the string. You can use two different types of notation to
refer to an object's property. The first and most common method is to separate the object name
and property name with a period. For example, the following statement sets the variable len to the
length of the address string variable:
len = address.length;
The second method is the one you use to refer to array elements, which are actually properties of
an array object. This uses brackets around the property name. This example sets the len variable
to the length of the address string, just as the previous example does:
len = address["length"];
Because this method can be used effectively to create an array with names instead of numbers
for indices, it is also referred to as an associative array. This is an array with named values, which
makes it very easy to deal with things such as database entries.
You can use either the bracket or period syntax interchangeably in most cases. The exception is
when you are using a variable to hold the name of a property. For example, the following
statements refer in a roundabout way to a string's length property:
x = "length"; len = address[x];
In this case, you have to use brackets for the property name. If you simply used address.x, the
interpreter would look for a property called x, resulting in an error.
Note
You may be familiar with associative arrays if you have done
any programming in Perl. The named properties in a
JavaScript object provide a similar capability. Chapter 10,
"Working with Multiple Pages and Data," includes an example
Declaring a Function
Recall that a function is a set of JavaScript statements that accept one or more parameters and
return a value. Even without using objects, you can use a function in JavaScript to perform a
specific task. Chapter 2 "Working with Larger Programs and Variables," defined a function to add
two numbers. This was a simple function, and a useless one-the addition operator does the same
thing.
Let's try a more complex (and more useful) function. One handy use for functions is to avoid
repetitive use of complex HTML codes to output information. For example, consider the <TABLE>
tag in HTML 3.0. This example shows the HTML code to define a table of names, ages, and
birthdays for several people:
<TABLE> <TR> <TD>Fred</TD> <TD>27</TD> <TD>June 17</TD> </TR>
<TR> <TD>Tom</TD> <TD>24</TD> <TD>March 13</TD> </TR> <TR>
<TD>Rebecca</TD> <TD>25</TD> <TD>November 30</TD> </TR> </TABLE>
The <TABLE> tag is required to start and end the table, the <TR> tag starts and ends table rows,
and the <TD> tag starts and ends each cell within the row. As you can see, this can make for
some complicated HTML.
If your JavaScript program is producing this information as output, it becomes that much more
difficult, because you have to print each of the tags carefully in the right order. Listing 3.1 shows a
JavaScript program to print the table shown previously.
Listing 3.1. A JavaScript program to print the table.
document.write("<TABLE>\n"); document.write("<TR> <TD>Fred</TD>
<TD>27</TD> <TD>June 17</TD> </TR>\n"); document.write("<TR>
<TD>Tom</TD> <TD>24</TD> <TD>March 13</TD> </TR>\n");
document.write("<TR> <TD>Rebecca</TD> <TD>25</TD> <TD>November
30</TD> </ÂTR>\n"); document.write("</TABLE>");
As you can see, this isn't exactly the most readable JavaScript program. A much better method is
to use a function to perform the repetitive task-in this case, printing the <TR> and <TD> tags in
the right order with each row of data. Listing 3.2 shows the definition for a PrintRow() function to
perform this task:
Listing 3.2. The PrintRow function, for printing a table row.
function PrintRow(name, age, birthday) { document.write("<TR> <TD>", name,
"</TD> <TD>", age, "</TD> <TD>", birthday, "</TD> </TR>\n"); }
The first line of the function definition includes the function keyword, which is required to begin a
function definition. The function name, PrintRow, is then given. The parameters the function will
expect are in the parentheses; these are also the names of variables, local to the function, which
will be defined to store the parameters passed.
The statements that comprise the function begin with the left brace. In the second line, the
document.write function is used to output the parameters, with the proper HTML table tags
between them. Because this is the final statement in the function, it ends with a right brace.
Tip
Not all functions have parameters. You can define a function
that doesn't require any parameters by using an empty
parameter list: ().
Calling a Function
You now have a function that can be used to print a row of the table. In order to use it, you need
to call the function. A function call is simply the name of the function and the parameters to send
it.
Using function calls to the PrintRow() function defined in Listing 3.2, you can easily create the
table of names, ages, and birthdays without unnecessary repetition:
Returning a Value
The function used previously accepted parameters, but did not return a value. A function can
send a value back to the calling statement with the return keyword. This can be useful for a
function that calculates a result; it can also be used to indicate success or failure.
The value returned by a function can be of any type-a number, a string, or even an object. As a
simple example of returning values, let's define a function that returns a string. Once again HTML
is used as an example. The function in Listing 3.3 provides a quick way to add boldface on/off
(<B> and </B>) HTML tags to a piece of text.
This function accepts a string as a parameter and stores it in the text variable. It then creates
another variable called temp and concatenates the required tags to text. The temp variable is
then returned.
Note
This function provides a good demonstration of the loosely
typed nature of JavaScript. The function would actually accept
any type of variable as a parameter; the only thing that implies
that a string is required is the concatenation operator used in
the second line.
The function call is slightly different for a function that returns a value, because you need to do
something with the returned value. For example, you could store it in a variable:
boldtext = Bold("This is a test.");
Because JavaScript considers a function call to be an expression, you can also use it anywhere
that type of data (in this case, a string) is expected. For example, you could print it directly:
document.write(Bold("This is a test."));
In this case, the Bold() function is called to produce a result, and the resulting string is used as
the parameter of the document.write() function. JavaScript always evaluates expressions like this
starting at the innermost level of parentheses.
One final note: You don't actually have to use the value a function returns unless you want to. For
example, you have already looked at the eval() built-in function, which executes JavaScript
commands from a string. The eval() function returns the result of the commands, but if you don't
need to use the result, you can ignore it by simply using a normal function call:
eval("temp = 12");
Note
Another method of hiding JavaScript from older browsers is discussed in
Chapter 1 "Creating Simple JavaScript Programs."
Another reason to include function definitions in the header is that it is the first part of the HTML
document loaded by the browser. This will ensure that when you make the function call, the
function is loaded and ready to execute. You cannot call a function that hasn't been defined yet.
The function call, on the other hand, should be included in the <BODY> of the HTML document
so that it can display its results. As an example, Listing 3.4 shows an HTML document that
includes the PrintRow function, defined in Listing 3.2, and uses calls to the function in the body to
display a table.
Listing 3.4. (TABLE.asp) An HTML document that uses JavaScript to print a
table.
<HTML> <HEAD> <TITLE>JavaScript table test</TITLE> <SCRIPT
language="JAVASCRIPT"> function PrintRow(name, age, birthday)
{ document.write("<TR> <TD>", name, "</TD> <TD>", age, "</TD> <TD>",
birthday, "</TD> </TR>\n"); } </SCRIPT> </HEAD> <BODY> <H1>Table Test
Using JavaScript</H1> <TABLE> <SCRIPT language="JAVASCRIPT">
PrintRow("Fred", 27, "June 17"); PrintRow("Tom", 24, "March 13");
PrintRow("Rebecca", 25, "November 30"); </SCRIPT> </TABLE> End of table.
</HTML>
As you can see, the PrintRow function is defined in the <HEAD> section of the document and
called where it is needed, in the <TABLE> tags in the document's body. You can see the output
of this document, as displayed by Netscape, in Figure 3.1.
Figure 3.1 : Netscape displays the output of the JavaScript table example.
Tip
You may not even need a <SCRIPT> tag to call your function.
Functions can also be used by event handlers to respond to
events. You will explore event handlers in detail in the Event
Handlers section, later in this chapter.
When you are writing JavaScript, you may not know exactly what should be a function and what
shouldn't. Here are some tips for determining whether you should use a function:
• If you find yourself typing the same (or nearly the same) set of commands repeatedly.
• If you expect to use the same commands again for a different purpose, define a function.
It will make your job easier when you need to do it again.
• Even if you won't use a section of code again, you might want to consider using functions
to separate the individual tasks within the program.
• If you need to complete a set of statements in a single line-such as in an event handler,
described later in this chapter-you'll need to use a function.
In general, any time you end up with more than five to six lines of code, you may want to split
parts of it into functions. This makes the main body of code easier to read. As a matter of fact,
many programmers use functions almost exclusively, making the main program itself small and
very easy to understand.
As you create a large JavaScript program with several functions, you may wonder how the
functions will work together. There are two ways to keep track of data between functions.
The first method of passing data to and from a function is the one you've already used-function
parameters. You can pass a set of parameters to the function, and the function can return a
value.
Although this parameter-passing mechanism works well in most cases, you will run into some
situations where it just isn't practical. One reason for this is that functions can return only one
value. In cases like this, the answer is to use a variable.
As you learned in Chapter 2 variables you declare in a function with the var keyword are local to
that function; they can't be accessed from any other function. In order to keep data between
functions, you need to use a global variable.
Defining a global variable is easy: just place the variable definition outside any functions. Once
you've defined it, you can then use it in all functions in your program. You can also use global
variables in statements outside of functions and in event handlers.
This technique is particularly useful for quantities that concern the whole program. For example,
in a game program you might use a global variable for the score. This would enable you to add to
the score from any function, without having to pass it back and forth.
Understanding Methods
Now that you understand functions, let's look at how they work with objects. You use a function to
define an object, and you can also define methods, or built-in ways of working with the objects.
Methods are simply functions that have been linked to an object and work on the properties of
that object. As an example, the built-in string object includes some methods to work with strings.
One of them, toLowerCase(), converts the string to all lowercase.
To call a method, you use a period to divide the string name and the method name, as with
properties. However, because a method is a function, you must include parentheses for the
parameters. In the case of the toLowerCase() method, there are no parameters. The following
JavaScript code demonstrates the use of this method:
var text = "THIS IS UPPERCASE"; var ltext = text.toLowerCase();
In this example, the ltext variable is used to hold the lowercase version of the text string. The
toLowerCase() method does not modify the string itself; instead, it returns a lowercase version.
To further illustrate methods and objects, let's return to the business card example. As you may
recall, the Card object you worked with earlier has the following properties:
• name
• address
• work_phone
• home_phone
To define and use this object in a JavaScript program, you need to create a function to create
new Card objects. This function is referred to as the object definition for an object, or the
constructor. Here is an object definition for the Card object:
function Card(name,address,work,home) { this.name = name; this.address =
address; this.work_phone = work; this.home_phone = home; }
The object definition is a simple function that accepts parameters to initialize a new object and
assigns those to the corresponding properties. One thing you haven't seen before is the this
keyword; this is required for object definitions and refers to the current object-the one that is being
created by the function.
Next, let's create a method to work with the Card object. Because all Card objects will have the
same properties, it might be handy to have a function that prints the properties out in a neat
format. Let's call this function PrintCard().
Because your PrintCard() function will be used as a method for Card objects, you don't need to
ask for parameters. Instead, you can use the this keyword again to refer to the current object's
properties. Here is a function definition for the PrintCard() function:
function PrintCard() { document.write("Name: ", this.name, "\n");
document.write("Address: ", this.address, "\n"); document.write("Work Phone: ",
this.work_phone, "\n"); document.write("Home Phone: ", this.home_phone,
"\n"); }
This function simply reads the properties from the current object (this), prints each one with a
caption, and skips to a new line. The last thing you need to do is make PrintCard() part of the
function definition for Card objects. Here is the modified function definition:
function Card(name,address,work,home) { this.name = name; this.address =
address; this.work_phone = work; this.home_phone = home; this.PrintCard =
PrintCard;
}
The added statement looks just like another property definition, but it refers to the PrintCard()
function. This will work so long as the PrintCard() function is defined with its own function
definition.
Notice that I have modified the PrintCard() function slightly to make things look good with HTML
line breaks, boldface, and horizontal rules. The Netscape output of this document is shown in
Figure 3.2.
Figure 3.2 : Netscape displays the output of the business card example.
Conditionals and Loops
Next, let's look at two types of statements you'll need in just about any large program:
conditionals, which enable you to test data, and loops, which execute a block of code multiple
times.
This statement checks the variable a, and if it has a value of 1, prints a message. Otherwise, it
does nothing. You can also use multiple statements by enclosing them in braces:
if (a == 1) { document.write("Found a 1!"); a = 0; }
This block of statements checks the variable a once again. If it finds a value of 1, it prints a
message and sets a back to zero.
The if statement has an optional else keyword, which can specify a block of statements to
execute if the condition is not true. You could modify Listing 3.5 to print an alternative message if
the value of a is not 1:
if (a == 1) { document.write("Found a 1!"); a = 0; } else
{ document.write("Incorrect value: " + a); a = 0; }
As you can see, you can follow the block of statements after the if keyword with an else keyword
and a second block of statements. Only one of the blocks will be executed, depending on the
condition.
You can use any of the conditional expressions and operators introduced in Chapter 2as the
conditional in the if statement. You can also use a nonconditional expression, such as a variable
assignment; the condition will be true if the assignment is successful.
Note
One of the most common errors is to use the assignment (=)
operator in a conditional instead of the equality (==) operator.
This can be especially confusing because the assignment will
evaluate as a true condition. Be sure to check your conditions
for this.
Conditional Expressions
In addition to the if statement, JavaScript provides a shorthand type of conditional expression that
you can use to make quick decisions. This uses a peculiar syntax, which is also found in other
languages, such as C. Here is an example of a conditional expression:
value = (a == 1) ? 1: 0;
This statement may look confusing, but it is equivalent to this if statement:
if (a == 1) value = 1; else value = 0;
In other words, the value after the question mark (?) will be used if the condition is true, and the
value after the colon (:) will be used if the condition is false. The colon represents the else portion
of the statement, and like the else portion of the if statement, is optional.
These shorthand expressions can be used anywhere JavaScript is expecting a value. They
provide an easy way to make simple decisions about values. As an example, here's an easy way
to display a grammatically correct message about the counter variable:
document.write("Found ", counter, (counter == 1) ? " word.": " words.");
This will print the message "Found 1 word" if the counter has a value of 1, and "Found 2 words"
with a value of 2 or greater. This is one of the most common uses for a conditional expression.
One of the main reasons for computer programs is to perform repetitive tasks. JavaScript
includes several keywords that make it easy to repeat blocks of code in a loop. There are several
different types of loops, each with its own keyword.
The for keyword is the first tool to look at for creating loops. A for loop typically uses a variable
(called a counter or index) to keep track of how many times the loop has executed, and it stops
when the counter reaches a certain number. A basic for statement looks like this:
for (var = 1; var < 10; var++) {
There are three parameters to the for loop, separated by semicolons:
• The first parameter (var = 1 in the example) specifies a variable and assigns an initial
value to it. This is called the initial expression, because it sets up the initial state for the
loop.
• The second parameter (var < 10 in the example) is a condition that must remain true to
keep the loop running. This is called the condition of the loop.
• The third parameter (var++ in the example) is a statement that executes with each
iteration of the loop. This is called the increment expression, because it is usually used to
increment the counter.
After the three parameters are specified, a left brace is used to signal the beginning of a block. All
the statements between the braces will be executed with each iteration of the loop.
This may sound a bit confusing, but once you're used to it, you'll use for loops frequently. Let's
take a look at a simple example of this type of loop, shown in Listing 3.6.
This example displays a message including the loop's counter during each iteration. The output of
Listing 3.6 would look like this:
This is line 1 This is line 2 This is line 3 This is line 4 This is line 5 This is line 6
This is line 7 This is line 8 This is line 9
Notice that the loop was executed only nine times. This is because i<10 is the conditional. When
the counter (i) is incremented to 10, the expression is no longer true. If you need the loop to count
to 10, you could change the conditional; either i<=10 or i<11 will work fine.
Note
You might notice that the variable name i is often used as the
counter in loops. This is a programming tradition that began
with an ancient language called Fortran. There's no need for
you to follow this tradition, but it is a good idea to use one
consistent variable for counters.
The structure of the for loop in JavaScript is based on Java, which in turn is based on C. Although
it is traditionally used to count from one number to another, you can use just about any statement
for the initialization, condition, and increment. However, there's usually a better way to do other
types of loops with the while keyword, described in the next section.
The other keyword for loops in JavaScript is while. Unlike for loops, while loops don't necessarily
use a variable to count. Instead, they execute as long as (while) a condition is true. In fact, if the
condition starts out as false, the statements might not execute at all.
The while statement includes the condition in parentheses, and it is followed by a block of
statements within braces, just like a for loop. As an example, here is a simple while loop:
while (total < 10) { n++; total += values[n]; }
This loop uses a counter, n, to iterate through the values array. Rather than stopping at a certain
count, however, it stops when the total of the values reaches 10.
You might have noticed that you could have done the same thing with a for loop:
for (n=0;total < 10; n++) { total += values[n];
}
As a matter of fact, the for loop is nothing more than a special kind of while loop that handles an
initialization and an increment for you. You can generally use while for any loop; however, it's
best to choose whichever type of loop makes the most sense for the job, or takes the least
amount of typing.
There's a third type of loop available in JavaScript. The for...in loop is not as flexible as ordinary
for or while loops; instead, it is specifically designed to perform an operation on each property of
an object.
For example, remember that the elements of an array are actually properties of an array object.
You can use a for...in loop to access each element of the array in turn. This simple loop adds one
to each of the members of the counters array:
for (i in counters) { counters[i]++;
}
Like an ordinary for loop, this type of loop uses an index variable. (i in the example). For each
iteration of the loop, the variable is set to the next property of the object. This makes it easy when
you need to check or modify each of an object's properties.
Remember that this doesn't just work with arrays-the previous example would work with an array
with indices 1 through 5, but it would also work if the object had properties such as hits and
misses. The index variable would be set to each of the property names.
Infinite Loops
The for and while loops allow you quite a bit of control over the loop. In some cases, this can
cause problems if you're not careful. Take this loop, for example:
while (j < 10) { n++; values[n] = 0; }
I've made a mistake in the previous example. The condition of the while loop refers to the j
variable, but that variable doesn't actually change during the loop. This creates an infinite loop.
The loop will continue executing until it is stopped by the user, or until it generates an error of
some kind.
Obviously, infinite loops are something to avoid. They can also be difficult to spot, because
JavaScript won't give you an error that actually tells you there is an infinite loop. Thus, each time
you create a loop in your JavaScript programs, you should be careful to make sure there's a way
out.
Occasionally, you may want to create an infinite loop deliberately. This might include situations
when you want your program to execute until the user stops it or if you are providing an escape
route with the break statement, introduced below. Here's an easy way to create an infinite loop:
while (true) {
Because the value true is the conditional, this loop will always find its condition to be true.
One more statement is available to help you control the execution of statements in a loop. The
continue statement skips the rest of the loop, but unlike break, it continues with the next iteration
of the loop:
for (i=1; i<21; i++) { if (score[i]==0) continue; document.write("Student number ",i,
" Score: ", score[i], "\n"); }
This program uses a for loop to print out scores for 20 students, stored in the score array. The if
statement is used to check for 0 scores. You assume that a score of 0 means that the student
didn't take the test, so you continue the loop without printing the score.
You use a for loop to read all the arguments. The arguments.length property gives us the total
number of arguments. Each is added to the local tot variable, which is returned.
The final concept you will look at in this chapter is one of the strengths of JavaScript: event
handlers. These enable you to integrate JavaScript with a Web page in ways possible with no
other language.
In an object-oriented environment, events are often used to trigger portions of a program. In
JavaScript, events pertain to the Web page containing the script. When the user clicks on a link,
selects or enters text, or even moves the mouse over part of the page, an event occurs.
You can use JavaScript to respond to these events. For example, you can have custom
messages displayed in the status line (or somewhere else on the page) as the user moves the
mouse over links. You can also update fields in a form whenever another field changes.
Note
Because one of the main uses for event handlers is in HTML
forms, you will explore them in much more detail in Chapter 6
"Using Interactive Forms."
Types of Events
You will explore the different events available for use in JavaScript, and the objects they
correspond with, in Chapter 5 "Accessing Window Elements as Objects." For now, take a quick
look at Table 3.1, which lists the types of events and their use.
As you can see, you can respond to a wide variety of events. This makes it possible to interact
with the user instantaneously-something CGI programmers have wanted for years.
Note
The previous example uses single quotation marks to surround
the text. This is necessary in an event handler, because double
quotation marks are used by HTML. The event handler itself is
surrounded by double quotes.
You can use JavaScript statements like the previous one in an event handler, but if you need
more than one statement, it's a good idea to use a function instead. Just define the function in the
<HEAD> of the document, then call the function as the event handler:
<a href="#bottom" onMouseOver="DoIt();">Move to the bottom</A>
This example calls the DoIt() function when the user moves the mouse over the link. Using a
function is convenient because you can use longer, more readable JavaScript routines as event
handlers.
As a final note about event handlers, you need to know a bit of programming philosophy. If you've
programmed in a language such as BASIC, C, or Perl, you're used to creating a program that
executes in a logical order, and you control that order.
With graphical environments, such as Windows and the Macintosh, came the need for event-
based programming. This type of programming uses events to trigger sections of the program, so
you don't really know what order it will execute in-that depends on what the user does.
On the other hand, event-based programming can make things much easier. In traditional
programming, you typically interact with the user with a series of if statements, checking for each
thing the user might have done. In event-based programming, this part is done for you-all you
have to do is write the functions for each event you wish to handle.
If you've programmed in other environments, the event-based nature of JavaScript might take a
bit of getting used to, but it's worth it-it makes programming simple. If JavaScript is the first
language you're learning, you'll find it easy to learn to use events. Event handlers are used in
several useful ways in Chapter 5and throughout this guide.
Workshop Wrap-Up
In this chapter, you learned many of the more advanced aspects of JavaScript, including the
following:
Next Steps
Next, you can learn more about objects in JavaScript, or move on to creating more complex
programs:
• To learn more about the built-in objects and functions in JavaScript, along with custom
objects of your own, see Chapter 4, "Using Built-In Objects and Custom Objects."
• To learn about the specific events you can use with each of the objects in an HTML page,
see Chapter 5 "Accessing Window Elements as Objects."
• To see how you can use objects with HTML forms, see Chapter 6, "Using Interactive
Forms."
• To see some applications of the techniques in this chapter, see Chapter 7 "Real-Life
Examples I."
Q&A
Q: There are many guides that go into more complicated detail about object-oriented
programming. Do these apply to JavaScript?
A: Only partially. JavaScript uses a basic implementation of objects, and does not fully
support features, such as encapsulation and inheritance, which are considered traits of
"true" objects. JavaScript's objects are simple, and you should learn all you need to know
about them in this guide.
Q: Some languages, such as C, have a switch or case statement, which enables me
to test several conditions conveniently. Does JavaScript have anything like this?
A: Not exactly. You can use a sequence of if and else if statements to do the same thing,
though.
Q: If I use the onSelect method, how can I tell what part of the text was selected?
A: Unfortunately, you can't. This may be resolved in a future version of JavaScript. Even
then, writing a complete text editor in JavaScript may be a bit ambitious.
Chapter 4
Using Built-In Objects and Custom Objects
You learned about the basic principles of object-oriented JavaScript programming in Chapter 3
"Working with Objects and Events." This chapter goes into detail about the techniques used in
object-oriented programming. You will also explore the built-in objects you can use to make
JavaScript programming easier, and learn about these objects using several example programs.
This function simply defines the name of the object type and assigns values to each of its
functions. It also assigns the name of a function (PrintCard) as a method of the Card object.
You can use any variable as a property of an object-in fact, you can use another object as a
property. For example, suppose you defined an Address object to hold the different components
of an address:
This is the syntax you will use any time an object is used as a property of another object. You will
see in Chapter 5 "Accessing Window Elements as Objects," that the built-in objects used to
represent parts of the browser's display and the Web page use this technique frequently.
This function uses the variable i to iterate through the object's properties and uses the
document.write() function to display the property name and the value.
Note
Notice that I used the syntax object[i] to refer to the property of
the object in the previous example. It may seem more obvious
to use object.i to refer to the property, but this won't work-
JavaScript will interpret this as asking for a property called i. In
order to use the value of i, you need to use brackets.
Note
When you define an array, its elements are filled with null, or
undefined values, up to the length you specify. You can
dynamically change an array's size by assigning to the length
property.
• join() quickly joins all the array's elements, resulting in a string. The elements are
separated by commas or by the separator you specify.
• reverse() returns a reversed version of the array: the last element becomes the first, and
the first element becomes the last.
• sort() returns a sorted version of the array. Normally, this is an alphabetical sort;
however, you can use a custom sort method by specifying a comparison routine.
You will see examples of these methods throughout this guide; for example, in Chapter 15, "Real-
Life Examples III," the sort() method is used to score poker hands. You will also look at a simple
example in the next section.
Creating an Array
Before continuing, let's explore an example of using an Array object with some of the array
methods. Look at the JavaScript program shown in Listing 4.2.
Listing 4.2. Use of the Array object and its methods.
// Room for 3 items (0-2) groceries = new Array(3); groceries[0]="dental floss";
groceries[1]="baby powder"; groceries[2]="clam chowder";
document.writeln(groceries.join()); document.writeln(groceries.reverse().join());
document.writeln(groceries.sort().join());
This defines an array called groceries, able to hold 3 items. Next, you assign values to three of
the items. You can then observe the Array object methods in action with three document.writeln
statements:
Note
You don't have to create a string variable to use the String
object methods; you can use them on any object with a string
value. This includes the text-valued properties of any of the
objects in the Web page object hierarchy.
String Conversions
Two methods of the String object enable you to convert the contents of the string easily to all
uppercase or all lowercase:
• Indexing starts with 0 for the first character of the string, so the fourth character is actually
index 3.
• The second index is noninclusive. A second index of 6 includes up to index 5 (the sixth
character).
• You can specify the two indexes in either order; the smaller one will be assumed to be
the first index. In the previous example, (6,3) would have produced the same result.
As another example, suppose you defined a string called alpha to hold the alphabet:
alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
The following are examples of the substring() method using this string:
• alpha.substring(0,4) returns "ABC".
• alpha.substring(10,12) returns "KL".
• alpha.substring(12,10) also returns "KL". Because it's smaller, 10 is used as the first
index.
• alpha.substring(6,7) returns "G".
• alpha.substring(24,26) returns "YZ".
• alpha.substring(0,26) returns the entire alphabet.
• alpha.substring(6,6) returns the null value, an empty string. This is true whenever the two
index values are the same.
The second method for working with substrings is the charAt() method. This method is simpler: it
takes a single index, and returns a single character. Here are a few examples using the alpha
string defined previously:
Searching a String
The indexOf() method searches for a string within another string. Use the string you wish to
search for the method call and specify the string to be searched for in the parentheses. This
example searches for "text" in the temp String object:
location = temp.indexOf("text");
The value returned to the location variable is an index into the string, similar to the first index in
the substring() method. The first character of the string is index zero.
You can specify an optional second parameter to indicate the index value to begin the search.
For example, this statement searches for the word "fish" in the temp string, starting with the 20th
character:
location = temp.indexOf("fish",19);
Tip
One use for the second parameter is to search for multiple
occurrences of a string. After finding the first occurrence, you
search starting with that location for the second one, and so
on.
A second method, lastIndexOf(), works the same way, but finds the last occurrence of the string.
It searches the string backwards, starting with the last character. For example, this statement
finds the last occurrence of "Fred" in the names string:
location = names.lastIndexOf("Fred");
As with indexOf(), you can specify a location to search from as the second parameter. In this
case, the string will be searched backward starting at that location.
• String.big() displays big text, using the <BIG> tag in HTML 3.0.
• String.blink() displays blinking text, using the <BLINK> tag in Netscape.
• String.bold() displays bold text, using the <B> tag.
• String.fixed() displays fixed-font text, using the <TT> tag.
• String.fontcolor() displays the string in a colored font, equivalent to the <FONTCOLOR>
tag in Netscape.
• String.fontsize() changes the font size, using the <FONTSIZE> tag in Netscape.
Tip
There are also two JavaScript functions, escape() and
unescape(), which convert strings to URL encoding and back.
These are explained in Chapter 17, "Combining JavaScript,
CGI, and SSI."
and this statement sets a link on the words "Click Here" to the anchor defined previously:
"Click Here".link("#test");
The Date object is a built-in JavaScript object that enables you to conveniently work with dates
and times. You can create a Date object any time you need to store a date, and use the Date
object's methods to work with the date.
Strangely, the Date object has no properties. To set or obtain values from a Date object, you
must use the methods described in the next section.
Note
JavaScript dates are stored as the number of milliseconds
since January 1st, 1970, at midnight. This date is called the
epoch. Dates before 1970 aren't allowed. This means I can't
store my birthday in a Date object, and there's a good chance
you can't either. Hopefully, this will be fixed in a future version
of JavaScript. In the meantime, you can work with dates
manually, using strings or numeric variables.
• getTimeZoneOffset() gives you the local time zone's offset from GMT (Greenwich Mean
Time, also known as UTC).
• toGMTString() converts the date object's time value to text, using GMT.
• toLocalString() converts the date object's time value to text, using local time.
• Date.parse() converts a date string, such as "June 20, 1996" to a Date object (number of
milliseconds since 1/1/1970).
• Date.UTC() is the opposite: it converts a Date object value (number of milliseconds) to a
UTC (GMT) time.
Note
Because you may use the Math object's properties and
methods throughout an entire group of statements, you may
find it useful to use the with keyword, introduced earlier in this
chapter, to specify the Math object for those statements.
I will introduce some highlights of the Math object's methods in the following sections. For a
complete list of the properties and methods of this object, including trigonometric and logarithmic
functions, refer to appendix A.
Note
One use for the navigator object is to check for a particular
version of Netscape; this is most useful if you are using a
feature that was recently added and want to include an
alternative for users of older versions.
There are also several properties of the navigator object that deal with Java, plug-ins, and
multimedia documents:
Customizing Objects
Along with the various built-in objects, you can also create objects of your own. You've already
seen the basic example of doing this with the new keyword:
var = new ObjectType(parameters);
This assumes you have created an object definition for the object. Once you've done this, you
can work with the properties and methods of the object, just like the built-in objects.
In object-oriented terms, the object definition defines a prototype for the object. This is the set of
rules that govern how an object works. JavaScript provides a prototype keyword, which enables
you to modify the prototype of all objects of a certain class.
As an example, suppose you defined an object called lunch with the following properties:
lunch.sandwich lunch.drink lunch.fruit
You could then create a lunch object like this:
mylunch = new lunch("bologna","coke","banana");
As you saw in other chapters, you could then add a property to the object:
mylunch.dessert = "pie";
With a prototype, though, you can add a property to the object definition itself. This command will
add the dessert property to all existing and future lunch objects:
lunch.prototype.dessert = "cake";
Any lunch object created after this point will include this property, with a default value of "cake".
The property will also be added to existing lunch objects. You can also extend the prototypes of
the built-in objects, as you'll see in the next example.
First, you define the addhead() function, which will serve as the new string method. It accepts a
number to specify the heading level. The start and stop variables are used to store the HTML
begin and end header tags, such as <H1> and </H1>.
After the function is defined, you simply use the prototype keyword to add it as a method of the
String object. You can then use this method on any String object; this is demonstrated by the last
statement, which displays a quoted text string as a level-one header.
Workshop Wrap-Up
In this chapter, you learned the details of JavaScript's object-oriented capabilities, the various
keywords used for working with objects in JavaScript, and techniques for working with objects
and properties.
You also learned about the built-in objects that aren't directly related to Web pages:
Next Steps
You can now learn about the JavaScript object hierarchy and more advanced features:
• To learn about the object hierarchy, which enables you to work with Web page elements,
see Chapter 5 "Accessing Window Elements as Objects."
• To learn to use the objects to work with HTML forms, see Chapter 6, "Using Interactive
Forms."
• To review the basics of JavaScript objects, see Chapter 3 "Working with Objects and
Events."
• To see some of the techniques in this chapter in action, see Chapter 7 "Real-Life
Examples I."
• To learn techniques for perfecting and debugging your JavaScript programs, see Chapter
14, "Debugging JavaScript Programs."
Q&A
Q: Do you really need to use objects within objects? Is there any practical reason to
do this?
A: JavaScript programs are usually simple, and you probably won't need data structures
that are complicated very often. However, the object hierarchy--which you'll learn about
in Chapter 5--uses these techniques heavily.
Q: Most of the string appearance methods, such as string.big, take almost as much
typing as simply including the appropriate HTML codes. Why would I use these?
A: One reason is that they may be more readable if someone (including you) needs to
read through the source code later. Another reason is that the HTML specification may
change; presumably, future versions of JavaScript will use the appropriate codes for
new versions of HTML, so you won't have to worry about updating your program.
Q: Is there any limit to the length of a string variable in JavaScript?
A: Strictly speaking, no. The only limitation is the memory available on the user's machine.
You should keep lengths to a minimum, though, to avoid crashing the browser.
Chapter 5
Accessing Window Elements as Objects
One of JavaScript's strengths is the capability of working with elements of the Web page directly.
This is handled through the JavaScript object hierarchy. This hierarchy includes a variety of
objects that represent data on the current Web page and in the current browser window.
These objects are organized into a hierarchy of parent and child objects. A child object is simply
an object that is used as a property of another object (the parent object).
Each of the objects in the hierarchy includes properties, which are often objects in themselves. It
may also include methods to perform functions on the object. Finally, it may include event
handlers, which call functions or JavaScript statements when an event happens to that object.
A diagram of the object hierarchy is given in Figure 5.1. The hierarchy begins with the window
object, which serves as the parent object for most of the other objects. This chapter describes
each object in the following sections, beginning with the window object and working downward
through the hierarchy.
Figure 5.1 : The JavaScript object hierarchy.
• The location object stores the location (URL) that is displayed in the window.
• The document object holds the Web page itself.
• The history object contains a list of sites visited before and after the current site.
Each of these objects is described in detail later in this chapter. In most cases, there is only one
window object, so you can omit the window object name when referring to the current script's
window. For example, this statement sets the current window's status property:
status = "This is a test."
Note
Notice the syntax used to refer to the text field:
document.statform.input1.value. This may be a bit confusing,
but this is the syntax required to access an element of a form.
You'll learn about forms in detail in Chapter 6 "Using
Interactive Forms."
Although this application is an example of how much fun you can have with JavaScript in only
one statement, it's not very useful. A more common (and more practical) application is to use the
status line for onMouseOver event handlers, which enables you to provide useful instructions for
links and form elements. You'll learn about this use of the status property in Chapter 8.
Using Frames
Some browsers (including the latest Netscape and Microsoft browsers) support frames or
framesets. These enable you to divide the browser window into multiple panes, called frames.
Each frame can contain a separate URL or the output of a script.
When you use frames, there are several window objects: one for the main (parent) window, and
one for each frame. The window object has two properties that are used with frame documents:
• The frames array is used to store information about each frame. It is made up of frame
objects, which work as window objects in themselves. You can also refer to a frame's
window object by name.
• The parent.frames.length property specifies the number of frames in the window.
Because frames can make for some complicated-and useful-programming, they are described in
detail in Chapter 9 "Using Frames, Cookies, and Other Advanced Features."
• The WindowName variable is used to store the new window object. You can access
methods and properties of the new object by using this name.
• The first parameter of the window.open() method is an URL, which will be loaded into the
new window. If left blank, no Web page will be loaded.
• The second parameter specifies a window name (here, WindowName again). This is
assigned to the window object's name property and is used for targets, which are
explained in Chapter 9.
• The third parameter is a list of optional features, separated by commas. You can
customize the new window by choosing whether to include the toolbar, status line, and
other features. This enables you to create a variety of "floating" windows, which may look
nothing like a typical browser window.
The features available in the third parameter of the window.open() method include width and
height, to set the size of the window, and several features that can be set to either yes (1) or no
(0): toolbar, location, directories, status, menubar, scrollbars, and resizable. You can list only the
features you want to change from the default. This example creates a small window with no
toolbar or status line:
SmallWin = window.open("","small","width=100,height=120,toolbar=0,status=0");
Of course, you can close windows as well. The window.close() method closes a window.
Netscape doesn't enable you to close the main browser window without the user's permission; its
main purpose is for closing windows you have created. For example, this statement closes a
window called updatewindow:
updatewindow.close( );
As another example, Listing 5.2 shows an HTML document that enables you to open a new
window by pressing a button. (I have specified a very small size for the second window so you
can tell them apart.) You can then press another button to close the new window. The third button
attempts to close the current window; Netscape allows this, but asks for confirmation first.
Again, this example uses event handlers to do its work, one for each of the buttons. Figure 5.3
shows Netscape's display of this page, with the small new window on top.
Figure 5.3 : A new Netscape window opened with JavaScript.
Displaying Dialogs
The window object includes three methods that are useful for displaying messages and
interacting with the user:
• The alert() method displays an alert dialog box, shown in Figure 5.4. This dialog simply
gives the user a message.
• The confirm() method displays a confirmation dialog. This displays a message and
includes OK and Cancel buttons. This method returns true if OK is pressed and false if
Cancel is pressed. A confirmation is displayed in Figure 5.5.
• The prompt() method displays a message and prompts the user for input. It returns the
text entered by the user.
Figure 5.4 : A JavaScript alert dialog displays a message.
Figure 5.5 : A JavaScript confirm dialog asks for confirmation.
This example displays three buttons, and each uses an event handler to display one of the
dialogs. Let's take a detailed look at each one:
Figure 5.6 shows the program in Listing 5.3 in action. The prompt dialog is currently displayed
and shows the default value, and the status line is still displaying the result of a previous
confirmation dialog.
Figure 5.6 : The dialog box example's output, including a prompt dialog.
Note
Notice that Netscape prefaces each of the dialogs with a
message, such as "JavaScript Alert:" or "JavaScript Confirm:".
Unfortunately, there is no way to avoid the display of these
messages in the present version.
Using Timeouts
Two more methods of the window object enable you to set timeouts. These are statements (or
groups of statements) that will be executed after a certain amount of time elapses. These are
handy for periodically updating a Web page or for delaying a message or function.
You begin a timeout with the setTimeout() method. This method has two parameters. The first is
a JavaScript statement, or group of statements, enclosed in quotes. The second parameter is the
time to wait in milliseconds (thousandths of seconds). For example, this statement displays an
alert dialog after 10 seconds:
ident=window.setTimeout("alert('Time's up!')",10000);
A variable (ident in this example) stores an identifier for the timeout. This enables you to set
multiple timeouts, each with its own identifier. Before a timeout has elapsed, you can stop it with
the clearTimeout() method, specifying the identifier of the timeout to stop:
window.clearTimeout(ident);
These timeouts execute only once; they do not repeat unless you set another timeout each time.
• The blur() method is the opposite-it removes focus from the specified window, sending it
to the background.
• The onLoad event occurs when the document in the window is finished loading.
• The onUnload event occurs when another document starts to load, replacing the
window's current document.
• The onFocus event occurs when the window receives focus.
• The onBlur event occurs when the window loses focus.
• The onError event occurs if the document in the window fails to load properly.
You can specify JavaScript statements or functions for these events using attributes of a Web
page's <BODY> tag. For example, Listing 5.5 shows an HTML document that displays an alert
message when it is loaded and another when it is unloaded.
Listing 5.5. (ONLOAD.asp) Using the onLoad and onUnload events to
display dialogs.
<HTML> <HEAD><TITLE>onLoad and onUnload Example</TITLE> </HEAD>
<BODY onLoad="window.alert('Hello, and welcome to this page.');"
onUnload="window.alert('You unloaded the page. Goodbye!');"> <H1>The
onLoad and onUnload Methods</H1> <HR> This page displays a "hello" dialog
when you load it, and a "goodbye" dialog when you unload it. Annoying, isn't it?
<HR> This is done through event handlers specified in this document's
<BODY> tag. Aside from that tag, the rest of the document doesn't affect
the dialogs. <HR> </BODY> </HTML>
This document will display a "hello" alert when it loads and a "goodbye" alert when it unloads.
You can unload the page by closing the browser window or by loading a different page. Figure
5.8 shows Netscape's display of this document, including the onLoad alert.
Figure 5.8 : The output of the onLoad and onUnload example.
http://www.starlingtech.com/guides/javascript/test.asp#part2
The following are the components of the URL as they correspond with properties of the location
object:
• location.protocol is the protocol (or method) of the URL. This specifies the protocol to be
used-world-wide web, gopher, and so forth. In the example, the protocol is http:. The
colon is included in the protocol property.
• location.hostname specifies the host where the resource is located
(www.starlingtech.com in the example).
• location.port specifies the communication port number on the host, usually 80 for the
Web (and in the example).
• location.host is a combination of the host name and port (www.starlingtech.com:80 in the
example).
• location.pathname is the directory to find the document on the host and the name of the
file (/guides/javascript/test.asp in the example).
• location.hash is the name of an anchor within the document, if specified (#part2 in the
example). You can set this value to different anchor names to jump around the Web
page.
• location.target specifies the TARGET attribute of the link that was used to reach the
current location. You will examine this attribute in detail in Chapter 9.
• location.query specifies a query string; if the location is a CGI program, this string is
passed as a parameter to the program.
• Finally, location.href is the whole URL, including all the parts listed.
• location.reload() reloads the current document; this is the same as the reload button on
Netscape's toolbar.
• location.replace() replaces the current location with a new one; this is similar to setting
the location object's properties yourself. The difference is that the new location replaces
the current history entry rather than adding to the history.
Caution
The only way to modify most of the document object's
properties is to change the HTML page itself, or use JavaScript
statements within the page to generate HTML dynamically.
• The URL property (formerly location) specifies the document's URL. Don't confuse this
with the location object explained earlier: it's a simple text field. You can't change this
property; if you need to send the user to a different location, use the window.location.href
property.
• The title property lists the title of the current page, defined by the HTML <TITLE> tag.
• The referrer property is the URL of the page the user was viewing prior to the current
page-usually, the page with a link to the current page.
• The lastModified property is the date the document was last modified. This date is sent
from the server along with the page.
As an example, this is a short HTML document that displays its last-modified date:
This can be a useful indication to the user of when the page was last changed, and if you use
JavaScript, you don't have to remember to update the date each time you modify the page.
Note
The lastModified property doesn't work correctly and may
cause crashes in certain platforms and Netscape versions. In
addition, some Web servers don't send modification dates
properly. See Chapter 14, "Debugging JavaScript Programs,"
for further information.
• The form objects include information about each <FORM> in the current document.
• The anchors array identifies each of the anchors (places that can be jumped to) in the
current document.
• The links array includes information for each of the links in the current document.
• The images array contains information about each of the images in the document.
The forms, anchors, and links objects are each discussed in their own sections later in this
chapter. The images array is explained in Chapter 12.
The simplest document object methods are also the ones you will use most often. In fact, you've
used one of them already. The document.write() method prints text as part of the HTML page in a
document window. This statement is used whenever you need to include output in a Web page.
An alternative statement, document.writeln(), also prints text, but it also includes a newline (\n)
character at the end. This is handy when you want your text to be the last thing on the line.
Tip
Bear in mind that the newline character is ignored by HTML,
except inside the <PRE> container. You will need to use the
<BR> tag if you want an actual line break.
You can only use these methods within the body of the Web page, so they will be executed when
the page loads; you can't add to a page that has already loaded. You can write new content for a
document, however, as the next section explains.
Note
When you use the document.open() method, the current
document is cleared. Any data already displayed in the
document is erased.
Warning
The clear() method doesn't work reliably in most versions of
Netscape. The best solution for clearing and updating
documents is to use the open() method to clear the document
window, use the write() method to write the new contents (or
no contents), and then use the close() method to close the
stream.
The history object is another child (property) of the window object. This object holds information
about the URLs that have been visited before and after the current one, and it includes methods
to go to previous or next locations.
The history object has one property: length. This keeps track of the length of the history list-in
other words, the number of different locations that the user has visited.
You might notice one thing missing from the history object's properties: the URLs themselves.
These used to be available as a property, but Netscape removed them due to privacy concerns.
When they worked, Web pages could grab your history list and use it for statistics, marketing, or
even blackmail.
Note
The saying "You can't change history" also applies to
JavaScript. You can't modify a window's history list or delete
items from the list.
The history object's methods enable you to send the user to other locations:
• history.back() goes back to the previous location. This is equivalent to the browser's
back-arrow button.
• history.forward() goes forward to the next location. This is equivalent to the browser's
forward-arrow button.
• history.go() goes to a specified location in the history list. You can specify a positive
number to go forward, a negative number to go back, or a string to be searched for in the
history list.
Each link object (or member of the links array) has a list of properties defining the URL. These
are the same properties as the location object, defined earlier in this chapter. You can refer to a
property by indicating the link number and property name. For example, this statement assigns
the variable link1 to the entire URL of the first link (index 0):
link1 = links[0].href;
Tip
The links array also includes area objects, which are used with
client-side image maps. These are explained in Chapter 12.
• The onMouseOver event happens when the mouse pointer moves over the link's text.
• The onClick event happens when the user clicks on the link.
You'll use the onMouseOver event to create friendly status-line descriptions for links in Chapter 8.
As for the onClick event handler, it's very handy for executing a JavaScript function when the user
clicks on a link. For example, this defines a link that displays an alert:
<a href="#" onClick="window.alert('This is a test.');">
Notice that I used a simple # sign as the URL in this example, to avoid sending the user to
another page when the link is clicked. Another use for the onClick event handler is to prevent a
link from being followed; your event handler can do this by returning false. For example, this link
asks for confirmation:
<a href="sound.wav" onClick="return window.confirm('play sound?');">
If the user clicks the OK button, the link is followed because true is returned; otherwise, false is
returned and the link is ignored. This might be handy for files that will take a while to download, or
any situation where you want to control links with JavaScript.
Form Objects
Another child of the document object is the form object, which represents an HTML form. Like
anchors and links, there can be several form objects within a document. You can access a form
by name (specified with the NAME attribute to the <FORM> tag) or by using the forms array,
which includes an element for each form.
The form has many properties that are objects themselves: the elements, or components, of the
form. These are the text fields, buttons, and other objects that make up a form. You can access
these by using their individual names, or once again with an array; the elements array indexes
each element of the form.
Forms have been used in a few of the examples in this chapter. Because forms are one of the
greatest strengths of JavaScript, there's a lot of information to cover. Chapter 6covers forms and
form objects in detail.
Workshop Wrap-Up
In this chapter, you took a guided tour of the JavaScript object hierarchy, which contains objects
to represent parts of the current window and document:
• The window object represents the browser window or each window in a framed
document.
• The document object represents the currently loaded document in a window.
• The location object stores the current location or URL for each window.
• The history object stores the history of documents for a window or frame.
• The link and anchor objects store information about links and link targets in a document.
• The forms array, or form objects, store information about each form in a document.
Next Steps
You should now know the JavaScript object hierarchy inside and out. Continue with one of these:
• To learn about built-in objects outside the hierarchy, such as Math, Date, Array, and
String, see Chapter 4 "Using Built-In Objects and Custom Objects."
• To learn to use the objects to work with HTML forms, see Chapter 6, "Using Interactive
Forms."
• To learn more about using frames and other features of the latest generation of Web
browsers, see Chapter 9 "Using Frames, Cookies, and Other Advanced Features."
• To see some of the techniques in this chapter in action, see Chapter 7 "Real-Life
Examples I."
• To learn techniques for perfecting and debugging your JavaScript programs, see Chapter
14, "Debugging JavaScript Programs."
Q&A
Q: Why do I have to specify the document object, but not the window object, when
using its properties and methods?
A: Good question! The reason is that the window object contains the current script, so it's
treated as a default object. Also, be warned that there are situations in which you
shouldn't omit the window object's name-when frames or multiple windows are involved,
for example, or in an event handler.
Q: When I try to close the current window with window.close(), I get an error or no
result. Is there a solution?
A: This is another capability that was removed from JavaScript due to a security concern.
(The last thing Netscape wants is for people to click on a button and exit Navigator
immediately.) You can officially use the close() method only on windows that you opened
yourself. Some versions of Netscape crash when you attempt to close the main window;
the most recent version asks the user for confirmation before closing it.
Q: Why is the text "JavaScript Alert:" displayed at the top of all my alert messages?
Is there no way to stop this?
A: No, and it's another security feature. Without it, I could make my script display an alert
with a message like "Netscape error: please enter your password" and get a few unwary
users to send me their passwords. (Not that I would do that, of course.)
Q: I want to make a control panel window for my Web page. Is there a way to keep
this window on top at all times?
A: No, no easy way; JavaScript doesn't have an "always on top" feature. You could use the
focus() method in an onBlur event handler to make it return to the top, but this doesn't
always work.
0
00
0
0
0
Chapter 6
Using Interactive Forms
In this chapter you'll explore one of the most powerful uses for JavaScript: working with HTML
forms. You can use JavaScript to make a form more interactive, to validate data the user enters,
and to enter data based on other data.
Let's begin with a basic order form for an imaginary company and use JavaScript to add features
to the form. Along the way you'll learn about the various form elements, how they relate to
JavaScript, and just what you can do with each one.
Tip
It is possible to have a JavaScript-only form. You used simple
forms in Chapter 5 "Accessing Window Elements as Objects,"
to interact with the user. You'll find many more examples
throughout this guide.
After the CGI script receives the data, it sends a response back to the user. This can send the
user to a different Web page or can generate a page "on the fly" and display it.
• NAME is simply a name for the form. You can use forms without giving them names, but
you'll need to assign a name in order to use the form with JavaScript.
• METHOD is either GET or POST; these are the two ways the data can be sent to the
server.
• ACTION is the CGI script that the form data will be sent to when submitted. You'll look at
an actual script in Chapter 17. You can also use the mailto: action to send the form's
results to an e-mail address.
For example, here is a <FORM> tag for a form named Order. This form uses the GET method
and sends its data to a CGI script called order.cgi in the same directory as the Web page itself:
<FORM NAME="Order" METHOD="GET" ACTION="order.cgi">
For a form that will be processed entirely by JavaScript (such as a calculator or interactive game),
the METHOD and ACTION attributes are not needed. You can use a simple <FORM> tag that
names the form:
<FORM NAME="calcform">
The <FORM> tag is followed by one or more form elements. These are the data fields in the form,
such as text fields and checkboxes. You will look at each type of element in the following
sections. After all the elements comes the form ending tag, </FORM>. After this tag, you can't
use form elements without starting another form.
Note
You can also include any normal HTML elements within the
<FORM> tags. This is useful for labeling each of the elements.
An optional attribute to the SELECT tag, MULTIPLE, can be specified to allow multiple items to
be selected. Browsers usually display a single-selection SELECT as a drop-down list and a
multiple-selection list as a scrollable list.
Figure 6.2 is an example of an HTML page in Netscape that shows examples of checkboxes,
radio buttons, and single- and multiple-selection lists.
Figure 6.2 : An example of the display of checkboxes, radio buttons, and selection lists.
Hidden Fields
HTML form elements include a special type of field: the hidden field. This includes a name and a
value, similar to a text field; however, you can't edit it, and it is not displayed on the Web page.
Hidden fields are useful for passing information to the CGI script or between multiple scripts.
A hidden field uses the <INPUT> tag and simply has a name and a value. For example, this
command defines a hidden field called score with a value of 40200:
• type=SUBMIT is a submit button. This button causes the data in the form fields to be sent
to the CGI script.
• type=RESET is a reset button. This button sets all the form fields back to their default
value, or blank.
• type=BUTTON is a generic button. This button performs no action on its own, but you can
assign it one using JavaScript.
All three types of buttons include a NAME to identify the button, and a VALUE that indicates the
text to display on the button's face. A few buttons were used in the examples in Chapter 5. As an
example, the following defines a SUBMIT button with the name sub1 and the value "Click Here":
<INPUT TYPE="SUBMIT" NAME="sub1" VALUE="Click Here">
• Text fields for the buyer's name, phone number, and e-mail address, and text areas for
the billing and shipping address.
• Because the company has only four products, there's room to list them all on the form.
Each has its own text fields for quantity and cost.
• A total cost text field is used to store the total cost. The user then selects the method of
payment from the selection list and enters a credit card number or check number if
needed.
• Finally, a SUBMIT button enables users to send the order, and a RESET button enables
them to start over with the defaults.
Listing 6.1 shows the complete HTML form, and Figure 6.3 shows Netscape's display of the form.
Forms like this one are used all over the Web. As you can see, this form isn't very user-friendly;
the user has to calculate the cost for each item and the total cost. You will use JavaScript to add
automatic calculation and other interactive features later in this chapter.
array. For example, these expressions both refer to the first element in the order form, the name1
text field:
document.order.elements[0] document.order.name1
Note
Both forms and elements can be referred to with their own
names, or as indices in the forms and elements arrays. For
clarity, this chapter will use individual form and element names
rather than array references.
If you do refer to forms and elements as arrays, you can use the length property to determine the
number of objects in the array: document.forms.length is the number of forms in a document, and
document.form1.elements.length is the number of elements in the form1 form.
Along with the elements, each form object also has a list of properties, most of which are defined
by the corresponding <FORM> tag. You can also set these from within JavaScript. They include
the following:
• action is the form's ACTION attribute, or the program to which the form data will be
submitted.
• encoding is the MIME type of the form, specified with the EncTYPE attribute. In most
cases, this is not needed.
• length is the number of elements in the form.
• method is the method used to submit the form, either GET or POST.
• target specifies the window in which the result of the form (from the CGI script) will be
displayed. Normally, this is done in the main window, replacing the form itself.
Note
You can use a mailto URL in the ACTION attribute of a form
and have the data mailed to you instead of submitted to a CGI
script. Using the submit() method with such an action enabled
scripts to obtain information about your computer or to send
mail from your address without your knowledge. Because of
this potential security and privacy concern, Netscape disabled
the submit method for mailto URLs.
• name is the name given to the field. This is also used as the object name.
• defaultValue is the default value; this corresponds to the VALUE attribute. This is a read-
only property.
• value is the current value. This starts out the same as the default value, but can be
changed-either by the user or by JavaScript functions.
Most of the time when you work with text fields, you will use the value attribute to read the value
the user has entered, or to change the value. For example, this statement changes the value of a
text field called username in the order form to "John Q. User":
document.order.username.value = "John Q. User"
Note
For security reasons, you cannot normally access the value
property of a password object in JavaScript. You can access it
if you enable data tainting, as explained in Chapter 10,
"Working with Multiple Pages and Data."
• focus() sets the focus to the field. This positions the cursor in the field and makes it the
"current" field.
• blur() is the opposite; it removes the focus from the field.
• select() selects the text in the field, just as a user can do with the mouse. You cannot
currently select only part of a field.
Tip
These aren't the only methods you can use with text fields;
don't forget that because the value property is a String object,
you can use any of the String methods on the value. The String
object is explained in Chapter 4 "Using Built-In Objects and
Custom Objects."
Text Areas
Text areas are defined with their own tag, <TEXTAREA>, and are represented by the textarea
object. This object includes the same properties, methods, and event handlers as the text and
password objects. For example, this <TEXTAREA> tag includes an onFocus event handler to
change the status line:
<TEXTAREA NAME="text2" onFocus = "window.status = 'got focus.';">Default
Value</TEXTAREA>
There is one difference about a text area's value: it can include more than one line, with end-of-
line characters between. This can be complicated by the fact that the end-of-line character is
different on the three platforms (\r\n in Windows; \n in UNIX and Macintosh). Be sure to check for
both types when needed.
If you are placing your own values into a text field, the latest version of JavaScript automatically
converts any end-of-line characters to match the user's platform, so you can use either type.
Note
This is an example of a platform-specific issue within
JavaScript; although JavaScript is intended as a platform-
independent language, there are still a few stubborn features.
See Chapter 14, "Debugging JavaScript Programs," for
additional information.
Checkboxes
A checkbox is simple: it has only two states. Nevertheless, the checkbox object has four different
properties:
• name is the name of the checkbox, and also the object name.
• value is the "true" value for the checkbox-usually on. This value is used by the server to
indicate that the checkbox was checked. In JavaScript, you should use the checked
property instead.
• defaultChecked is the default status of the checkbox, assigned by the chECKED
attribute.
• checked is the current value (true for checked, and false for unchecked).
To manipulate the checkbox or use its value, you use the checked attribute. For example, this
statement turns on a checkbox called same in the order form:
document.order.same.checked = true;
The checkbox has a single method, click(). This method simulates a click on the box. It also has a
single event, onClick, which occurs whenever the checkbox is clicked. This happens whether the
box was turned on or off, so you'll need to check the checked property.
Caution
The click() method does not work properly in some versions of
Netscape. You should avoid it when possible.
Radio Buttons
Radio buttons are similar to checkboxes, but an entire group of them shares a single name and a
single object. You can refer to the following properties of the radio object:
• name is the name common to the radio buttons.
• length is the number of radio buttons in the group.
To access individual buttons, you treat the radio object as an array. The buttons are indexed,
starting with 0. Each individual button has the following properties:
• value is the value assigned to the button. (This is used by the server.)
• defaultChecked indicates the value of the chECKED attribute and the default state of the
button.
• checked is the current state.
For example, you can check the first radio button in the radio1 group on the form1 form with this
statement:
document.form1.radio1[0].checked = true;
However, if you do this, be sure you set the other values to false as needed. This is not done
automatically. You can use the click method to do both of these in one step.
Like a checkbox, radio buttons have a click() method and an onClick event handler. Each radio
button can have a separate statement for this event.
Note
A bug in Netscape Navigator 2.0 causes radio buttons to be
indexed backward; index 0 will actually be the last button on
the page. This is fixed in version 3.0 and later, but watch out
for strange behavior when users use an old version.
Selection Lists
A selection list is similar to radio buttons, because the entire group of options shares a name. In
this case, the data for each element is stored in the options array, which indexes the different
options starting with 0.
The object for selection lists is the select object. The object itself has the following properties:
• name is the name of the selection list.
• length is the number of options in the list.
• options is the array of options (explained later).
• selectedIndex returns the index value of the currently selected item. You can use this to
check the value easily. In a multiple-selection list, this indicates the first selected item.
The options array has a single property of its own, length, which indicates the number of
selections. In addition, each item in the options array has the following properties:
• index is the index into the array.
• defaultSelected indicates the state of the SELECTED attribute.
• selected is the current state of the option. Setting this property to true selects the option.
You can select multiple options if the MULTIPLE attribute is included in the <SELECT>
tag.
• name is the value of the NAME attribute. This is used by the server.
• text is the text that is displayed in the option. In Netscape 3.0 or later, you can change
this value.
The select object has two methods, blur() and focus(). These perform the same purpose as the
corresponding methods for text objects. The event handlers are onBlur, onFocus, and onChange,
also similar to other objects.
You can change selection lists dynamically-for example, choosing a product in one list could
control which options are available in another list. You can also add and delete options from the
list. You will look at these capabilities in Chapter 11, "Real-Life Examples II."
Note
The onChange event doesn't work for select lists in some
versions of Netscape . It does work properly in version 3.0 and
later.
Hidden Fields
Hidden fields are stored in hidden objects. This object has two properties, name and value. These
function similarly to a text field. There are no methods or event handlers for the hidden object-it
can't be changed, so the user can't really mess with a hidden field.
Buttons
Buttons can be defined as SUBMIT buttons, RESET buttons, or generic BUTTON buttons. All of
these types have the same properties, methods, and events.
Buttons support the name property, used to identify the button, and the value property, which
defines the button's text. You cannot change either of these values. Buttons support a single
method, click(), and an event handler, onClick.
The onClick action is performed with any button. In the case of a generic button, nothing else
happens. In a SUBMIT or RESET button, you can prevent the submission or resetting by
returning a false value.
Note
As with radio buttons and checkboxes, the click method may
not work with some older versions of Netscape. Check your
version before attempting to use it, and expect trouble from
users of older versions.
A relatively new feature of Netscape enables you to define a file upload field on a form. This
enables the user to upload a file to the server. You can define a file upload field with an <INPUT>
tag:
<INPUT TYPE="file" NAME="fname">
Because this field is mainly for interacting with the server, JavaScript has little control over it. A
FileUpload object represents the field, and you can access two properties:
• name is the name of the field, as defined in the <INPUT> tag.
• value is the name of the file (if any) the user is uploading.
Listing 6.2 shows the revised HTML order form including the new functions. You now have an
order form that updates automatically-each time you enter or change a quantity, the cost for that
item and the total cost are updated. Figure 6.4 shows the order form after several quantities have
been entered.
Figure 6.4 : The order form with automatically updated numeric totals.
Listing 6.2. The revised HTML order form, including automatic update
functions.
<HTML> <HEAD><TITLE>Order Form</TITLE> <SCRIPT> // function to
calculate the total cost field function Total() { var tot = 0; tot += (40.00 *
document.order.qty1.value); tot += (69.95 * document.order.qty2.value); tot +=
(99.95 * document.order.qty3.value); tot += (4.95 * document.order.qty4.value);
document.order.totalcost.value = tot; } // function to update cost when quantity is
changed function UpdateCost(number, unitcost) { costname = "cost" + number;
qtyname = "qty" + number; var q = document.order[qtyname].value;
document.order[costname].value = q * unitcost; Total(); } </SCRIPT> </HEAD>
<BODY> <H1>Order Form</H1> <FORM NAME="order"> <B>Name:</B>
<INPUT TYPE="text" NAME="name1" SIZE=20> <B>Phone: </B><INPUT
TYPE="text" NAME="phone" SIZE=15> <B>E-mail address:</B><INPUT
TYPE="text" NAME="email" SIZE=20><BR> <B>Billing and Shipping
Addresses:</B><BR> <TEXTAREA NAME="billto" COLS=40 ROWS=4> Enter
your billing address here. </TEXTAREA> <TEXTAREA NAME="shipto"
COLS=40 ROWS=4> Enter your shipping address here. </TEXTAREA>
<B>Products to Order:</B><BR> Qty: <INPUT TYPE="TEXT" NAME="qty1"
VALUE="0" SIZE=4 onChange = "UpdateCost(1, 40.00);"> Cost: <INPUT
TYPE="TEXT" NAME="cost1" SIZE=6> ($40.00 ea) Fictional Spreadsheet 7.0
<BR> Qty: <INPUT TYPE="TEXT" NAME="qty2" VALUE="0" SIZE=4 onChange
= "UpdateCost(2, 69.95);"> Cost: <INPUT TYPE="TEXT" NAME="cost2"
SIZE=6> ($69.95 ea) Fictional Word Processor 6.0<BR> Qty: <INPUT
TYPE="TEXT" NAME="qty3" VALUE="0" SIZE=4 onChange = "UpdateCost(3,
99.95);"> Cost: <INPUT TYPE="TEXT" NAME="cost3" SIZE=6> ($99.95 ea)
Fictional Database 7.0 <BR> Qty: <INPUT TYPE="TEXT" NAME="qty4"
VALUE="0" SIZE=4 onChange = "UpdateCost(4, 4.95);"> Cost: <INPUT
TYPE="TEXT" NAME="cost4" SIZE=6> ($4.95 ea) Instruction guidelet for the
above <HR> <B>Total Cost:</B> <INPUT TYPE="TEXT" NAME="totalcost"
SIZE=8><HR> <B>Method of Payment</B>: <SELECT NAME="payby">
<OPTION VALUE="check" SELECTED>Check or Money Order <OPTION
VALUE="cash">Cash or Cashier's Check <OPTION VALUE="credit">Credit Card
(specify number) </SELECT><BR> <B>Credit Card or Check Number:</B>:
<INPUT TYPE="TEXT" NAME="creditno" SIZE="20"><BR> <INPUT
TYPE="SUBMIT" NAME="submit" VALUE="Send Your Order"> <INPUT
TYPE="RESET" VALUE="Start Over"> </FORM> </BODY> </HTML>
Automating the Shipping Address
Because the order form includes spaces for separate billing and shipping addresses, it's a good
idea to give the user an option to use the same address for both. Using JavaScript, you can add
such an option easily-and it makes for a neat bit of automation.
To accomplish this, you'll add a checkbox above the addresses and label it:
<INPUT TYPE="chECKBOX" NAME="same" onClick="CopyAddress();"> Ship to
Billing Address
You'll use the onClick event handler for the checkbox to handle the copying. Here is the
CopyAddress function for copying the address:
Where to Validate?
You could use the onChange event handler on each of the fields to validate it. For example, as
soon as users enter their names and move to the next field, you could alert them if the names are
invalid.
This method is worth considering in some cases, but for most forms it's best to validate all the
fields at once, using the form's onSubmit event handler. This enables users to correct any fields
necessary, then press submit when they're really ready.
For the FSC order form, you will use a single onSubmit event handler to perform the validation for
all the fields.
Tip
If you choose to validate fields as they change, you might find
it useful to use the this keyword. Within an event handler, this
represents the object that triggered the event. This technique
enables you to use a single validation routine for several fields.
• If the payment method is anything but cash, the credit card number/check number field
must be at least 2 characters.
Obviously, you could make some of these more specific, but they'll do to illustrate the concept.
You'll need to choose the appropriate values for each form with which you work.
One more thing: the error function sets a variable, errfound, to indicate that an error has
happened. It returns immediately if an error was already found; this prevents multiple dialogs from
showing if more than one field is invalid.
Workshop Wrap-Up
In this chapter, you built a fully functional ordering system for an imaginary company, which could
easily be modified for use by a real company. In the process, you learned the following:
• How to use HTML forms and their many elements in a Web page
• How to use JavaScript to add validation to the form
• How to use JavaScript to add automation to a form
• About the <FORM> object and form elements, and how to manipulate and read each of
their values in JavaScript
Next Steps
You should now know how to use JavaScript with forms. To move on, turn to one of the following
chapters:
• To learn about the object hierarchy that underlies forms, see Chapter 5 "Accessing
Window Elements as Objects."
• To see another example of form validation, turn to Chapter 7, "Real-Life Examples I."
• To learn to add functionality to a Web page, such as navigation bars and the status line,
see Chapter 8 "Improving a Web Page with JavaScript."
• To learn about advanced browser features such as frames, see Chapter 9 "Using
Frames, Cookies, and Other Advanced Features."
• To learn more about CGI and interactive forms, see Chapter 17, "Combining JavaScript,
CGI and SSI."
Q&A
Q: Is there any way to force a form to be submitted automatically, without the user
pressing a button?
A: Yes. You can do this with the form.submit() method. However, this is bad manners; it's
usually best to let the user know what's going on. Also note that due to security
concerns, you can't do this with a form that uses the mailto action.
Q: I am having problems trying to force a checkbox to be selected using the click
method. Is there a way to solve this?
A: Unfortunately, at least for many versions of Netscape, the only solution is not to use the
click method. Fortunately, it's easy to do most things without it. For a checkbox, you can
manipulate the checked property; for a button, you can call the same function as its
onClick event handler.
Q: If I use JavaScript to add validation and other features to my form, can users with
non-JavaScript browsers still use the form?
A: Yes, if you're careful. Be sure to use a SUBMIT button rather than the submit action.
Also, because the CGI script may receive nonvalidated data, be sure to include
validation in the CGI script. Non-JavaScript users will be able to use the form but won't
receive instant feedback about their errors.
Q: Can I add new form elements "on the fly," or change them-for example, change a
text box into a password field?
A: No. The form elements are set by the HTML code. There are ways to work around this,
such as updating the form in a separate frame.
Q: Is there any way to create a large number of text fields without dealing with
different names for all of them?
A: Yes. If you use the same name for several elements in the form, their objects will form an
array. For example, if you defined 20 text fields with the name member, you could refer
to them as member[0] through member[19]. Chapter 15, "Real-Life Examples III," uses
this technique for score values in a game.
Q: When validating an e-mail address, is there any way to be sure the address is
valid, or that it is the user's address?
A: No. This is a classic question about CGI; neither JavaScript nor CGI has a good solution.
The only way to be sure an e-mail address is valid is to send information, such as a
password, to the address; even then, you can't be sure users are entering their own
addresses.
Q: Why doesn't JavaScript recognize my form elements when I use a table to lay
them out?
A: JavaScript does not deal well with forms within tables when <TABLE> tags are nested.
For now, the only solution is to avoid using nested tables.
Q: Is there a way to place the cursor on a particular field when the form is loaded?
A: Yes. You can use the field's focus() method to send the cursor there. The best way to do
this is to use an onLoad event handler and add a slight delay with the setTimeout()
method to allow the page to finish loading.
Chapter 7
Real-Life Examples I
This chapter includes several example JavaScript applications that apply the techniques you
learned in Part II, "Using JavaScript Objects and Forms." These include the following:
One of the things that keeps users coming back to a good Web page is variety-something
different every time they visit. Using JavaScript, you can add a random quotation, a random link,
or a random tip to the page.
For this example, let's display a random quotation at the top of a Web page. This example
illustrates the following techniques:
You will embed the script to generate random quotations in the body of the Web page with the
<SCRIPT> tag. Listing 7.3 is the HTML document, including the JavaScript program.
Note
This script uses the Math.random() method, which wasn't
supported for all platforms until Netscape 3.0b3. Be sure you
try it with the most recent version.
"Mark Twain"; quotes[3] = "The pure and simple truth is rarely pure and never
simple."; authors[3] = "Oscar Wilde"; quotes[4] = "There's no business like show
business, but there are several businesses like accounting."; authors[4] = "David
Letterman"; quotes[5] = "Man invented language to satisfy his deep need to
complain."; authors[5] = "Lily Tomlin"; //calculate a random index index =
Math.floor(Math.random() * quotes.length); //display the quotation
document.write("<DL>\n"); document.write("<DT>" + "\"" + quotes[index] + "\"\n");
document.write("<DD>" + "- " + authors[index] + "\n"); document.write("</DL>\n");
//done </SCRIPT> <HR> The quotation above was generated randomly when
you loaded this page. Reload for another one, or cheat-view the source code and
see them all. <HR> </BODY> </HTML>
This example uses two arrays, quotes and authors, to store the quotations. Notice that an array
can hold more than just numbers-in this case, each array element is a string.
To select a random quotation, you use Math.random() to produce a random number between 0
and 1. You then multiply it by the number of quotations, provided by the length property of the
array, to produce a number in the right range. All this is enclosed in the Math.floor function, which
removes the fractional part of the result.
Figure 7.2 shows the output of this example. Here are a few observations and notes about this
program:
Figure 7.2 : The output of the random quotations example.
• I've used this example to display a random humorous quotation. You could substitute tips
about the current page, short advertisements about the company, or even random links-
you can include HTML within the array elements without causing a problem.
• There are only six quotations in this example-to keep things short. You could easily add
more; just continue with quotes[6] and so on. Be aware that this is within the HTML
source, though, so the more available quotes, the slower the user's access to the page.
Just for fun, I've included a version of this program with over 100 quotations on the CD-
ROM.
• Notice that there are two arrays, one for quotations and one for authors. An object-
oriented alternative is to create a new object with two string properties, then store an
object in each array element. For example, you could create a Quotation object with
author and quote properties. You might find this useful if you have more than two parts
for each of your random items.
The mailto: action is used to submit the data. (Be sure to replace user@host with your e-mail
address.) If the user submits the form and validation is successful, a simple e-mail message is
sent with the information from each of the fields. An example of such a message is shown in
Listing 7.5.
Listing 7.5. The e-mail message sent as a result of the registration form.
username=Michael+Moncur&phone=555-555-2314
&email=guides@starlingtech.com &address=234+Elm+Street &city=Anywhere
%2C+USA+44444 &submit=Submit+Registration
As you can see, this doesn't exactly come back in English. It's even worse than you think-I added
the line breaks in the listing. Nevertheless, you can read the results. Software is also available to
read it automatically.
The encoding in Listing 7.5 is called URL encoding and is used when data is sent to a CGI script.
You'll look at this process in detail in Chapter 17, "Combining JavaScript, CGI, and SSI."
0
0
0
0
0
0
0
0
0
00
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
Chapter 8
Improving a Web Page with JavaScript
Although JavaScript is useful for forms, it can also be useful for an ordinary Web page. It can add
user-friendliness, convenience, and eye-catching gadgets to liven up a page.
In this chapter, you will look at some of the ways JavaScript can improve a Web page. You'll start
with a simple Web page, then add interactive features with JavaScript.
Let's begin with an example of a typical Web page. Once again let's use FSC (the Fictional
Software Company) as an example. FSC has a simple set of Web pages that introduce the
company and include detailed information about each of the products.
Although the FSC pages are functional and include good information about the company and its
products, they're not about to win any awards. In this chapter and the next, you'll learn how
JavaScript can make the page more friendly and exciting.
The main FSC Web page is shown in Figure 8.1. It includes a logo at the top, three paragraphs of
information, and a simple bulleted list of links to the various subpages. This page is defined using
the HTML in Listing 8.1.
The various links on the page send you to the company's other pages. One describes each of the
company's products, another contains information about the company, and another gives
technical support information. A link is also provided to the order form, which was created in
Chapter 6 "Using Interactive Forms."
More recently, FSC decided to add more detailed information to its pages. The main page
remains the same, but each product's page is now a menu of links to subpages with various
categories of information.
As it is, the pages can be difficult to navigate. For example, if you want to view the system
requirements for the Fictional Word Processor product, you must select the product name from
the main page, wait for the page to load, then select the "System Requirements" link.
With JavaScript, you can create a friendly interface to all the pages on the main page-without
taking much space. Let's use one selection list to choose the product and another selection list to
choose the type of information about the product to view.
Note
In this example, the two selection lists stay the same because
each product has the same categories of information available.
You will learn a technique for changing the contents of a
selection list in Chapter 11, "Real-Life Examples II."
In writing a program, the programming isn't always the hardest part. You should define the task
the program will perform and the data it will use in advance; this will make the actual task of
writing the program simple.
In order to make the navigation bar programming task easier, let's choose simple, meaningful
names for each of the subpages. This will make it easy to construct their names based on the
value of the selection lists.
Assign a one-letter code to each product: w for the word processor, s for the spreadsheet, and d
for the database. Then follow that with an underscore and a word indicating the type of
information. Here are the categories of information and their corresponding codes:
For example, s_feat.asp is the features list for the spreadsheet program. Meaningful names like
this are a good idea in any HTML task, because they make it easier to maintain the pages. When
you're automating with JavaScript, they can make a big difference.
Note
To try this example yourself, you'll need all the individual HTML
files. This chapter does not present them, because they're
simple HTML; however, the complete set of files is on the CD-
ROM included with this guide.
Creating the Data Structures and HTML for the Navigation Bar
Before you write the function to navigate the pages, you need to store the needed data. In this
case, you need to store the three codes for the software products and the five codes for types of
pages. You could create an array for each list, but that isn't necessary in this case.
Rather than creating an array, you can simply place the information in the HTML page itself, and
it will be stored in the properties of the form object by the JavaScript interpreter. You will use the
codes as the VALUE attribute of each option.
You will need to define an HTML selection list for each of the lists of information. In addition, the
user needs a way to visit the page after selecting it; you will accomplish this with a "go" button
next to the drop-down lists.
Listing 8.2 shows the HTML to add to the main page. It's included toward the end of the page, but
it's generally self-contained and could be placed anywhere. Chapter 9includes an example of
using this same navigation bar within a separate frame.
Listing 8.2. The HTML to define the table of contents.
<FORM name="navform"> <SELECT name="program"> <OPTION VALUE="x"
SELECTED>Select a Product <OPTION VALUE="w">Fictional Word Processor
<OPTION VALUE="s">Fictional Spreadsheet <OPTION VALUE="d">Fictional
Database </SELECT> <SELECT name="category"> <OPTION VALUE="x"
SELECTED>Select a Category <OPTION VALUE="tech">Technical Support
<OPTION VALUE="sales">Sales and Availability <OPTION VALUE="feat">List
of Features <OPTION VALUE="price">Pricing Information <OPTION
VALUE="tips">Tips and Techniques </SELECT> <INPUT TYPE="button"
NAME="go" VALUE="Go to Page" onClick="Navigate();"> </FORM>
In addition to the categories discussed, I have included an additional option with the value x in
each selection list. These options will display an instructional message to the user. Clicking on
them will do nothing but will provide the user with a hint about using the selection lists. These are
marked as the default selections, so the instructions will be displayed until the user makes a
selection.
Tip
When adding features with JavaScript, don't forget to explain
their use, especially if you are using a technique used in few
other pages. The user shouldn't have to spend any time
figuring out how to use your page.
You defined an onClick event handler for the "go" button, which calls the Navigate() function.
Next, you need to create this function. This function will read the current value of both selection
lists and construct a filename, then load that file in the browser.
Listing 8.3 shows the Navigate() function. You will look at the features of this function in detail
next.
Listing 8.3. The function for navigating based on the selection lists.
function Navigate() { prod = document.navform.program.selectedIndex; cat =
document.navform.category.selectedIndex; prodval =
document.navform.program.options[prod].value; catval =
document.navform.category.options[cat].value; if (prodval == "x" || catval == "x")
return; window.location = prodval + "_" + catval + ".asp"; }
To begin, this function sets two variables, prod and cat, to hold the currently selected index for
each selection list. Next, prodval and catval are assigned to the corresponding value properties.
The if statement checks for the x value, meaning that the user hasn't yet selected an item, in both
lists; if no value has been selected in either list, it returns without doing anything.
Finally, the new document filename is constructed by concatenating the two codes, the
underscore (_), and the html suffix. This value is assigned to the window.location property, which
causes the new page to be loaded.
Note
Because changing the location property loads the new
document, you can't do anything more in the current JavaScript
Your final task is to combine the new navigation form and the Navigate() function with the Web
page HTML. Listing 8.4 shows the revised Web page with the new features, and Figure 8.2
shows how the page looks in Netscape.
Figure 8.2 : The revised Web page with interactive table of contents.
Listing 8.4. (NAVBAR.asp) The complete HTML page with table of contents
feature.
<HTML> <HEAD> <TITLE>Fictional Software Company</TITLE> <SCRIPT>
function Navigate() { prod = document.navform.program.selectedIndex; cat =
document.navform.category.selectedIndex; prodval =
document.navform.program.options[prod].value; catval =
document.navform.category.options[cat].value; if (prodval == "x" || catval == "x")
return; window.location = prodval + "_" + catval + ".asp"; } </SCRIPT> </HEAD>
<BODY> <IMG SRC="fsclogo.gif" alt="Fictional Software Company"> <HR>
Welcome to our web page! Fictional Software Company specializes in creating
innovative, user-friendly software applications with descriptions filled with
industry buzzwords. <P> We have a wide range of products (3 of them) to meet
the needs of you and your company. Follow the links below for more information.
<P> <FORM name="navform"> <SELECT name="program"> <OPTION
VALUE="x" SELECTED>Select a Product <OPTION VALUE="w">Fictional Word
Processor <OPTION VALUE="s">Fictional Spreadsheet <OPTION
VALUE="d">Fictional Database </SELECT> <SELECT name="category">
<OPTION VALUE="x" SELECTED>Select a Category <OPTION
VALUE="tech">Technical Support <OPTION VALUE="sales">Sales and
Availability <OPTION VALUE="feat">List of Features <OPTION
VALUE="price">Pricing Information <OPTION VALUE="tips">Tips and
Techniques </SELECT> <INPUT TYPE="button" NAME="go" VALUE="Go to
Page" onClick="Navigate();"> </FORM> <P> Unlike other software companies,
our products have absolutely no bugs, and always work perfectly on all
computers. Nevertheless, you may run into problems in rare cases, usually your
own fault. If this happens, visit our <A HREF="support.asp">Technical
Support</A> department for helpful information and tips. You can also view more
information <A HREF="company.asp">about our company</A> or order products
with our friendly <a href="order.asp">Order Form</A>. <HR> <I>(c)1998 FSC -
designed by the FSC staff</I> </BODY> </HTML>
Note
The one thing missing in this Web page is a way to navigate
the pages for non-JavaScript browsers. This could easily be
done with normal links; in addition, the form you create could
be used to call a CGI script to perform the same function (but a
bit slower). You'll learn more about combining JavaScript and
CGI in Chapter 17, "Combining JavaScript, CGI, and SSI."
As discussed in Chapter 5 "Accessing Window Elements as Objects," you can change the value
of the window.status property to display a message on the status line. You can use this feature to
add features to a Web page, displaying helpful information about links or about the company.
Normally, as you move the mouse over each link in a Web page, the status line displays the URL
of the link. You can improve on this with JavaScript by displaying a description of the link's
destination instead.
You can accomplish this easily using onMouseOver event handlers. When the user moves the
mouse over a link, this event will call a function to display the appropriate message on the status
line. For example, the following HTML defines a link with a friendly status line:
This simply sets the value of window.status to display the message. In addition, the true value is
returned; this is necessary to override the normal action (displaying the URL) for the status line.
Listing 8.5 shows the result of adding onMouseOver functions to each of the links in the original
version of the FSC Software page. The page is shown in action in Figure 8.3.
Figure 8.3 : Using event handlers to display link information in the status line.
Listing 8.5. (LINKDESC.asp) The FSC page with the addition of friendly
links.
<HTML> <HEAD> <TITLE>Fictional Software Company</TITLE> <SCRIPT>
function message(text) { window.status = text; return true; } </SCRIPT> </HEAD>
<BODY> <IMG SRC="fsclogo.gif" alt="Fictional Software Company"> <HR>
Welcome to our web page! Fictional Software Company specializes in creating
innovative, user-friendly software applications with descriptions filled with
industry buzzwords. <P> We have a wide range of products (3 of them) to meet
the needs of you and your company. Follow the links below for more information.
<P> <UL> <LI><A HREF="spread.asp"
onMouseOver="window.status='Information about the spreadsheet';return true;">
Fictional Spreadsheet 7.0</A> <LI><A HREF="word.asp"
onMouseOver="window.status='Information about the word processor';return
true;"> Fictional Word Processor 6.0</A> <LI><A HREF="data.asp"
onMouseOver="window.status='Information about the database';return true;">
Fictional Database 7.0</A> </UL> <P> Unlike other software companies, our
products have absolutely no bugs, and always work perfectly on all computers.
Nevertheless, you may run into problems in rare cases, usually your own fault. If
this happens, visit our <A HREF="support.asp"
onMouseOver="window.status='Technical Support for our products';return true;">
Technical Support</A> department for helpful information and tips. You can also
view more information <A HREF="company.asp"
onMouseOver="window.status='Information about FSC Software Co.';return
true;"> about our company</A> or order products with our friendly <a
href="order.asp" onMouseOver="window.status='Allows you to order
products';return true;"> Order Form</A>. <HR> <I>(c)1998 FSC - designed by
the FSC staff</I> </BODY> </HTML>
Note
You might be tempted to make a function to avoid using such
long statements as event handlers. Unfortunately, because the
return true statement must be in the event handler itself, it
• The substring of the message, starting at the current position and ending at the end of
the string
• The spacer value
• The rest of the message, starting at the beginning and ending at the current position
It then increments the position indicator pos. If it has reached the end of the string, it resets pos to
zero. Finally, the window.setTimeout() method is used to cause the ScrollMessage() function to
execute again, using a timeout of one-fifth of a second.
This message-scrolling routine works fine, but it suffers from a failing common to most such
routines: it obliterates anything else in the status line. This makes it hard to tell where the links
go-in fact, it defeats the purpose of the friendly link messages created in the previous section.
To fix this, you'll define a new variable, showmsg. This variable will hold a Boolean value, initially
true. When it is set to false, the ShowMessage() function will refrain from showing the message.
Instead, it will set a timeout to show the message later. Here is the revised ShowMessage()
function:
This function sets the showmsg variable to false, then displays the message in the status line. To
call the function, you use an event handler like this:
Tip
As an alternative to scrolling messages, Chapter 11 includes a
routine that displays random, nonscrolling tips, messages, or
advertisements in the status line.
Listing 8.6. (SCROLMSG.asp) The FSC page with the scrolling message
routine.
<HTML> <HEAD> <TITLE>Fictional Software Company</TITLE> <SCRIPT> //
message to scroll in scrollbar var msg = "Welcome to Fictional Software
Company. Watch for a new product coming next month!"; var spacer = "... ..."; //
current message position var pos = 0; //flag to control message var showmsg =
true; function ScrollMessage() { if (!showmsg)
{ window.setTimeout("ScrollMessage()",1500); showmsg = true; return; }
window.status = msg.substring(pos, msg.length) + spacer + msg.substring(0,
pos); pos++; if (pos > msg.length) pos = 0; // set timeout for next update
window.setTimeout("ScrollMessage()",200); } // Start the scrolling message
ScrollMessage(); // Display a link help message function LinkMessage(text)
{ showmsg = false; window.status = text; } </SCRIPT> </HEAD> <BODY> <IMG
SRC="fsclogo.gif" alt="Fictional Software Company"> <HR> Welcome to our web
page! Fictional Software Company specializes in creating innovative, user-
friendly software applications with descriptions filled with industry buzzwords.
<P> We have a wide range of products (3 of them) to meet the needs of you and
your company. Follow the links below for more information. <P> <UL> <LI><A
HREF="spread.asp" onMouseOver="LinkMessage('Information about the
spreadsheet');return true;"> Fictional Spreadsheet 7.0</A> <LI><A
HREF="word.asp" onMouseOver="LinkMessage('Information about the word
processor');return true;"> Fictional Word Processor 6.0</A> <LI><A
HREF="data.asp" onMouseOver="LinkMessage('Information about the
database');return true;"> Fictional Database 7.0</A> </UL> <P> Unlike other
software companies, our products have absolutely no bugs, and always work
perfectly on all computers. Nevertheless, you may run into problems in rare
cases, usually your own fault. If this happens, visit our <A HREF="support.asp"
onMouseOver="LinkMessage('Technical Support for our products');return true;">
Technical Support</A> department for helpful information and tips. You can also
view more information <A HREF="company.asp"
onMouseOver="LinkMessage('Information about FSC Software Co.');return
true;"> about our company</A> or order products with our friendly <a
href="order.asp" onMouseOver="LinkMessage('Allows you to order
products');return true;"> Order Form</A>. <HR> <I>(c)1998 FSC - designed by
the FSC staff</I> </BODY> </HTML>
There are some disadvantages to using the status line to display scrolling messages. For one
thing, the user may want to view URLs rather than your descriptions. Also, the browser uses it to
display status when loading documents.
Finally, the status line is at the bottom of the page-hardly the place for an important
announcement. Some users habitually ignore the status line, and may not even see your
message.
To solve these problems, you can use a text field as an alternative to the status line. You can
display help for links in such a field or use it to scroll a message.
Changing the ScrollMessage() function to use a text field instead of the status line requires only a
minor change. Here is the revised function:
function ScrollMessage() { document.form1.text1.value = msg.substring(pos,
msg.length) + spacer + msg.substring(0, pos); pos++; if (pos > msg.length) pos =
0; // set timeout for next update window.setTimeout("ScrollMessage()",200);
}
You are now placing the current message value in the value property of the text1 form element.
Notice that the check for the showmsg variable is no longer necessary, because the scrolling
message will not conflict with the link descriptions (which are still in the status line).
You define the text field (in its own little form) with the HTML:
<FORM name="form1"> <INPUT TYPE="text" name="text1" SIZE="60">
</FORM>
One more change is necessary. Because the form1 element doesn't actually exist until it is
defined in the Web page, you can no longer start the scrolling in the <HEAD> section of the
document. It must start after the page is loaded.
An easy way to accomplish this is with the document's onLoad event handler. You use the
following <BODY> tag to start the document and define the event handler:
<BODY onLoad = "ScrollMessage();">
Note
One disadvantage of using a text field in this way is that the
user can modify the value. However, because you're updating
the field every fifth of a second, the user can't affect it much.
Listing 8.7 integrates the new function and the text field into the FSC home page. The status line
is still used to display help about each of the links. Figure 8.5 shows Netscape's output of this
page.
Figure 8.5 : Netscape shows the FSC home page with the scrolling text field.
Listing 8.7. (SCROLTXT.asp) The FSC page with the scrolling text field
routine.
<HTML> <HEAD> <TITLE>Fictional Software Company</TITLE> <SCRIPT> //
message to scroll in text field var msg = "Welcome to Fictional Software
Company. Watch for a new product coming next month!"; var spacer = "... ..."; //
current message position var pos = 0; //flag to control message function
ScrollMessage() { document.form1.text1.value = msg.substring(pos, msg.length)
+ spacer + msg.substring(0, pos); pos++; if (pos > msg.length) pos = 0; // set
timeout for next update window.setTimeout("ScrollMessage()",200); } // Display a
link help message function LinkMessage(text) { window.status = text; }
</SCRIPT> </HEAD> <BODY onLoad = "ScrollMessage();"> <IMG
SRC="fsclogo.gif" alt="Fictional Software Company"> <FORM name="form1">
<INPUT TYPE="text" name="text1" SIZE="55"> </FORM> Welcome to our web
page! Fictional Software Company specializes in creating innovative, user-
Workshop Wrap-Up
In this chapter, you learned some of the ways a Web page can be improved by using JavaScript,
including the following:
• Using selection lists to create a table of contents to make the page easy to navigate
• Using the status line to display information about links rather than the URLs
• Using the status line to display a scrolling message, and using a text field as an
alternative for the purpose
Next Steps
To continue your studies of JavaScript, move on to one of the following chapters:
• To learn the specifics about the objects and window elements used in this chapter, see
Chapter 5 "Accessing Window Elements as Objects."
• To continue improving a Web page, this time using advanced features such as frames,
see Chapter 9 "Using Frames, Cookies, and Other Advanced Features."
• To learn some techniques for organizing a larger and more complicated Web site, see
Chapter 10, "Working with Multiple Pages and Data."
• To see some more real-world examples of the techniques in this chapter, see Chapter
11, "Real-Life Examples II."
Q&A
Q: What's wrong with the many popular scrolling message routines available on the
Web?
A: Most of them are victims of the memory leak bug in Netscape, because they reassign a
string every time the text in the status bar moves. The example in this chapter avoids
this problem. See Chapter 14, "Debugging JavaScript Programs," for details.
Q: Is there any way to use some kind of "floating hints" or "balloon help" with links
instead of using the status bar?
A: Not currently. This may be added in some fashion in a future implementation of
JavaScript.
Q: Can the navigation bar in this chapter be used with browsers that don't support
JavaScript?
A: Yes. You could easily modify it to send the selections to a CGI script, which could send
the user to the correct page. You'll take a closer look at CGI in Chapter 18.
Chapter 9
Using Frames, Cookies, and Other Advanced Features
In this chapter, you'll continue to revise the FSC Web pages created in Chapter 8 moving on to
features found in the latest browsers- specifically, the latest version of Netscape. Features such
as frames and cookies enable you to add unique capabilities to a JavaScript-enhanced page.
Although Netscape version 3.0 is the current version at this writing, most of the features
discussed in this chapter were introduced in version 2.0, which also introduced JavaScript.
Note
At this writing, Microsoft has released a beta version of version
3.0 of its Internet Explorer (MSIE) Web browser. This release
supports frames and cookies, along with much of JavaScript.
Frames
Netscape introduced frames in version 2.0. Recall that frames, also called framesets, are used to
divide a Web page's display into multiple sections, each of which can display a different
document or portion of a document. Frames are becoming a popular feature in Web pages and
are already supported by some non-Netscape browsers.
An example of a document that uses frames is Netscape's JavaScript Authoring Guide, shown in
Figure 9.1. The window is divided into three frames: a frame on the left with the table of contents,
one on the right with the actual text, and a small strip on the bottom with two buttons used for
JavaScript functions.
Figure 9.1 : Netscape's JavaScript Authoring Guide is an example of a document that uses
frames.
Each frame acts as a separate window; it has its own URL. Each frame can also have horizontal
and vertical scrollbars. The user can move the dividing lines to resize the different frames. You
can enable and disable scrollbars and resizing through HTML attributes.
Defining a Frameset
You use the <FRAMESET> tag to define a framed document. This tag is used instead of the
<BODY> tag. The page with the <FRAMESET> declaration defines the layout of the different
frames and which documents are loaded into them, but contains no actual data-the contents of
each frame are at their own URLs.
The frame definition begins with the <FRAMESET> tag and ends with the closing
</FRAMESET> tag. Within these tags you can't use any ordinary HTML; you can use only tags
and attributes that define frames. You can also nest a frameset within another frameset.
The <FRAMESET> tag has two attributes: ROWS and COLS. These define how the window is
divided. You can use either of these attributes or both. Both of these attributes have the same
value, which is a list of dimensions for each row or column. You can define the rows or columns
in the following ways:
• Specify a numeric value to define the size of a row or column in pixels. For example,
"40,40,40" defines three frames, each 40 pixels in size. Note that Netscape will expand
the frames to fill the browser window, though.
• Specify a percentage value to allocate a percentage of the window. For example,
"20%,40%,40%" allocates 20 percent of the window to the first frame and 40 percent to
the other two.
• Specify a relative value with the asterisk (*) character. For example, "*,*,*,*" divides a
page evenly into four frames. You can specify a number to give a frame more than one
share; for example, "1*,2*" creates two frames, one with 1/3 of the space and the other
with 2/3.
Note
It is considered bad style to specify an exact number of pixels
for a frame except in certain cases. Users may have different
window sizes and different fonts, and you will end up annoying
some users. One exception is when you are using a frame to
display an image, such as a logo or navigation icons. You can
then set the frame size to fit the image exactly.
You can combine the different methods any way you like; in fact, this is almost always the best
way to define a frameset. The following examples will give you some ideas of how these can be
combined:
• <FRAMESET ROWS="30,*"> devotes 30 rows of pixels to the first frame (for a navigation
bar image, perhaps) and the remaining space to the second frame.
• <FRAMESET COLS="50%,25%,*"> splits the screen vertically into three frames. The first
uses 50 percent of the available space, the second uses 25 percent, and the third uses
the remaining space (25 percent).
• <FRAMESET ROWS="*,*,50"> splits the screen horizontally. The bottom frame is exactly
50 pixels high, and the top two frames divide the remaining space equally.
• <FRAMESET ROWS="*,*" COLS="*,*"> splits the screen into four equally spaced
frames.
Note
Notice that you are not required to define a value for the
number of frames in the frameset. This value is calculated
based on the number of values in the ROWS and COLS lists.
The first frame takes 10 percent of the available space, and the second and third divide the
remaining space equally, giving them 45 percent each. The third frame includes a left and right
margin of 50 pixels. Figure 9.2 shows how this set of documents looks in Netscape.
Figure 9.2 : An example of a framed document with three horizontal frames.
Note
One common mistake is to assume that browsers that support
frames also support JavaScript. Some Web authors have used
<NOFRAMES> to weed out non-JavaScript browsers. There
are now several browsers that support frames but not
JavaScript, so this is not reliable. The <NOSCRIPT> tag,
introduced in Netscape 3.0b4, provides a solution.
You will look at some of these uses later in this chapter; you will also use frames in many of the
applications created in the upcoming chapters.
Targeted Links
Because you can display multiple documents in a window with frames and multiple windows, you
need a way to specify which window or frame to use. The TARGET property enables you to do
this.
The TARGET property is used in links, and it indicates the window or frame in which the
document will be displayed. This is the name you assigned using the NAME attribute of the
<FRAME> tag. For windows you create in JavaScript, this is the window reference you specified
when creating the window.
For example, this link will open the order.asp document in the win1 frame or window:
<A HREF="order.asp" TARGET="win1">Order form</A>
If the window doesn't already exist, a new window will be created with the document loaded. For
example, this link creates a new window called win2 and loads the support.asp document into it:
<A HREF="support.asp" TARGET="win2">Technical Support</A>
Another tag, <BASE>, enables you to define a default target window for a document. This target
will be used for all links in the document except those with a differing TARGET property of their
own. This statement sets the default target to win2:
<BASE TARGET="win2">
This is particularly useful for a frame that will be used as a navigation bar or table of contents,
because you will want every link in the document to load in a different frame.
Note
As mentioned in Chapter 6 "Using Interactive Forms," the
<FORM> tag can also have a TARGET property. In this case,
it defines which window or frame will be used to display the
results after the form is submitted.
Cookies
In CGI programming, one of the most vexing problems is storing state information. When users
go from one page to the next, it's hard to keep track of what they were doing, or even if they are
the same users.
Netscape created cookies as one solution to this problem. A cookie is a chunk of information sent
by the server, which can be stored on the client. Cookies are stored with a date they expire and
the name of the host from which they came. When the user communicates with the same host
later, the data is sent back.
Here are some examples where cookies can be useful:
• They can store a user's "preferences" for a Web page. When users return to the page,
they can view it in their desired fashion. For example, Netscape's home page uses this
technique to turn frames on or off based on the user's preference.
• They can maintain state between CGI scripts or JavaScript programs. For example, a
quiz might ask you one question, then load a new page for the next question, storing your
score in a cookie.
• They can remember information so that users can avoid entering it every time they
access a page. For example, a page that requires a user's name can remember it with a
cookie.
Cookies can also be used in JavaScript. You can use them to store information between pages,
or even to store information on users' computers to remember their preferences next time they
load your page.
Each cookie stores a named piece of information and includes an expiration date. With few
exceptions, this date is usually one of the following:
• When used to store preferences, a faraway date is usually used-in essence, it never
expires.
• When used to maintain state, a date in the near future-typically the next day-is used. In
the previous quiz example, a user that came back the next day would have to start the
quiz over.
The cookies are stored in a "cookie jar" on the user's computer. Specifically, each cookie is a line
in a file called cookies.txt, usually in the same directory as Netscape itself.
Plug-Ins
One feature added by Netscape surpasses even frames: the plug-in specification. This is an
Application Program Interface (API) that enables programmers to create add-ons for Netscape.
These are typically used to enable the browser to view non-HTML data.
Plug-ins are available for a wide variety of formats, and more are coming out every day. You can
use plug-ins to display new kinds of images, animations, video, and 3D graphics directly in the
browser window.
Because plug-ins are all about multimedia and bring many new media formats to
the Web, you'll explore them in detail in Chapter 13, "Working with Multimedia and Plug-Ins."
Note
You can't write plug-ins with JavaScript, but there are features
to enable you to control and interact with them using
JavaScript.
This simply divides the window into quarters. If you have a JavaScript program in the topleft.asp
file, it would refer to the other windows as parent.topright, parent.bottomleft, and so on. The
keywords window and self would refer to the topleft frame.
Note
If you use nested framesets, things are a bit more complicated.
Window still represents the current frame, parent represents
the frameset containing the current frame, and top represents
the main frameset that contains all the others.
parent.TimeFrame.document.open();
parent.TimeFrame.document.write("<HTML><BODY><CENTER><FONT
SIZE='+35'>"); parent.TimeFrame.document.write(hh + ":" + mm + ":" + ss);
parent.TimeFrame.document.writeln("</H1></BODY></FONT>");
parent.TimeFrame.document.close(); // set the next timeout
window.setTimeout("Update();",5000); } </SCRIPT> </HEAD> <BODY> The
above frame displays the time, which is updated once every 5 seconds after you
load this page. The frame is updated with the <b>document.open()</b> and
<b>close()</b> methods in JavaScript. </BODY> </HTML>
This document includes the Update() function, which updates the clock by rewriting the
TimeFrame frame's contents. The document.open() and document.close() methods used to
accomplish this are explained in Chapter 5. Figure 9.5 shows this example in action.
Figure 9.5 : The output of the frame update example.
• name=value: A name and value, separated by the equal sign. This is the actual data
stored in the cookie.
• expires=date: An expiration date. If this date is not included, the cookie is erased when
the user exits the browser. (For the format of the date, see the example later.)
• domain=machine: The domain name for which the cookie is valid. By default, this is the
domain of the current page.
• path=path: The URL path for which the cookie is valid. By default, this is the current URL.
As an example, Listing 9.9 shows a document that remembers the name of each user who
accesses it. Each section of the document is explained later.
Listing 9.9. (COOKIE.asp) An example of cookies in JavaScript.
<HTML> <HEAD> <TITLE>The page that remembers your name</TITLE>
<SCRIPT> if (document.cookie.substring(0,2) != "n=") { nam =
window.prompt("Enter your name"); document.cookie = "n=" + nam + ";";
document.cookie += "expires=Tuesday, 31-Dec-99 23:59:00 GMT" } </SCRIPT>
</HEAD> <BODY> <H1>Here is Your name</H1> <HR> <SCRIPT> indx =
document.cookie.indexOf(";"); nam = document.cookie.substring(2,indx+1);
document.write("Hello there, ", nam); </SCRIPT> <P> next paragraph </BODY>
</HTML>
The script in the document header simply checks the name portion of the cookie string for the n=
characters. If they are not found, it prompts for the user's name, and stores the value in the "n="
cookie. A faraway expiration date is used to save the information indefinitely.
The script in the body of the document is then able to greet the user by displaying a name, if one
has been defined. The output of this page is shown in Figure 9.6. Obviously, there are more uses
for cookies than just names. You will explore another use in Chapter 11.
Figure 9.6 : The output of the JavaScript cookie example.
Workshop Wrap-Up
In this chapter, you continued the process of adding interactive features to a company Web page
with JavaScript, taking advantage of the latest browser features:
• The most important feature you can use with JavaScript is frames, which enable you to
divide a window into multiple areas. You can use frames to create separate navigation
bars, status areas, and many other useful divisions.
• You can use cookies to store information about the user or the current session. This can
be useful for keeping state between different documents and for storing user preferences.
Next Steps
You have now expanded your knowledge of JavaScript to include frames and cookies, and you
should have an idea of the possibilities they offer. Move on with one of the following:
• To review the JavaScript objects referred to in this chapter and their uses, see Chapter 5
"Accessing Window Elements as Objects."
• To learn various ways to liven up a page without frames, see Chapter 8 "Improving a
Web Page with JavaScript."
• To learn how to use frames and cookies in more complicated ways, turn to Chapter 10,
"Working with Multiple Pages and Data."
• To see more examples of the techniques in this chapter, see Chapter 11, "Real-Life
Examples II."
• To learn more about Netscape plug-ins, see Chapter 13, "Working with Multimedia and
Plug-Ins."
Q&A
Q: How do frames and cookies fit into the HTML standards, if at all?
A: Frames have been proposed as an extension to HTML, but have not been implemented
in the latest version (HTML 3.2). You can bet they will become a standard, with both
Netscape and Microsoft behind them. Cookies have not yet been discussed as an
addition to HTML.
Q: Is there any way for a user to access information stored in a cookie by a previous
user?
A: No. Cookies are stored on the user's machine, so each user has a separate database.
There is no way to send this data to the server with JavaScript.
Q: Can I modify the frameset "on the fly"-for example, adding a new frame or
eliminating an existing one?
A: Not without loading a different frameset. JavaScript has no capability of changing
framesets, at least in the current version.
Q: Can I call a function I defined in a different frame's document?
A: Yes. JavaScript functions are properties of the window object, so you can specify the
window and document when you call the function, such as parent.frame2.Update().
Listing 9.7 uses this technique.
Q: Nobody takes me seriously when I talk about cookies. Who at Netscape can I
blame for creating a silly term like that?
A: Netscape is innocent in this case. The terms "cookie" and "cookie jar" have been used
for years in the computer industry to represent named bits of information, usually stored
in a computer's memory.
Chapter 10
Working with Multiple Pages and Data
In this chapter, you'll look at some of the more complex capabilities of JavaScript. You learned
the basics of using frames in Chapter 9, "Using Frames, Cookies, and Other Advanced
Features;" you'll look at some more sophisticated examples here. You'll also explore techniques
for storing data and learn about the data tainting feature, which enables you to overcome some of
Netscape's security restrictions.
HREF="word.asp"
onMouseOver="parent.description.document.form1.text1.value='Information
about the word processor';return true;"> Fictional Word Processor 6.0</A>
<LI><A HREF="data.asp"
onMouseOver="parent.description.document.form1.text1.value='Information
about the database';return true;"> Fictional Database 7.0</A> </UL> <HR>
<I>(c)1998 FSC - designed by the FSC staff</I> </BODY> </HTML>
The third frame is an image map, which can be used for navigation. It uses event handlers to
place informative messages in the text field in the fourth frame. Listing 10.3 shows the image map
document.
Listing 10.3. (MAP.asp) The image map document for the nested frames
example.
<HTML> <BODY> <MAP NAME="map1"> <AREA SHAPE=RECT
COORDS="6,7,61,43" HREF=support.asp
onMouseOver="parent.description.document.form1.text1.value='Support for our
products';return true;"> <AREA SHAPE=RECT COORDS="73,8,129,42"
HREF=compinfo.asp
onMouseOver="parent.description.document.form1.text1.value='About our
Company';return true;"> <AREA SHAPE=RECT COORDS="140,7,200,42"
HREF=order.asp
onMouseOver="parent.description.document.form1.text1.value='Order
Products';return true;"> <AREA SHAPE=RECT COORDS="211,6,276,43"
HREF=customer.asp
onMouseOver="parent.description.document.form1.text1.value='Customer
Service';return true;"> <AREA SHAPE=default HREF=fscmain2.asp> </MAP>
<IMG SRC="fscmap.gif" USEMAP="#map1"> </BODY> </HTML>
Finally, the fourth frame contains a simple text field, which is used in place of the status bar to
display descriptions as the user moves over links. Listing 10.4 shows this document.
Listing 10.4. (DESCRIP.asp) The description text field document for the
nested frames example.
<HTML> <BODY> <FORM NAME="form1"> <INPUT TYPE="TEXT"
NAME="text1" SIZE="40" VALUE="Look Here for help."> </BODY> </HTML>
This is a good example of how complicated frames programming can get. Both the middle frame
and the image map frame address the text field in the fourth frame to display descriptions. The
final document, as displayed in Netscape, is shown in Figure 10.1.
The first technique may seem simple, but it's often overlooked. Because a JavaScript variable
can hold any type of data, it can be used as a string array. For example, the following code
creates a three-element string array and assigns values to its elements:
strings = new Array(3); strings[0] = "This is the first element."; strings[1] = "This is
the second element."; strings[2] = "This is the third element.";
Each element of the array can be used as an ordinary string object. For example, this statement
displays a substring from the third element of the array defined previously:
document.write(strings[2].substring(5,10));
Tip
The solitaire game in Chapter 15, "Real-Life Examples III,"
uses several of these techniques to store information about the
cards in use.
The fix in Netscape 2.02 was to prevent a document from accessing properties of another
document, unless it came from the same server. Thus, if your document loaded Netscape's home
page in a frame, it couldn't access the links, anchors, or even the address of the Netscape page.
Although the fixed version prevented these problems, it also removed a useful feature. If you
could access properties of a document in another frame, for example, you could create a "link
summary" frame with a quick reference to all the links on the page.
Luckily, Netscape found a solution to make everyone happy, beginning with Navigator 3.0b5,
which introduced data tainting. This enables you to access properties of a document in another
frame, but not without evidence.
As an analogy, consider the security devices used in a modern record or video store. The simple
solution to prevent theft is to keep all the items in locked cabinets, but that would prevent
customers from browsing them. Instead, magnetic strips are attached to each item, and can't be
removed. Thus, you can take an item off the shelf and look it over-but come near the exit, and
alarms go off all over the place.
Data tainting does the same thing for data from other servers. Data from another server is
marked, or tainted. The data is still useful, but it is marked. No matter what you do with the data-
assign it to variables, use it in calculations, and so on-it remains tainted.
When a JavaScript program attempts to send data to a server-either by submitting form data or
by using an URL-it is checked for tainting. If any tainted data is present, the user is alerted and
allowed to cancel the operation.
Note
To send data to a server using an URL, the application could
use the data as a document name or as a parameter. In either
case, a CGI script could receive the data on the server.
The actual tainting is done by using a special taint code in storing the value. The taint code is
unique for each server. Thus, you can freely send data to the same server it was originally taken
from, but the user is warned if you attempt to send it to a different server.
Note
When data tainting is enabled, you can also access the value
of password objects in a form. Because their value is tainted,
though, you can't send this information to a server.
• taint adds taint to a value, using the current program's taint code.
• untaint removes the taint from a value.
These functions return a tainted or untainted result, but do not modify the original value. The main
use for untaint is to make values available to other scripts without security restrictions.
Note
Although you can add taint to any value with taint(), you can
only untaint values that have the current program's taint code.
There is no way to remove taint from a value that originates
from another window.
Listing 10.6. (LINKSUMM.asp) The main HTML document for the link
summary JavaScript application.
<HTML> <HEAD> <TITLE>Link Summary</TITLE> <SCRIPT
LANGUAGE="JavaScript"> function newloc() { // send other frame to new URL
parent.frames[1].location.href = document.form1.text1.value; // update link
summary self.location.reload(); } </SCRIPT> </HEAD> <BODY> </BODY>
<H3>Link Summary</H3> <HR> <FORM NAME="form1"> <INPUT TYPE="text"
NAME="text1" VALUE="enter new URL"> <INPUT TYPE="button" VALUE="GO"
onClick="newloc();"> </FORM> <SCRIPT LANGUAGE="JavaScript"> // list links
in other frame len = parent.frames[1].document.links.length;
document.write("<B>Total links: " + len + "</B>"); // begin numbered list
document.write("<BR>\n<OL>"); // reproduce each link here for (i=0; i < len; i++) {
document.write("<LI><A HREF='");
document.write(parent.frames[1].document.links[i].href); document.write("'>");
document.write(parent.frames[1].document.links[i].pathname);
document.write("</A>\n"); } document.write("</OL>"); </SCRIPT> <HR>
</HTML>
This is where the real action happens. The JavaScript functions in this document create a
summary of the links in the second document. The links are listed in a numbered list, with each
linked to its corresponding document name.
Of course, when you first load the document, there will be no document in the second frame. You
can use the text field and form in the link summary frame to load a new document, and the link
information will be displayed.
Thanks to data tainting, this should work with any Web document. It will not currently work with
framed documents, because it hasn't provided for multiple frames. The output of this program, as
displayed by Netscape, is shown in Figure 10.2. In the figure, I've loaded Netscape's page, and
the links on the page are listed.
Figure 10.2 : The output of the link summary, application.
Creating a Questionnaire
As a complex example of using frames to keep track of state between pages, let's create a
questionnaire. This program asks several questions; after you answer each question, it stores the
answer in an array. The array is part of the script in the top frame; the bottom frame is used to
show the questions. The frameset document for this example is shown in Listing 10.7.
Listing 10.7. (QUIZ.asp) The frameset document for the questionnaire.
<HTML> <FRAMESET ROWS="15%,*"
onLoad="setTimeout('parent.MainFrame.NextQuestion();',1000);"> <FRAME
NAME="MainFrame" SRC="quizmain.asp"> <FRAME NAME="QuizFrame"
SRC="doc1.asp"> </FRAMESET>
Listing 10.8 shows the main program for the questionnaire. When you load the page, the
questions are asked one at a time. After the last question, a summary of your answers is
displayed. The final output of this program is shown in Figure 10.3.
Figure 10.3 : The questionnaire is complete, and the results are displayed.
Listing 10.8. (QUIZMAIN.asp) The main JavaScript program for the quiz
example.
<HTML> <HEAD><TITLE>Questionnaire Example</TITLE> <SCRIPT
LANGUAGE="JavaScript"> // global variables var answers = new Array(5); var
questions = new Array(5); questions[0] = "What is your name"; questions[1] =
"What is your age"; questions[2] = "What is your phone number"; questions[3] =
"How many beans make 5"; var current = 0; var quest; // function to ask a
question in other frame function NextQuestion() { if (current > 0) { ans =
parent.QuizFrame.document.form1.question.value; answers[current-1] = ans; } if
(current + 1 < questions.length) { text = questions[current];
parent.QuizFrame.document.open();
parent.QuizFrame.document.write("<HTML><BODY>\n");
parent.QuizFrame.document.write("<h1>" + "Question #" + current + "</ h1>");
parent.QuizFrame.document.write("<hr>");
parent.QuizFrame.document.write("<b>" + text + "?</b><br>");
parent.QuizFrame.document.write("<FORM NAME=\"form1\">\n");
parent.QuizFrame.document.write("<INPUT TYPE=\"text\" NAME=\"question\">
"); parent.QuizFrame.document.write("<BR><INPUT TYPE=\"BUTTON\"
VALUE=\"Submit Answer\" ");
parent.QuizFrame.document.write("onClick=\"parent.MainFrame.NextQuestion();
\" >"); parent.QuizFrame.document.write("</BODY></HTML>");
parent.QuizFrame.document.close(); current++; } else
{ parent.QuizFrame.document.open();
parent.QuizFrame.document.write("<HTML><BODY>\n");
parent.QuizFrame.document.write("<h1>Your answers:</h1><hr>"); for (i=0;
i<(questions.length-1); i++) { parent.QuizFrame.document.write("<B>" +
This program uses the questions array to store the questions and the answers array to store the
user's answers. When the page is loaded, the NextQuestion() function is called to display a
question.
Each question is displayed in the bottom frame. The document you create in this frame also has a
JavaScript event handler, which calls the NextQuestion() function (in the top frame) when the
question is entered.
Workshop Wrap-Up
In this chapter, you learned some of the more complex aspects of JavaScript and how it can work
with complicated pages and data:
• How to integrate documents in nested frames and refer between them
• How to store data with string arrays and associative arrays
• How to use the data tainting feature to access properties of pages from different servers
• How to use frames to store the current state of a JavaScript application and keep track of
variables between pages
Next Steps
When you master the techniques in this chapter, you've come a long way toward becoming a
JavaScript expert. Continue your studies with one of the following:
• For simpler examples of using frames in Web pages, turn to Chapter 9 "Using Frames,
Cookies, and Other Advanced Features."
• For examples that illustrate the techniques you learned in this chapter, see Chapter 11,
"Real-Life Examples II."
• To learn techniques for debugging JavaScript applications, see Chapter 14, "Debugging
JavaScript Programs."
• To learn about using Java to further enhance your page, turn to Chapter 16, "Integrating
JavaScript with Java."
Q&A
Q: Using data tainting, I can access properties of another document, such as links
and anchors. Is there any way to read the HTML source of the document itself?
A: Currently, there is no way to do this. The properties made available in the object
hierarchy (explained in Chapter 5 "Accessing Window Elements as Objects") are all you
can access via JavaScript. This is not expected to change.
Q: Can a JavaScript program in one frame read variables (not properties) defined by
a JavaScript program in another frame?
A: Yes. Just treat the variable name as a child of the frame's window object. For example,
parent.frame1.score refers to the score variable in the frame1 frame.
Q: What happens if the document I load into a frame is a framed document itself? Will
0
0
0
0
0
0
Chapter 11
Real-Life Examples II
This chapter includes several example JavaScript applications that apply the techniques you
learned in Part III, "Creating Smart Web Pages." These include the following:
• Example 1: Nonscrolling Status Line Messages: A different idea for displaying
messages in the status line
• Example 2: An Improved Navigation Bar: Using dynamically changed selection lists to
allow the user to select a specific page
• Example 3: Storing User Preferences: A page that remembers a user's preference and
shows either the frames or no-frames version
Note
This program uses the Math.random() method, which was fully
implemented in Netscape 3.0b3, although it worked in earlier
UNIX versions. Be sure you're using the latest version to try
this example.
This program is shown in action in Figure 11.1. I hope this not only gives you an alternative way
of displaying messages, but the inspiration to come up with new and creative ways of your own.
Figure 11.1 : Netscape's display of the nonscrolling message example.
As you can see, this is a much more interactive use of JavaScript-and a more practical one
because you will rarely have exactly the same list of pages for each product. This could easily be
adapted for a wide variety of uses.
Figure 11.2 shows this example in action. Here are a few observations about this program:
• The technique of changing selection lists was added in Netscape 3.0b4. This may not be
available to all your users, and it will cause an error on earlier versions.
• Notice that although you change the list of categories, there are always four of them. I did
this to keep things simple; you could also add and delete options. To add an option, use
the Option() constructor to create a new object, assign its text property, and assign it to
the last element of the options array. To delete items, assign their place in the array to
null, starting at the end of the options array.
• Notice that you change the first option of the category when a product is selected, to
prompt the user and indicate the selection. This makes it a bit more friendly than the
original navigation bar.
• There may be problems if you try to assign a value to a selection list's text property that is
longer than the value it replaces, because Netscape allocates space for the list when the
page is first displayed. A solution is to be sure that one of the original options is longer
than any others you will use, or explicitly refresh the page with the location.reload()
method.
This example is a useful application for cookies (Chapter 9). You will use a cookie to indicate the
user's preference and either display a frames or no-frames version of the page.
This program attempts to read the cookie for the current document with the document.cookie
property. If it contains the keyword "frames=yes", the user will be sent to the frames version;
otherwise, the user is sent to the no-frames page. (Thus, no frames is the default.)
Next, you will need the actual framed and non-framed pages. Listing 11.4 shows the page for the
frames version, which includes an option to switch to the no-frames version.
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
Chapter 12
Working with Graphics in JavaScript
One of the most challenging-and most rewarding-uses of a programming language is creating
graphic applications and games. In this chapter you'll look at some techniques you can use for
graphic pages-or to add excitement to any Web page.
Now don't get too excited-JavaScript is a young language, and a simple one, so it will be quite a
while before someone writes a version of DOOM in JavaScript. However, you can create uniquely
dynamic Web content. JavaScript includes several features, including dynamic images, that aren't
even available in Java.
You will explore some simple examples of these techniques in this chapter. For an example of a
large-scale graphic application-in this case, a poker solitaire game-see Chapter 15, "Real-Life
Examples III."
This technique isn't perfect for all applications. Before you get started, note the following
limitations:
• You can only change existing images in the page-you can't add new ones or remove an
image entirely.
• You can replace an image with a larger or smaller image, but this may not look good,
because the text won't be reformatted to match.
• Any image you use will have to be loaded from the server; this makes this technique
impractical for complicated animations or large images.
• border represents the BORDER attribute of the <IMG> tag; this defines whether a border
is drawn around a linked image.
• complete is a flag that tells you whether the image has been completely loaded. This is a
Boolean value (true or false).
• height and width reflect the corresponding image attributes. This is for information only;
you can't change an image's size dynamically.
• hspace and vspace represent the corresponding image attributes, which define the
image's placement on the page. Again, this is a read-only attribute.
• name is the image's name. You can define this with the NAME attribute in the image
definition.
• lowsrc is the value of the LOWSRC attribute. This is a Netscape-specific attribute that
enables you to specify a low-resolution image to be loaded before the "real" image.
• src is the image's source, or URL. This is the value you can change to change images
dynamically.
For most purposes, the src attribute is the only one you'll use. However, you can also change the
lowsrc attribute. This defines a low-resolution image to load first and will be used only when you
change the src attribute.
The image object has no methods. It does have three event handlers you can use:
Preloading Images
Although you can't add an image to the page dynamically, you can create an independent image
object. This enables you to specify an image that will be loaded and placed in the cache, but not
displayed on the page.
This may sound useless, but it's a great way to work with modem-speed connections. Once
you've preloaded an image, you can replace any of the images on the page with the image-and
because it's already cached, the change happens instantly.
You can cache an image by creating a new image object, using the new keyword. Here's an
example:
Image2 = new Image(); Image2.src = "arrow1.gif";
Note
The new keyword, and its other uses for object-oriented
programming, are described in Chapter 4 "Using Built-In
Objects and Custom Objects."
Tip
You might be tempted to speed up the timer in this example
and use it for animation. This will work, but only if you preload
each image first. In addition, JavaScript animations aren't very
fast. You may want to look into
GIF animations, which provide a good alternative. See
appendix C, "Online JavaScript Resources," for more
information
Note
Several shareware programs enable you to create image maps
without hassle. One of them, Map This!, is included on the CD-
ROM accompanying this guide.
Listing 12.5 shows the example client-side image map definition. This uses both javascript: links
and event handlers to perform functions. Rather than link to an actual page, clicking on the areas
will display a message in a text field (see Figure 12.5). In addition, the onMouseOver event
handlers display a description in the status line for each area.
Figure 12.5 : An example of an image map in JavaScript.
Listing 12.5. (IMAGEMAP.asp) Using a client-side image map with
JavaScript.
<HTML> <HEAD> <TITLE>Image Map Example</TITLE> <SCRIPT
LANGUAGE="JavaScript"> function update(text) { document.form1.text1.value =
text; } </SCRIPT> </HEAD> <BODY> <MAP NAME="map1"> <AREA
SHAPE=RECT COORDS="14,15,151,87" HREF="javascript:update('service');"
onMouseOver="window.status='Service Department'; return true;"> <AREA
SHAPE=RECT COORDS="162,16,283,85" HREF="javascript:update('sales');"
onMouseOver="window.status='Sales Department'; return true;"> <AREA
SHAPE=RECT COORDS="294,15,388,87" HREF="javascript:update('info');"
onMouseOver="window.status='Information'; return true;"> <AREA
SHAPE=RECT COORDS="13,98,79,178" HREF="javascript:update('email');"
onMouseOver="window.status='Email Us'; return true;"> <AREA SHAPE=RECT
COORDS="92,97,223,177" HREF="javascript:update('products');"
onMouseOver="window.status='Products'; return true;"> <AREA SHAPE=RECT
COORDS="235,98,388,177" HREF="javascript:update('our staff');"
onMouseOver="window.status='Our Staff'; return true;"> <AREA SHAPE=default
HREF="javascript:update('No item selected.');"
onMouseOver="window.status='Please select an item.'; return true;"> </MAP>
<h1>Client-Side Image Map Example</h1> <hr> The image map below uses
JavaScript functions in each of its areas. Moving over an area will display
information about it in the status line. Clicking on an area places the name of the
area in the text field below the image map. <hr> <IMG SRC="imagemap.gif"
USEMAP="#map1"> <hr> <FORM NAME="form1"> <b>Clicked Item:</b>
<INPUT TYPE="text" NAME="text1" VALUE="Please select an item."> </FORM>
<hr> </BODY> </HTML>
This program uses a single JavaScript function called update(); this function simply places an
item in the text field form1.text1. The text is sent directly by the link in each area definition.
Workshop Wrap-Up
In this chapter, you explored several uses of JavaScript in working with graphics, and you learned
the following:
• How to create graphic back and forward buttons
• How to use the dynamic images technique to change images "on the fly"
• Applications of dynamic images, including a clock and a method for rotating
advertisements
• How to use JavaScript with client-side image maps
Next Steps
You should now understand how JavaScript works with images. Continue with one of the
following:
• To review the rest of the objects in the object hierarchy, see Chapter 5 "Accessing
Window Elements as Objects."
• To add more multimedia features, such as sound and video, see Chapter 13, "Working
with Multimedia and Plug-Ins."
• To learn techniques for debugging JavaScript programs and review the differences
between browser versions, see Chapter 14, "Debugging JavaScript Programs."
• For an example of a complete graphical application in JavaScript, see Chapter 15, "Real-
Life Examples III."
Q&A
Q: I need to eliminate an image entirely, rather than changing its source. Is there a
way to do this?
A: Not officially; you can't remove an image. However, you can replace it with a blank
image of the same size, which should produce the same effect-and a one-color GIF is a
very small file. Remember, you can't do anything that would change the layout of the
text.
Q: I created a JavaScript program on a page with images, and my event handlers
don't seem to be working. What's wrong?
A: JavaScript requires you to use HEIGHT and WIDTH attributes on all IMG tags. Adding
these will most likely make the event handlers work properly. See Chapter 14 for other
debugging techniques.
Q: I'd like to create a clock using text instead of graphics. This should be easy, right?
A: It's easy, but only if you use a text field in a form. As for normal text in the page, there's
no way to change it. You could keep the clock in a separate frame, though, and update
the entire frame. An example in Chapter 9 "Using Frames, Cookies, and Other
Advanced Features," does exactly `hat.
Chapter 13
Working with Multimedia and Plug-Ins
"Multimedia" is probably the oldest buzzword in the computer industry, and its definition keeps
changing. In the 80s, decent graphics and sound were enough to make a multimedia computer
system. Now the term includes such things as CD-ROM, CD-quality audio, and full-motion video.
As far as the Web is concerned, multimedia generally means having more than the usual media-
text and images-on your Web page. Alternate forms of media can be supported on a Web page in
two key ways:
• Helper applications are the traditional solution. These give a browser added capabilities,
such as playing sounds or displaying video images. The file you link to is downloaded
completely, then passed to the helper application.
• Plug-ins are a new solution, developed by Netscape. These are custom applications that
work within the browser, using a special programmer's interface (API). Using plug-ins,
alternate media can be displayed directly in the browser window.
Although JavaScript is a simple language, it can work with multimedia. In this chapter, you'll
explore what it can-and can't-do. You'll start with a look at sounds and their use in JavaScript,
then continue with a discussion of plug-ins.
JavaScript doesn't include any special functions to play sounds. However, it's easy to force a
sound to load and play in JavaScript. You can do this by setting the window.location.href
property-the same thing you set when forcing the user to load another page.
The result is the same as if the user clicks on a link to the sound. The file is downloaded, and
after the download is complete, the sound player application plays the sound.
By using this technique, you can play a sound at any time during the execution of your JavaScript
application. This could be as an event handler, as an alternative to an alert message, or just to
annoy the user.
Tip
Speaking of annoying the user, keep in mind that network
connections aren't always fast. It's best to stick to small, easily
downloaded sounds to keep things fast and smooth.
has gotten into the act; the latest version of Microsoft Internet Explorer (MSIE) also supports
Netscape-compatible plug-ins.
Plug-ins are developed by third parties (or by browser developers, in some cases) using an API
available from Netscape. The plug-in is able to use the resources of the browser and display its
output within the browser window.
Here is a sampling of the plug-ins currently available, most at little or no charge:
Tip
I don't have room to list all the available plug-ins here; such a list
could probably fill its own guide. See appendix C, "Online JavaScript
Resources," for a list of online resources for plug-ins.
• Adobe's Acrobat Plug-in (Amber) enables Portable Document Format (PDF) documents
to be displayed in the browser window.
• Macromedia's Shockwave plug-in enables Director movies and animations to be
displayed inline.
• The QuickTime plug-in displays QuickTime movies inline.
• A wide variety of plug-ins support Virtual Reality Markup Language (VRML). This enables
you to create interactive 3D sites. JavaScript can also work with VRML-see appendix C
for a pointer to information about VRMLScript.
• The ncompass plug-in, from ExCITE, enables Netscape to support ActiveX (OLE)
controls. You'll learn about ActiveX in Chapter 18, "Using ActiveX and Microsoft Internet
Explorer."
• The RealAudio plug-in enables you to listen to real-time audio; the sound is played as it is
downloaded. Netscape includes its version of this, LiveAudio, in the latest version.
• The Pointcast (pcN) plug-in displays news stories, stock information, and press releases.
Note
Plug-ins are not platform-independent. If a plug-in manufacturer
wants to support multiple platforms, it has to create a separate
version of the plug-in for each platform. Many plug-ins are available
exclusively for Windows or for the Macintosh.
You can place a plug-in document in a Web page using the <EMBED> tag, an extension to
HTML. For example, the following HTML tag inserts a PDF file at the current location in the page:
<EMBED SRC="doc.pdf">
For plug-ins that take up an area of the screen, such as video players and graphics, you can
specify HEIGHT and WIDTH attributes to limit the size of the embedded object, as with an
ordinary image. For example, the following PDF document is limited to a 200-by-100-pixel
square:
• Using the LiveConnect features of Netscape 3.0, you can control a plug-in with
JavaScript.
You'll look at each of these capabilities in the following sections.
Listing Plug-Ins
Using the navigator.plugins object, you can easily make a program to display a list of currently
available plug-ins. Listing 13.2 is such a program. The name, filename, and description for each
plug-in are listed in a table.
For example, this code checks for the Shockwave plug-in. If it's installed, the Director movie is
embedded in the document; otherwise, a message about the plug-in is displayed.
test = navigator.plugins["Shockwave"]; if (test) document.writeln("<EMBED
SRC='test.dir' HEIGHT=50 WIDTH=100>") else document.writeln("The
Shockwave Plug-in is required for this part of the page.")
You are simply displaying a message that the plug-in is required. As noted earlier, you could also
provide a link to download the plug-in, then use the refresh method of the plugins object to add it
to the plug-ins list and reload the document.
Workshop Wrap-Up
You should now understand how to use JavaScript to work with multimedia. You've learned the
following:
Next Steps
Continue your studies of JavaScript with one of the following:
• To add dynamic images and simple animation to your multimedia Web page, see
Chapter 12, "Working with Graphics in JavaScript."
• To learn about common errors in JavaScript programs and how to avoid them, see
Chapter 14, "Debugging JavaScript Programs."
• For an example of a large-scale JavaScript application, see Chapter 15, "Real-Life
Examples III."
• To learn to further enhance your Web pages with Java, see Chapter 16, "Integrating
JavaScript with Java."
Q&A
Q: If users don't have a plug-in that my page requires, is there any way to make their browsers
automatically download and install it?
A: Not presently, and this probably won't be a JavaScript feature in the future. However, Netscape is
considering a similar feature to be built in to a future version of Navigator (probably version 4.0).
Q: Is there any possibility of true integration of JavaScript with plug-ins-for example, being
able to add event handlers to parts of a video image or PDF document?
A: Not at present, and trying to do this would open quite a can of worms for Netscape-particularly
because each of the plug-in vendors would have to add JavaScript support.
Q: Is there any disadvantage to using plug-ins on my pages?
A: Yes. First of all, you'll be restricting the page to users of plug-in compatible browsers; second,
they will need the plug-in itself installed. Many users will consider this too much work just to
view one Web page.
Chapter 14
Debugging JavaScript Programs
So far, you've learned the basics of JavaScript and several advanced techniques. You have
explored several examples, all of which were tested and debugged for publication in this guide.
At this point, you're probably interested in creating your own unique JavaScript applications, and
you may have run into some problems. In this chapter, you'll explore some common errors and
misconceptions in JavaScript programming.
You'll also look at some tools and techniques you can use to debug your programs. Finally, you'll
explore some problems that aren't your fault-bugs in various implementations of JavaScript. You'll
also consider the impact of these bugs and explore ways of working around them.
Syntax Errors
Some of the most common errors you might make in a JavaScript program are syntax errors-
errors in the punctuation, object names, and such that make up a program.
Some syntax errors are obvious. For example, you might miss a comma or period, or spell the
name of an object wrong. Netscape recognizes most of these errors and will point them out to
you.
Unfortunately, some of the easiest syntax errors to make can be the hardest to detect. Netscape
won't detect them, and the program may even work-but produce the wrong result. You'll explore
the most difficult syntax errors in the following sections.
The first statement is considered an error because you are trying to compare the variable a with a
value, but a currently has no value. The error message produced by this example is shown in
Figure 14.2.
Figure 14.2 : the error message produced when you used the equality error by mistake.
However, consider the following modified version of the example:
a = 7; a == 5; if (a == 5) window.status="a is 5";
In this example, the variable a has been defined and assigned a value, before the equality
operator is used. This makes a == 5 an expression that simply evaluates to true, doing nothing.
No error message is produced, but the correct action is not performed.
message: name has no properties. Figure 14.3 shows an example of the error message when the
form name has been left out.
Figure 14.3 : The error message you usually get when using the incorrect name for an object.
You should also keep close watch on your capitalization, because JavaScript variable, method,
function, object, and property names are case-sensitive. For example, this statement is invalid
because the random() method should not be capitalized:
a = Math.Random();
Tip
If JavaScript gives you an error message saying that a name is
invalid, doesn't exist, or has no properties, look for a
punctuation or capitalization error.
HTML Issues
Because a JavaScript program is embedded within an HTML document, errors in the actual
HTML can affect your program. HTML is a complicated language in itself, and this guide can't
cover all of it here; however, here are some common HTML errors that can affect JavaScript
programs:
• Be sure to use the NAME attribute for all forms, form elements, and frames. This makes it
easy to access the objects from JavaScript.
• Be sure to enclose JavaScript code within <SCRIPT> tags, except when defining event
handlers.
• Use quotation marks around an entire event handler, and be sure to use single quotation
marks (apostrophes) instead within the event handler itself.
• Avoid using too many statements in an event handler; if you have a complex need, define
a function and call the function in the event handler.
• If you are using HTML comments to hide JavaScript code from older browsers, you have
to be careful; using the greater-than (>) or decrement (-) symbols anywhere in the script
can cause the comment to end prematurely. For tips on working around this problem, see
Chapter 1 "Creating Simple JavaScript Programs."
Some of the objects and properties in JavaScript can be confusing. The best example of this is
that the document and the window both have a location property. These are very different things:
• window.location is a location object that defines the location of the current window (or the
specified window). You can change this location to cause a new document to be loaded
by changing its properties, such as window.location.href.
• document.location is a simple text property that indicates the location of the document.
This may be different from the value of window.location.href if the document was
redirected from a different location.
A common error is to attempt to set document.location to send the user to a new URL. This
doesn't generate an error message, but also doesn't accomplish anything. You should always use
window.location.href to load a new URL.
Another area of confusion is the history object. Some references, such as Netscape's own
documentation, refer to the history object as a property of document. However, it is actually a
property of the window object. Each window has its own history.
For example, to go back to the previous document, you should use the window.history.back()
method, or simply history.go(). To go back to the previous document in the frame1 frame, you
would use parent.frame1.history.back(). Using document.back() results in an error.
Note
You can omit the window keyword if you are referring to an
object (such as history) in the current window. If you are
referring to a different window, you need to use its name. You
cannot omit the document keyword.
Timing Problems
A number of potential JavaScript programming errors are caused by failure to understand various
timing factors-the order in which a document loads and JavaScript code executes. Here are some
examples of problems of this nature:
• You must always define a function before calling it. If you place your function definitions
in the <HEAD> section of the HTML document, they will always be loaded first.
Otherwise, the script section that defines the function must be located before the section
that uses it.
• The window's onLoad event handler can be triggered before the entire document loads.
This is particularly true of images. This means that you should be careful when working
with the images array, because some images may not be loaded yet. You can use each
image's onLoad event handler to verify this.
• Another situation when onLoad doesn't always work is in using frames. The best way to
verify that an object you need to use is loaded is to check its value. If it isn't there, use
setTimeout to pause before trying again.
• Multiple setTimeout calls do not override each other. If the timeouts use different
variables, they will execute independently.
Variable Problems
Sometimes variables can create problems. One of the most confusing aspects of JavaScript is
the scope of variables-in other words, where a variable can be used. As you have learned, there
are basically two variable scopes in JavaScript:
• Global variables are those you define outside a function, or by using the var keyword.
These can be used anywhere in the HTML file where they are defined.
• Local variables are those you define within a function, or without using the var keyword.
They apply only to the function or set of <SCRIPT> tags where they are defined.
Problems can occur when you cut and paste JavaScript routines between two pages. You might
be using a global variable for one routine with the same name as a local variable used in another
outine. Any time a variable's value changes unexpectedly, suspect this type of problem.
Note
Two different local variables (local to two different functions)
can have the same name without causing a problem.
Reserved Words
JavaScript has a list of reserved words-words that you can't use as variable names because they
serve an important purpose within JavaScript. Because this list includes all the object properties
in the object hierarchy, it can be quite long.
This can create problems if you choose a name that matches a reserved word. For example,
suppose you created an order form that includes a name, address, and phone number. You might
choose the obvious names name, address, and phone for those text fields. However, because
form.name is a predefined property that holds the name of the form, this can create conflicts.
In some cases, the property might not work the way you expect it to, or change value
unexpectedly, because the internal JavaScript property has priority. In other cases, your new
property might override the built-in property, causing a different set of problems.
Tip
Refer to appendix B for a complete list of JavaScript reserved
words.
Platform-Specific Issues
JavaScript is designed as a platform-independent language. In other words, the Windows,
Macintosh, and UNIX versions of Netscape should run a script in exactly the same way.
For the majority of JavaScript features, this is true; however, there are still a few differences in the
way JavaScript works on the different platforms. Here are a few common platform-specific
problems:
• For some Macintosh versions of Netscape, dates in Date objects are one day in the
future compared to other versions.
• For some UNIX and Macintosh versions, the document.lastModified property returns an
incorrect value-or causes a crash.
• The parseInt() and parseFloat() functions return 0 to indicate that the result is not a
number in Windows platforms; on other platforms, they return "NaN" (not a number).
There are many other minor differences between platforms. Worse, when the current version of
Netscape is a beta version, there may be different bugs for different platforms, or the version may
not be available for a particular platform yet.
How do you keep up? The differences are usually minor, so you can usually avoid these issues.
Because most of us don't have several computers handy to test a program on every platform, the
best you can do is put it on the Web-you'll get feedback from users if there's a problem.
Tip
If you use much JavaScript in your pages and change it
frequently, you may wish to find at least one user on each
platform to use as a beta tester. Send that user a note when
you change your pages, to make sure the user works on all
platforms.
Tip
You can also use the status line to view debugging information.
However, the value you display there might be erased by
Netscape or by your program.
Debugging with a Temporary Window
For larger-scale debugging needs, you can open a new window and use it to display debugging
information. The following is an example of a statement to create a new window called bug to
display debug information in:
bug = window.open("","bug","status=0 toolbar=0");
After opening the debug window, you can use a simple function to write data to it:
function debug(text) { bug.document.writeln(text); }
You can now use the debug() function to display debug messages in the new window. Listing
14.1 shows a detailed example of this technique, and Figure 14.4 shows the output in the debug
window.
Figure 14.4 : Using a temporary window to display debugging information.
Listing 14.1. (TEMPWIN.asp) A simple program that displays debug
information in a temporary window.
<HTML> <HEAD><TITLE>Test of Debugging Window</TITLE> <SCRIPT>
//open the debug window bug = window.open("","bug","status=0 toolbar=0
height=100 width=400");
bug.document.write("<HTML><HEAD><TITLE>debug</TITLE></HEAD>");
bug.document.write("<BODY><h1>debug output</h1><hr><PRE>"); //function to
write to debug window function debug(text) { bug.document.writeln(text); } a =
17.5; b = 29; c = "This is text"; debug("Value of a is: " + a); debug("Value of b is: "
+ b); debug("Value of c is: " + c); </SCRIPT> </HEAD> <BODY> <h1>Test of
Debugging Window</h1> <hr> this is a test. </BODY> </HTML>
add5(39)
and the result (44) will be displayed.
Tip
You can also use the JavaScript command line as a
convenient calculator. Type an expression, such as 5*30, and
it will be evaluated. You can even define variables and use
them in your calculations.
javascript:window.alert("This is an alert.");
This makes it easy to test a statement or expression quickly. Using this method, however, you
cannot define functions or perform other complex operations.
Tip
You can also use javascript: as a link destination to make links
that execute a JavaScript statement or function. This is an
alternative to event handlers. You saw some uses for this
technique in Chapter 12.
Tip
The JavaScript Trace Facility is also included on the CD-ROM
accompanying this guide.
Once you've done this, you can use the functions for interactive debugging and tracing.
• The Expression or Object text field enables you to enter an expression, command, or
object name to be evaluated.
• The Evaluate button evaluates the expression, similar to Mocha's command line.
• The Properties button lists the properties of the object you have named on the command
line.
• The Clear button clears all the fields.
• The Result text field displays the result of the expression, the return code for a statement,
or the properties of the object.
• The Trace Output window displays tracing messages. You can create these by using the
trace functions, described in the next section.
• The Statistics button displays statistics for a function. This is used with the statistical
functions described in the next section.
Caution
All these trace functions will slow down your program, and they
should be used only while debugging. The statistical functions
are particularly time-consuming, and they may not work well
with complex programs.
In the next sections, you'll look at each of the versions of Netscape and Microsoft Internet
Explorer that support JavaScript, their limitations and bugs. If users report a problem with your
script, you should refer to this list to determine whether the problem is caused by their browsers.
Note
Bugs in JavaScript are still being fixed-and still being
discovered. There is no way to guarantee that every possible
bug is included, but I have tried to include all known problems
at the time of this writing.
Tip
For more detailed information about each version of Netscape,
including versions released after this guide, refer to Netscape's
release notes at this URL:
http://home.netscape.com/eng/mozilla/3.0/relnotes/index.a
sp.
• The select() and focus() methods for input fields don't work properly.
• The selectedIndex property of a selection list doesn't receive the correct value.
• The window.close() method does not work in these versions.
• Attempting to use a window the user has closed can cause Netscape to crash.
• The eval() function causes crashes, particularly in the 16-bit Windows version of
Netscape.
• Floating-point arithmetic has some inaccuracies.
• The <SCRIPT SRC> method of including JavaScript in an HTML file does not work.
Memory Problems
Along with these problems, Netscape 2.0 suffers from some memory leaks when JavaScript is
used. This means that certain JavaScript code can use up memory, often resulting in an out-of-
memory error or crash.
The most common cause of this problem is when you repeatedly assign a value to a string.
JavaScript cannot modify the value of a string without re-creating the entire string. If you change
a string's value repeatedly in a loop, memory will quickly disappear.
Tip
Some of the worst cases of memory leakage occur in scrolling-
message programs, which assign a new value to a string every
second or faster. The scrolling message program introduced in
Chapter 8 "Improving a Web Page with JavaScript," avoids this
problem.
New Features
Netscape 3.0 added many new features to JavaScript. In fact, many of the features you already
learned about were added in this version. JavaScript didn't really "grow up" until version 3.0 was
released. Here is a summary of the new features:
• JavaScript can now access a list of plug-ins, to determine which ones are available. You
will use this feature in Chapter 13, "Working with Multimedia and Plug-Ins."
• JavaScript can now communicate with and access Java applets, and Java applets can
access JavaScript. You'll explore these features in Chapter 16, "Integrating JavaScript
with Java."
• The Array and Object keywords, which you looked at in Chapter 4 "Using Built-In Objects
and Custom Objects," were added.
• The images array, which you looked at in Chapter 12, was added.
• Data tainting, explained in Chapter 10, "Working with Multiple Pages and Data," was
added.
• The focus() method can now be used on external windows.
• The <SCRIPT SRC> tag can now be used to include JavaScript from a URL.
• The <NOSCRIPT> tag makes it easy to detect non-JavaScript browsers.
• You can modify the items in a selection list on the fly.
Tip
You'll take a closer look at MSIE, ActiveX, and VBScript in
Chapter 18, "Using ActiveX and Microsoft Internet Explorer
3.0."
Workshop Wrap-Up
In this chapter, you explored some of the many ways JavaScript programs can fail, and what to
do about them:
• You've looked at some of the most common errors JavaScript programmers make and
how to avoid them.
• You have also looked at two techniques for displaying debug information: alerts and
external windows. Each of these has its advantages.
• Next, you looked at two tools that may help the debugging process: Netscape's
JavaScript command line, and the JavaScript Trace Facility by Fred Highland.
• Finally, you took a tour of the various versions of Netscape (and Microsoft Internet
Explorer) that support JavaScript and some of the problems and bugs in each version.
Next Steps
You should now have a good understanding of the techniques you can use to debug even the
most stubborn JavaScript program. Now move on with one of the following:
• To build a full-scale JavaScript application, see Chapter 15, "Real-Life Examples III."
• To learn issues involved when working with JavaScript and Java, see Chapter 16,
"Integrating JavaScript with Java."
• To learn tips for debugging CGI programs used with JavaScript and forms, see Chapter
17, "Combining JavaScript, CGI, and SSI."
• To learn more about Microsoft Internet Explorer and its scripting capabilities, see Chapter
18, "Using ActiveX and Microsoft Internet Explorer 3.0."
• To learn about proposed and rumored features for future versions of Netscape, see
Chapter 20, "The Future of JavaScript."
Q&A
Q: Are all the causes for Netscape crashes covered in this chapter?
A: By no means. I've tried to cover the most common causes, but there are still occasional
crashes-in any program, not just Netscape-that can't be explained. Watch also for new
bugs in any future version.
Q: What's the easiest way to avoid the problems with hiding JavaScript from older browsers
with HTML comments?
A: Instead of using comments, use the <SCRIPT SRC> command and store the script in a separate
file. This feature is supported in Netscape 3.0b5 and later versions.
Q: If the onLoad event doesn't necessarily happen after the document is finished loading,
how can I be sure it's finished?
A: A simple workaround is to set a timeout in the onLoad handler to execute your function a few
seconds later. Netscape has promised a method to verify this in a future version.
Chapter 15
Real-Life Examples III
This chapter includes a single example program: a poker solitaire game written in JavaScript.
This is the largest program presented in this guide and illustrates the following concepts from
previous chapters:
• Functions and event handlers (Chapter 3)
• Arrays, custom objects, and arrays of objects (Chapters 4 and 10)
• Forms (Chapter 6)
• Replacing inline images (Chapter 12)
In addition, it's a good demonstration of a large-scale JavaScript application. The next sections
describe and present the program.
• The board consists of 25 squares in a 5-by-5 grid. A "draw" card is on the lower right
corner.
• The computer deals cards one at a time. Each card appears in the draw pile. You can
click on one of the 25 squares in the grid to move the card to the board.
• Scoring is based on poker hands. Each row, column, and diagonal is a separate hand,
and is scored when it is completed. The total score is a combination of all of these.
• The game ends when 25 cards have been dealt. You can also click on the New Game
link to start over.
Before you move on to the program itself, let's look at a few of the challenges of planning a
project of this size:
• The board consists of 25 squares. By including a title graphic, I conveniently made these
the 1st through 25th images on the page-this will make them easy to access via the
document.images array.
• I used a custom object, Card, to store information about the cards in the game. This
object includes a number (1-13) and a suit (c, h, s, or d.)
• The deck of cards is stored in an array called deck; each element is a Card object.
• The cards currently on the board are placed in an array called board. Once again, these
are Card objects.
• I created 52 images-one for each card-and a blank image to represent blank spaces on
the board. These are all exactly the same size, so they can be easily swapped inline.
• The whole game board is laid out using a table. The first column includes a link to start a
new game and the total score, columns 2 through 6 are the game board, and the last
column and row are used for text fields. These will hold the score for each column, row,
and diagonal.
Placing Cards
Once the InitGame() function is finished, the program isn't running at all-that's the beauty of
event-based programming. The next step is up to the user, who should click on one of the
squares of the game board.
When a square is clicked, the PlaceCard() function, shown in Listing 15.3, is called. This function
moves the card from the draw pile to the appropriate square. Because it's already in the cache,
this happens instantly. An image object is then created to preload the next card. Figure 15.2
shows a game in progress with several cards placed.
The following scores are assigned to the various poker hands, based on their relative probability:
Straight flush 50
Royal Flush 250
Ending a Game
The EndGame() function, shown in Listing 15.5, is called when 25 cards have been played. This
function is simple; it "blanks out" the draw card and informs you that the game is over with an
alert. Because the total score is updated continuously, there's no need to worry about it here.
Listing 15.5. The EndGame() function ends the game.
// game over - final score function EndGame() { document.images[26].src =
"blank.gif"; window.alert("Game Over"); }
Figure 15.3 shows the screen after a reasonably successful game. That's it! I hope this example
shows you how much you can do with JavaScript and inspires you to even bigger things.
Figure 15.3 : The Poker Solitaire game display after all cards have been played.
Chapter 16
Integrating JavaScript with Java
As I mentioned in Chapter 1 there's not much relation between Java and JavaScript-except for
the name. However, they can both be useful on your Web pages-sometimes at the same time.
This chapter begins with an introduction to the Java language and its capabilities.
JavaScript also includes functions to control Java applets, and Java applets can access
JavaScript functions. By integrating these two Web languages, you can have the best of both
worlds, allowing for many complicated applications.
An Overview of Java
Let's begin with a tour of the Java language, the development process for Java applets, and the
way Java and HTML interact. If you're unfamiliar with Java, this will give you a quick start and
help you understand how Java and JavaScript can work together.
Note
Java is a complex language-much more so than JavaScript.
This chapter introduces Java, but can't explain it in detail. If
you want to learn more about Java, consult the online
resources listed in appendix C, or pick up a copy of the
bestselling Teach Yourself Java in 21 Days, by Laura Lemay,
also from Sams.net publishing.
machine. This virtual machine code can then be interpreted by an implementation of the virtual
machine, such as Netscape.
Note
To complicate things even more, the latest versions of
Netscape and MSIE include Java compilers. Called just-in-time
compilers, these compile Java virtual machine code into
executable code before running the applet. This greatly
increases the speed of applets.
Tip
You can also use JavaScript to choose between a Java or non-
The next section presents a complete HTML file with an embedded applet. For examples of
embedding public domain Java applets into your pages, see Chapter 19, "Real-Life Examples
IV."
Note
Currently, most complicated Java applets are a bit slow. If you
include one in your Web page, be sure you test it carefully; you
may also wish to warn users that an applet is loading.
Tip
The JDK is also included on the CD-ROM that accompanies
this guide, along with a variety of sample applets.
Note
Currently, there is no version of the JDK for Windows 3.1 or
68000-series Macintosh. You will need to use a different
platform to compile Java applets, although you can still view
applets in Netscape. If you have a shell account with your
Internet provider, you may be able to use the JDK from there.
The following tasks explain how to download and install the JDK, use it to create a simple Java
applet, and compile and view the new applet.
http://java.sun.com/
and follow the appropriate links. At this writing, the latest version of the JDK is 1.02. Once you've
downloaded it, the installation process depends on your platform:
• For Windows 95 or NT, start a DOS session. Copy the self-extracting archive file to the
directory or drive you wish to install the JDK in, and execute it. It will be unpacked into a
java directory with several subdirectories. The JDK needs about 5M of space to unpack.
• For Solaris, the JDK comes in a compressed tar file. You can expand it into the directory
of your choice with this command:
[
• For Macintosh, the JDK is available in MacBinary or hqx format. Expand the file with a
utility such as StuffIt, DeHQX, or BinHex4. Run the installer program, which will create a
folder on your desktop for the JDK.
Here is a brief explanation of the program. The first three lines are Java import statements. These
specify three classes (libraries) used by the applet:
Note
Just about everything in Java is case-sensitive-source files,
class files, and the <APPLET> tag. Be sure you use the exact
names.
To test the new applet, you need to embed it in an HTML page. Listing 16.2 shows a simple
HTML page that includes the applet created previously. Create this HTML file in the same
directory as the class file or copy the class file into its directory.
Listing 16.2. (JAVA1.asp) An HTML file to test the new Java applet.
<HTML> <HEAD> <TITLE>Simple Java Test</TITLE> </HEAD> <BODY>
<h1>test</h1> <hr> An applet is included below to display some text. <hr>
<APPLET CODE="JavaTest.class" WIDTH=450 HEIGHT=125> </APPLET>
<hr> applet finished... here's the rest of the page. </BODY> </HTML>
The <APPLET> tag in this file includes the filename of the JavaTest class and a width and height.
Be sure to include the closing </APPLET> tag, although there may be nothing between the two
tags.
Now that you have an HTML file, you need to test it. A simple way to do this is with the applet
viewer, included with the JDK. You can start the applet viewer by typing the following command in
the JDK directory:
bin\appletviewer file:\Java\JavaTest.asp
Tip
You may need to modify this command to work on your
system. You can also add the java\bin directory to your path to
avoid typing bin\ before each command.
Although you started the applet viewer from a command line, the actual output is shown in a
graphical window. Figure 16.2 shows the applet viewer in action, using the example applet.
Figure 16.1 : The Java applet viewer in action.
Notice that the applet viewer shows the output of the Java applet, but does not include the text
from the HTML file itself. This may be useful when you're debugging a Java applet. To see the
entire HTML file including the applet, you'll need to use a browser, such as Netscape.
To test the applet in Netscape, simply use the Open command to load the HTML file created
previously. Figure 16.2 shows the applet example as viewed by Netscape.
Figure 16.2 : The Java applet in action, as viewed by Netscape.
Note
Once you've created and debugged a Java applet, you'll
probably want to publish it on the Web. To do this, simply place
the class file for the applet in the same directory as the HTML
file on the Web server.
Note
There is an exception to the rule: any Java method that
communicates over the network can't be called from
JavaScript. This limitation exists for security reasons.
This applet now includes a SetMessage() method to change the text in the display. Listing 16.4
shows the HTML and JavaScript document used to control the applet.
This uses a simple event handler to call the Java applet's SetMessage() method. The string you
enter in the text field is passed to the applet and displayed in place of the original string. Figure
16.3 shows this application in action after the text has been changed.
You can also call JavaScript functions and methods from within Java, using the same technique.
The two methods you use for this purpose are call and eval. For example, this statement calls a
JavaScript method to display an alert message:
js = JSObject.getWindow(this); js.call("window.alert('This is a test.');");
Workshop Wrap-Up
In this chapter you learned about Java and how it can work with JavaScript:
• The basics of how the Java language and compiler work
• Where to get the Java Development Kit (JDK) and how to install it
• How to create and compile a simple Java applet
• How to embed a Java applet in an HTML page
• How to use JavaScript and LiveConnect to control a Java applet
• Using JavaScript objects, functions, and methods from within a Java applet
Next Steps
You can continue exploring JavaScript and Java with one of the following chapters:
• To learn how to combine JavaScript with other popular Web languages-CGI and SSI-turn
to Chapter 17, "Combining JavaScript, CGI, and SSI."
• To learn about Microsoft Internet Explorer, ActiveX, and VBScript, turn to Chapter 18,
"Using ActiveX and Microsoft Internet Explorer."
• To see examples of using Java applets and controlling them via JavaScript, see Chapter
19, "Real-Life Examples IV."
• To learn about the future of JavaScript, Java, and other Web languages, turn to Chapter
20, "The Future of JavaScript."
Q&A
Q: Can I access third-party Java applets from JavaScript, particularly those that were
created without JavaScript in mind?
A: Usually not. The applet must include the Netscape package, which includes the required
functions for JavaScript and Java communication.
Q: Can I use more than one Java applet in a Web page?
A: Yes. However, note that this may cause severe slowdowns (and sometimes crashes) in
some versions of Netscape.
Q: Judging by the examples in this chapter, Java isn't very similar to JavaScript. Why
on earth do they have similar names?
A: JavaScript was originally called LiveScript, but was renamed after Java. Although some
of the syntax is based on Java, it's a very different language.
Chapter 17
Combining JavaScript, CGI, and SSI
In the beginning, the Web was a read-only medium-you could browse all sorts of information and
link from site to site, but you couldn't really contribute anything yourself, except by clicking on an
e-mail address.
The Common Gateway Interface (CGI) specification was the first step in making the Web more
interactive. With new languages such as JavaScript and Java adding interactivity, you might
wonder whether CGI has become obsolete. At the moment, this is far from true-CGI bears little
resemblance to these languages, and can perform tasks impossible to other languages.
Because this is a guide about JavaScript, this chapter doesn't go into detail about CGI -it's
complicated enough to have merited a few guides of its own. You will take a look at the basics of
how CGI works, along with its close relative, SSI. This chapter presents a few examples of simple
CGI scripts and explains how you can install scripts on your server. Finally, you'll learn how CGI,
SSI, and JavaScript can work together to improve your Web pages.
NOTE
There are many guides about CGI. I recommend Teach
Yourself CGI Programming in Perl by Herrmann, and HTML &
CGI Unleashed by December, Ginsburg et al., both published
by Sams.net
• I created a CGI program called the Random Quotations Page, which you can access at
http://www.starlingtech.com/quotes/randquote.cgi
The output of this program is shown in Figure 17.1.
Figure 17.1 : A web page with random quotations, produced by a CGI program.
Using these pages as an example, here are a few comparisons of the capabilities of JavaScript
and CGI:
• My CGI version has about 20,000 quotes available, all stored in a database on the
server. This wouldn't be practical with JavaScript, because all the possible quotations
would have to be loaded with the Web page.
• The JavaScript version is much, much faster, and it places no more load on the server
than an ordinary Web page.
• The CGI version requires a server that supports CGI, access to it, and available disk
space-things a low-priced Internet account may not provide. The JavaScript version, on
the other hand, works even without a server-for example, you can load the file directly
from the CD-ROM included with this guide.
• The CGI version will work with any browser, but the JavaScript version requires
Netscape, MSIE, or another JavaScript-compatible browser.
• If the quotation was displayed in a text field, the JavaScript version could update it at the
touch of a button, without even reloading the page. CGI can't update part of a page.
As you can see, both JavaScript and CGI have advantages and disadvantages. Which you
choose for a particular job will depend on what you need to do and what resources you and your
users will have available.
TIP
CGI programs are sometimes referred to as CGI scripts,
because many of the languages used for CGI are considered
scripting languages.
When you're browsing the Web, you can access a CGI program in one of two ways:
• You can access it directly with an URL. The URL will often end in .cgi or .pl, although this
is not a requirement.
• You can press the SUBMIT button on an HTML form. This sends the data you have
entered in the form's elements to the CGI program on the server.
In technical terms, a request is being sent to the HTTP server to run the CGI program. After you
send your request using either method, the CGI program can send output back to you in the form
of a Web document. An entire document is always sent.
The requests sent to the server are sent using one of two methods. The difference between these
lies in the way that data from your browser, or from form elements you filled out, are sent to the
server. The two methods are the following:
• The GET method sends data in the URL itself. If you enter the URL of a CGI program
directly, you are accessing it with the GET method. Forms can also use this method.
• The POST method sends data in a stream (standard input) after the request. This
method enables larger amounts of data to be sent. The POST method is used exclusively
by forms.
NOTE
A JavaScript program cannot be used as the ACTION of a
form, but it can work with the data before it is sent to the CGI
program. Chapter 6describes the use of JavaScript with forms.
CGI sends data to the server using URL encoding, and you may need to encode data you are
sending. You may also run into this encoding using JavaScript; for example, data you send using
the mailto: method is encoded this way. URLs sometimes include encoded characters, and you
may need to decode them.
JavaScript includes two functions to let you work with encoding:
• The escape() function converts a string to URL-encoded form.
• The unescape() function converts a URL-encoded string to normal text.
With either function, simply use the text to be converted as the function's parameter.
Environmental Variables
Along with the name/value pairs, a CGI program also receives information in environment
variables. These include a variety of items about the server and the browser. Here are a few of
the most common ones:
• SERVER_SOFTWARE is the version of the Web server in use.
• REMOTE_ADDR is the user's IP address.
• REMOTE_HOST is the user's host name.
• REQUEST_METHOD is the form's method, either GET or POST.
• QUERY_STRING is used to store the name/value pairs if the GET method is used.
• HTTP_USER_AGENT is the name of the browser the user is using (similar to
JavaScript's Navigator object).
As you can see, these include some information that is not available to JavaScript. You'll see a
way to make this information available to JavaScript in the task Creating JavaScript Functions
with SSI, later in this chapter.
NOTE
The Content-type header must always be followed by a blank
line, before the actual output of the program begins
Optionally, a CGI program can send the user to an existing Web page, rather than outputting a
document of its own. This is done using the Location: header, as in this example:
Location: http://www.starlingtech.com/guides/javascript/
You should now have an understanding of the basics of CGI programming. You'll look at the
specific languages a CGI program can use later in this chapter and also see an example of a CGI
program.
Perl
Perl is by far the most common language used for CGI programs today. Perl is a versatile
scripting language available for UNIX, DOS, and Windows NT platforms; practically every Web
server has Perl available.
Like JavaScript, Perl is an interpreted language, so programs you download or create in Perl will
not require compiling.
Perl's syntax is unique and can be confusing; however, you'll find that it has much in common
with JavaScript. Many guides are available that explain Perl fully; you can also refer to appendix
C, "Online JavaScript Resources," for Web pages with information about Perl.
C and C++
C and its object-oriented counterpart, C++, are also a popular choice for CGI. Unlike Perl, these
languages must be compiled. If you download a public-domain program in these languages, you
need to compile it to run on your particular server.
Other Languages
Simple shell languages, such as sh and csh, are a common choice for simple CGI programs on
UNIX platforms. Other possibilities include Python and TCL. Any language you know can be
used, provided it's available on your server.
TIP
Like JavaScript, Perl allows comments. The lines beginning
with # in Listing 17.1 are comments, and they describe the
purpose of each section of the program.
Whether you learn to write CGI programs yourself or decide to use one of the many available
public-domain CGI programs, you'll need to install it on your Web server to use it. This section
explores the steps you follow to do this.
Depending on your situation, you might need to cooperate with the administrator of your server to
perform these tasks. Some Internet providers do not allow CGI programs at all; you should check
with the staff if you have any doubts or if the following steps don't work.
NOTE
Additional steps may be necessary, depending on the
configuration of your Web server. Check with your
administrator if the previous steps don't work.
Workshop Wrap-Up
In this chapter you learned about CGI and SSI, and how they can work with JavaScript:
Next Steps
Move on with one of the following:
• To learn to use JavaScript to validate a form before sending it to a CGI program, see
Chapter 6 "Using Interactive Forms."
• To learn about another Web language-Java-and how it can work with JavaScript, see
Chapter 16, "Integrating JavaScript with Java."
• To see examples of the techniques in this chapter, see Chapter 19, "Real-life Examples
IV."
• To learn how JavaScript's capabilities may improve in the future, see Chapter 20, "The
Future of JavaScript."
Q&A
Chapter 18
Using ActiveX and Microsoft Internet Explorer
In this chapter, you're taking a bit of a detour from JavaScript. You will be looking at Microsoft's
answer to scripting. This includes the following topics:
• Using the Microsoft Internet Explorer (MSIE) Web browser, and how it works with
JavaScript
• ActiveX controls, which can be placed on Web pages
• VBScript, a scripting language supported exclusively (for now) by MSIE
Downloading and Installing Internet Explorer 3.0
Microsoft Internet Explorer (MSIE) is Netscape's greatest competition, and for good reason-it
includes many enhancements and is completely free. However, it doesn't support JavaScript
completely. Here are some highlights of the features in the latest version:
• The entire HTML 3.2 specification is supported. In addition, MSIE supports style sheets-a
supplement to HTML that enables you to precisely control the way a page is laid out,
without violating the HTML standard. Netscape has planned support for style sheets for
Navigator 4.0.
• Along with JavaScript support, which is still being perfected at this writing, MSIE 3.0
supports ActiveX and VBScript, which you'll look at later in this chapter.
• MSIE 3.0 supports the Netscape plug-in specification; most Netscape plug-ins will work
just as well with MSIE. You learned about plug-ins in Chapter 13, "Working with
Multimedia and Plug-Ins."
• This is the first version of MSIE to fully support frames and cookies, which you learned
about in Chapter 9 "Using Frames, Cookies, and other Advanced Features."
• An extension to frames enables floating frames-frames that can be anywhere on the
page, rather than simply dividing the screen. They can also overlap.
• It includes intranet-specific features, such as enabling an administrator to limit which
functions users can access.
• You can follow links without using the mouse. This sounds minor, but it's something I've
wanted to see in Netscape for years.
Tip
For more information about MSIE 3.0, ActiveX, and VBScript,
take a look at Internet Explorer 3 Unleashed, published by
Sams.net.
To begin, you need to download the latest version of MSIE. You can find the appropriate link to
download it by starting at this URL:
http://www.microsoft.com/ie/
The Windows version of MSIE comes in a self-extracting archive file. To begin the installation,
simply click on the file. Note that, in the current version, MSIE installs on drive C, whether you
want it to or not.
Note
MSIE is available for Windows 95, Windows 3.1, and
Macintosh platforms at this writing, although not all platforms
have all features available. Consult Microsoft's Web page for
further information.
Once installed, you will find an icon to run MSIE on the desktop. When you first run MSIE, the
Microsoft Network page will be loaded by default, as shown in Figure 18.1. Luckily, you can
change the default page.
Figure 18.1 : The initial display of MSIE includes Microsoft's Web page.
Note
Bear in mind that this guide is based on Netscape 3.0's
implementation of JavaScript, but MSIE's support more closely
matches that of Netscape 2.0. A future version of MSIE will
undoubtedly address the 3.0 features.
As one example, Figure 18.2 shows MSIE displaying the Fictional Software Company Web page
with the scrolling message example from Chapter 8 "Improving a Web Page with JavaScript." The
scrolling status-line message works fine, but the onMouseOver events to display friendly link
descriptions don't.
Figure 18.2 : MSIE shows the FSC home page from Chapter 8.
Note
As you may have guessed, ActiveX is a Windows-only feature-
at least for now. It is unknown whether Microsoft will support
other platforms; ActiveX controls rely heavily on the Windows
API, so this may never happen.
How ActiveX Controls Work
You can use an ActiveX control anywhere in a Web page using the <OBJECT> tag, which you
learn about in the next section. ActiveX controls work similarly to Java-they are embedded in the
page and perform a specific function. Compared to Java, though, they're more integrated with
HTML.
Unlike Java, an ActiveX control can be permanently installed on your machine, making it
available for future use. When you access a page with a control, it attempts to use an installed
control. If you don't have the control installed, it downloads and installs it automatically. (It does
inform you that it's doing this.)
Also unlike JavaScript and Java, ActiveX controls are purely executable code-they are handled
by the operating system directly, and little work is done by the browser.
These controls can be quite large and complicated. They can be used to add functionality to the
browser, similar to Netscape plug-ins. For example, the current version of MSIE implements the
Java virtual machine as an ActiveX control.
You can create your own ActiveX controls-however, it's not as easy as JavaScript, or even Java.
You need to use the Microsoft C compiler under Windows to create them.
• width and height allocate an area for the control. This works the same as the
corresponding attributes in an image tag.
• StartColor, EndColor, and Direction are parameters to be passed to the control. In this
case, they control the starting and ending colors and the direction of the gradient.
• Animated Button enables you to include buttons with animated displays in a page. For
example, the button might look "pressed in" when you click on it.
• Chart displays pie, line, and other types of charts within a Web page. The data to be
charted is stored in a separate file on the Web server. Figure 18.4 shows an example of
this control in action on one of Microsoft's Web pages.
• Gradient displays a block of color, ranging from one color to another. This control was
used in the example in the previous section.
• Label displays text, but at any angle, or even a curve. This can be useful for labeling a
figure or control.
• New Item enables you to display "new" icons automatically next to links on your page. A
parameter enables you to specify a date, and after that date the icon is not displayed.
• Pop-up Menu displays a pop-up menu of options. Selecting an option causes an event,
which can be used with VBScript or JavaScript.
• Pre-loader enables a page to be loaded into the cache, but not displayed until you
specifically request it.
• Stock Ticker downloads data from the URL you specify at regular intervals and displays it
in an area of the page. This is useful for changing information, such as stock prices.
• Timer waits a specified time, then causes an event. This is similar to the setTimeout
method in JavaScript.
• PowerPoint Animation Player plays Microsoft PowerPoint animations within a page-an
easy way to make animations, if you have PowerPoint.
Figure 18.4 : The ActiveX Chart control enables you to display graphs and charts within Web
pages.
Note
All the controls listed are available from Microsoft's Web site.
See appendix C, "Online JavaScript Resources," for a listing of
other pages with downloadable controls.
As you can see, just about anything can be done with ActiveX controls. There's a price, however-
some of the controls can be quite slow, and downloading a new control can be even slower.
You'll also have to consider whether you want non-Windows users to be able to view your page.
Note
The ActiveX Control Pad can be used with any ActiveX control.
However, you must be licensed to use the control. Many
controls can be used freely; with others, you may have to
purchase a license to use them in your own pages.
An Introduction to VBScript
One of the latest weapons in Microsoft's war with Netscape is VBScript. VBScript is meant to
compete directly with JavaScript, and it includes many of the same features.
You might have noticed that this guide takes 17 chapters to explain JavaScript-of course,
VBScript can't be fully explained in one chapter. This section presents the basics of VBScript and
shows you how to create a simple VBScript application. You'll also look at some of the key
differences between JavaScript and VBScript.
Note
To learn more about VBScript, consult Microsoft's online
documentation or get a copy of Teach Yourself VBScript in 21
Days by Brophy and Koets, published by Sams.net. appendix
D of this guide includes a list of online references to get you
started.
Variables
Like JavaScript, VBScript is a loosely typed language. There is one variable type, called Variant,
that can hold a number, a string, or other types of values. Variables must be declared with the
Dim statement (similar to Var in JavaScript). This example declares a variable and assigns a
string value to it:
Dim Answer Answer = "The answer is 42."
Like JavaScript, VBScript can access all the elements in a form-in fact, the syntax is strikingly
similar. This is the VBScript syntax to refer to the text1 input field in the form1 form:
val = Document.form1.text1.value
VBScript can be used for form validation and can prevent form submission while fields are not
filled in correctly.
Object-Oriented Features
Although VBScript can access form elements and ActiveX controls as objects, it is not as object-
oriented as JavaScript. There is currently no way to create new objects or add properties to
existing ones. These may be added in a future version.
Workshop Wrap-Up
In this chapter, you learned about Microsoft Internet Explorer, ActiveX, and VBScript:
• How to download, install, and run MSIE
• How MSIE handles (or doesn't handle) JavaScript programs
• What ActiveX controls are, and how they are used
• How to embed an ActiveX control in a Web page
• What VBScript is, and how it compares to JavaScript
• How to create a simple VBScript program
You also explored a sampling of the available ActiveX controls.
Next Steps
Move on with one of the following:
• To see another example of an ActiveX control in action, see Chapter 19, "Real-Life
Examples IV."
• To learn about other alternatives to JavaScript and the future of scripting on the Web,
turn to Chapter 20, "The Future of JavaScript."
• To learn about Java, another powerful Web language, turn to Chapter 16, "Integrating
JavaScript with Java."
• To find online resources related to JavaScript and VBScript, see appendix C, "Online
JavaScript Resources."
Q&A
Q: If MSIE supports JavaScript and Netscape will support VBScript, which language
will be the standard?
A: Honestly, it's anyone's guess. Of course, Netscape wants JavaScript to be the
standard, and Microsoft wants VBScript to be the standard. However, on the Web right
now there are many sites using JavaScript and very few using VBScript. Will this
change? Who knows.
Q: Can VBScript be used with Java, as JavaScript can?
A: Yes, according to Microsoft. The Java support in the latest MSIE is still in beta, though,
and I haven't seen a working example of this yet.
Q: Which language should I use in my Web pages?
A: Because both MSIE and Netscape support it, at least to a point, JavaScript seems the
clear choice right now. JavaScript is also more sophisticated than VBScript. Although
MSIE is gaining rapidly, Netscape is still used by about 90 percent of Web users at this
writing.
Chapter 19
Real-Life Examples IV
This chapter presents three example applications that apply the techniques you learned in Part V,
"JavaScript Alternatives and the Future," of this guide. These include the following:
• Example 1: Manipulating a Java Applet. You looked at a simple example of accessing
Java from JavaScript in Chapter 16, "Integrating JavaScript with Java." This is a more
complicated example.
• Example 2: Creating JavaScript Dynamically. This uses SSI, which you looked at in
Chapter 17, "Combining JavaScript, CGI, and SSI," to modify a JavaScript program
before the page is sent to the browser.
• Example 3: Using an ActiveX Control. You looked at ActiveX in Chapter 18, "Using
ActiveX and Microsoft Internet Explorer 3.0." This example uses an ActiveX control to
include a chart in a Web page.
Listing 19.1. (ControlJava2.java) The Java source code for the Java applet
to be controlled from JavaScript.
import java.applet.Applet; import java.awt.Graphics; import java.awt.Font; public
class ControlJava2 extends Applet { Font f = new Font("TimesRoman",
Font.BOLD, 60); String Message; public void init() { Message = new String("Java
Test"); } public void SetMessage(String MsgText) { Message = MsgText;
repaint(); } public void SetFont(String NewFont, int NewSize) { f = new
Font(NewFont,Font.BOLD,NewSize); repaint(); } public void paint(Graphics g)
{ g.setFont(f); g.drawString(Message, 15, 50); } }
This source code should be placed in a file called ControlJava2.java. Once you've done that, you
can compile it into a Java class with this command:
bin\javac ControlJava2.java
Note
Be sure you have included the Netscape packages when you
compile this applet. See Chapter 16 for details.
You now have a working applet that should work within any HTML file-but to access the new
options you will need JavaScript. Listing 19.2 shows the HTML document with JavaScript
functions to change the text, font, and size for the applet.
This is an example of using SSI to generate JavaScript. It uses the following techniques:
• Using SSI in a Web page
• Combining SSI with JavaScript
• Writing a simple Perl program
One of the most common items on the Web these days is a hit counter-a simple counter that
displays the amount of visitors a page has received. They're a bit of a cliché right now, but many
users can't live without them.
One thing is certain about counters, though-you can't make one using JavaScript alone, because
JavaScript can't store any information on the server. You could count how many visits a particular
user has made with cookies, but there's not much use for that.
As a solution, let's combine JavaScript with SSI. A simple SSI program will be used to insert the
counter into the page; it will be inserted in the form of a JavaScript assignment statement, so the
counter can be used in any JavaScript function.
To begin, Listing 19.3 shows the SSI program, written in Perl, for the counter.
Listing 19.3. (COUNT.PL) The Perl SSI program for the counter example.
#!/usr/local/bin/perl MAIN: { print "Content-type:text/html\n\n"; $count = 'cat
count.dat'; $count += 1; open(LAST,">count.dat"); print LAST $count; close
LAST; print "count = ",$count, "\n"; }
Here is a brief explanation of this program:
• The MAIN function is the primary function for this Perl program (and the only function).
• The first print statement provides the required MIME type for the output of the SSI
program.
• The counter variable, $count, is read from a file on the server called count.dat. It is then
incremented and output back to the same file.
• Finally, the counter is printed, with count = before it. This will serve as the JavaScript
statement to initialize the counter.
Next, you will need a JavaScript program to use the counter. The HTML document, complete with
JavaScript and the SSI directive, is shown in Listing 19.4.
Listing 19.4. The HTML document with JavaScript functions for the counter
example.
<HTML> <HEAD> <TITLE>Counter Test in JavaScript and SSI</TITLE>
<SCRIPT LANGUAGE="JavaScript"> <!--#exec cgi="count.cgi"--> </SCRIPT>
</HEAD> <BODY> <H1>A counter using SSI and JavaScript</H1> <HR> This
page includes a counter using SSI, and made available to JavaScript. <HR> The
count is: <SCRIPT LANGUAGE="JavaScript"> document.write(count);
</SCRIPT> <HR> Press button for an alert with the count. <FORM
NAME="form1"> <INPUT TYPE="BUTTON" VALUE="Click for Count"
onClick="window.alert('The count is' + count);"> </FORM> <HR> </BODY>
</HTML>
This example is shown in Netscape in Figure 19.2. Here are a few notes about how this program
works:
Chapter 20
The Future of JavaScript
Welcome to the final chapter! If you've made it this far, you should be approaching JavaScript
Expert status. For this chapter, you'll take a look at what the future may bring for Netscape and
JavaScript. You'll look at new features that are planned and those that would sure be nice.
Finally, you'll examine some of the alternatives to JavaScript-both present and future.
LiveConnect
You learned about LiveConnect in Chapter 13, "Working with Multimedia and Plug-Ins," and
Chapter 16, "Integrating JavaScript with Java." This is the recently introduced feature that
enables integration between JavaScript, Java, and Netscape plug-ins.
Although LiveConnect is already available, I'm considering it part of the future because it isn't
well-supported yet. Once it is, you'll be able to enjoy the following benefits:
• A wide variety of public-domain Java applets will be available, which include public
methods that can be accessed with JavaScript.
• With any luck, plug-in authors will begin to widely support LiveConnect. This will enable
you to use JavaScript to manipulate and control new types of data-3D objects, VRML,
video, real-time audio, and many more.
Language Features
As noted in this guide, the JavaScript language is limited in many ways. Although its simplicity is
one of its greatest advantages, it can be difficult to create complex programs. Here are a few
language features that would make JavaScript an even better language:
• Objects could be improved with a truly object-oriented implementation-for example, an
object could be defined as based on another object and automatically inherit its
characteristics.
• As noted in Chapter 14, "Debugging JavaScript Programs," JavaScript's error messages
can be downright infuriating at times. It would be nice to have a JavaScript debugger of
some sort-or at least some more accurate error messages.
Interactive Forms
As noted previously, Netscape intends to add the capability of enabling and disabling form
elements. It would also be nice if you could modify a form after it was loaded-for example,
changing the width of a text field. Another interesting feature would be the capability of modifying
event handlers of form elements "on the fly."
• JavaScript can be used for form validation, but few sites currently do so. Validated forms
will become more common as the general public starts to accept JavaScript as part of the
Web.
• There are a few good JavaScript games-recall the one in Chapter 15, "Real-Life
Examples III"-but I believe the potential for games in JavaScript is largely untapped.
Hopefully, as features such as dynamic images become common knowledge, more
complex games will be developed.
• MSIE supports ActiveX, and Netscape can support it with the ncompass plug-in (see
appendix C). JavaScript can be used to add scripting and control to ActiveX controls, and
this use will increase in the future-especially if MSIE turns out to be serious competition
for Netscape Navigator.
• As LiveConnect becomes more widely supported, JavaScript will become a tool for
manipulating Java applets and plug-ins dynamically.
Alternatives to JavaScript
Finally, let's take a quick look at the Web languages that are currently giving JavaScript a run for
its money-or can be used along with it.
Java
Java was the first of the client-side Web languages, and is still among the most powerful. You
looked at Java in detail in Chapter 16 and explored ways of integrating it with JavaScript.
Java has become widely accepted on the Web-more so than JavaScript, as a matter of fact.
There are already over a thousand publicly available Java applets, and more are being developed
constantly.
Java is a bit ahead of JavaScript, and it has already moved beyond the novelty stage. Although
clocks, animations, and LED signs are still common Java applets, more and more sites are using
it for interactive applications, games, and custom business-oriented applications for business
intranets.
Microsoft has committed to supporting Java. It's already supported in the latest beta of Microsoft
Internet Explorer, and rumor has it that Java will be involved in a big way in the next release of
Windows.
Microsoft's concern is probably in response to the possibility of Network Computers (ncs)-
dedicated consumer machines that use an Internet connection to access software and use Java
as an operating system. ncs haven't become popular yet, but Java seems to be here to stay.
CGI
CGI was the first taste of interactivity for the Web. Despite the growth of Java, JavaScript, and
plug-ins, CGI is doubtless still the most common type of program in use on the Web.
Any time you fill out a registration form, make an order, or answer a question on most Web
pages, a CGI script is used. Some sites use CGI to read all pages from a database, so every
page you read comes from CGI.
CGI is also one of the few parts of the Web that doesn't seem to be changing much. The CGI
specification is much the same today as it was two or three years ago-and on the Internet, that's a
very long time.
Some current CGI applications are being replaced with Java versions because it can
communicate with the server and is more interactive; however, CGI will probably remain for a
long time yet.
SSI
Server-side includes (SSI) is a way of embedding a CGI program directly in a Web page.
Although less commonly used on the Web, it still provides features available in no other
language.
SSI is often used to add counters and dynamic information to pages, and it is used on some
servers as a simple way of including the same text-for example, a copyright notice-on a Web
page.
Shockwave
Shockwave was one of the first plug-ins available for Netscape Navigator. It enables Director
movies and animations to be displayed inline in a Web page, and it enables some measure of
interactivity.
The Shockwave plug-in is available at no charge from MacroMedia. However, to create content
for Shockwave, you need to use MacroMedia Director, which is not available for free. This has
prevented Shockwave from being widespread, but there are already a wide variety of Shockwave
sites available-and more are coming.
One reason sites avoid Shockwave, and other plug-in-based additions to the Web, is the concern
that not all users will download the plug-in. Netscape has considered making plug-ins download
automatically-something like ActiveX controls in MSIE-and this may solve the problem. In
addition, future versions of Netscape may be bundled with plug-ins.
ActiveX
ActiveX controls (previously known as OLE or OCX controls) are Microsoft's answer to dynamic
Web content. These controls can be embedded in a Web page and add capabilities to the page-
ranging from scrolling text to an entire spreadsheet.
The popularity of ActiveX in the future will depend on the popularity of MSIE, currently the only
browser that supports these controls. In addition, a plug-in for Netscape, ncompass, supports
ActiveX. Currently, Netscape does not plan to add ActiveX capabilities to Navigator directly.
Note
One limitation of ActiveX is that it works only on Windows
platforms. This limits the audience and may prevent it from
becoming widely accepted.
VBScript
VBScript is the only currently available Web language that fits into the same niche as JavaScript.
VBScript is implemented by MSIE, and it includes many of the same features of JavaScript. It's a
simpler language and may be easier for beginners to understand.
Again, the popularity of VBScript will depend on the popularity of MSIE. However, MSIE already
supports JavaScript, so users may simply keep using a language with which they're already
familiar. On the other hand, Netscape may be adding support for VBScript in a future version.
Note
Currently, VBScript is supported only by MSIE. Netscape does
not currently intend to support it. However, if MSIE becomes
widespread, it may be forced to.
HTML Enhancements
If some uses of JavaScript become obsolete, it may not be another language that takes them
over-additions to HTML itself may eliminate the need for JavaScript. Here are a few examples:
• Netscape intends to add simple form validation as an extension to HTML in a future
version.
• Tricks now implemented by JavaScript, such as scrolling messages, may be built directly
into HTML in the future.
• Style sheets, which will be supported in Netscape 4.0 and are already supported by
MSIE, will give both designers and users control over a page's appearance, eliminating
some needs for JavaScript (such as deciding whether to display a frame version).
As HTML improves, though, JavaScript will also improve-I'm confident that there will always be a
use for it in Web pages. (But will there always be Web pages? That's another story.)
Workshop Wrap-Up
In this chapter, you took a look at the future of JavaScript:
• Features Netscape might add to JavaScript in the future, and to its Web browser
• A wish list of features that could make JavaScript more useful and powerful
• A look at the other languages on the Web, and how they might affect JavaScript's
popularity in the future
Next Steps
If you've read this guide in order, you've reached the end of the line. If not, you can learn more
with the following:
• To learn about Java and how it can be integrated with JavaScript, see Chapter 16,
"Integrating JavaScript with Java."
• To learn about CGI and SSI, turn to Chapter 17, "Combining JavaScript, CGI, and SSI."
• To learn more about ActiveX, VBScript, and MSIE, turn to Chapter 18, "Using ActiveX
and Microsoft Internet Explorer."
• To see examples of integrating JavaScript with other Web languages, see Chapter 19,
"Real-Life Examples IV."
Q&A
Q: Why did Microsoft implement JavaScript in its Web browser, if it wants VBScript
to become a popular scripting language?
A: Microsoft needs people to accept MSIE as an alternative Web browser, and to do that it
needs to support the latest Web features-JavaScript being one of them. Also, the
ActiveX features of MSIE 3.0 make it easy to support a variety of scripting languages.
Q: Will ActiveX controls ever be available on anything but Windows platforms?
A: Doubtful, because they rely heavily on the Windows API. If they were implemented on
other platforms, they would probably be slower and require large amounts of memory.
Q: Is every Web language listed in this chapter?
A: I've tried to list the most popular and controversial languages-those that are driving the
future of the Web. However, there are always others. For example, there are well over a
hundred plug-ins besides Shockwave that enable different types of interactive content.
Conclusion
I hope you've enjoyed this guide, and that you're as excited as I am about the many possibilities
for JavaScript. You're probably already thinking of some new ideas for JavaScript programs.
To keep up with JavaScript, you'll need to keep an ear to the ground, because the language is
still changing. appendix C lists some online resources that may be helpful-in addition, be sure to
watch the Web site listed in the Introduction for updates, additions, and more examples.
If you create something new and exciting, I'd like to see it. Contact me at the address listed in the
introduction. I'll also try to answer any questions about this guide you may have.
I wish you well in your future tasks with JavaScript and other languages, and may all of your
JavaScript programs be bug-free. (Or at least, may you not give up until they are.) Good luck!