Chapter 35

Writing JavaScript Applications

by Rick Darnell


CONTENTS

JavaScript is a scripting language included in HTML pages to increase their interactivity. This runs the gamut from alert boxes and status-bar messages to complex menu systems and form validation.

It's based on Java, so if you're familiar with the way Java works, you'll be up and running with JavaScript in short order. However, because JavaScript is much smaller than Java and is geared specifically towards working with HTML pages, it is easy enough for page authors with no programming experience to use, too.

Creating Scripts

Creating scripts is really quite simple, although you must use proper syntax to ensure success. A knowledge of object-oriented programming will prove useful to anyone creating functions with JavaScript, but it is not a necessity.

New Language, New Terminology

Objects, methods, properties, classes-an object-oriented world has taken off, and a whole new batch of terminology has cropped up to go with it. This section provides a quick primer on the basic terms that get used in conjunction with an object-oriented language such as JavaScript.

Tip
JavaScript is case-sensitive. For example, if your variable is called Bob, you can also have a BOB, bob, and BoB, and each one will be unique.

Object

Objects are at the heart of any object-oriented programming language, and JavaScript is no different. An object is a software model, typically used to represent a real-world object along with a set of behaviors or circumstances. In JavaScript, built-in objects can also represent the structure, action, and state of an HTML page. In object-oriented terminology, the actions are called methods and the states are called properties. Both of these terms get covered later in this section.

To build an object, you need to know something about it. Consider a squirrel as an example. A squirrel has several physical properties, including sex, age, size, and color. It also has properties relating to its activity, such as running, jumping, eating peanuts, or tormenting dogs. Its methods relate to changes in behavior or state, such as run away, stop and look, or twitch tail and chatter.

This example may seem all well and good, but how do you represent this idea as an object in JavaScript? The basic object creation is a two-step process, beginning with defining a function that outlines the object, and then creating an instance of the object. Using some of the properties listed in the preceding example, you can make a JavaScript squirrel as demonstrated in Listing 35.1.


Listing 35.1. A JavaScript object definition for a squirrel.

function squirrel(color) {

    this.color = color;

    this.running = false;

    this.tormentingDog = false;

}



var groundSquirrel = new squirrel("brown")


The first part of the script with the function tag outlines the initial state for any given squirrel. It accepts one parameter, called color, which becomes a property, and adds two more properties, called running and tormentingDog (both set to false by default).

By itself, the function does nothing-it has to be invoked and assigned to a variable. This is what happens in the next step, where a variable called groundSquirrel is created, and given the color brown. The following code shows how the object and its properties get represented:


groundSquirrel.color // "brown"

groundSquirrel.running // false

groundSquirrel.tormentingDog // false

Now, to implement the object as part of an HTML page (see Figure 35.1), include the object definition between the <HEAD> tags. To see the object in motion, use Listing 35.2.


Listing 35.2. Use the JavaScript definition of a squirrel in an HTML document similar to this one.

<HTML>

<HEAD>

<TITLE>The Squirrel Page</TITLE>

<SCRIPT language="javascript">

<!--

function squirrel(color) {

    this.color = color;

    this.running = false;

    this.tormentingDog = false;

}



// -->

</SCRIPT>

</HEAD>

<BODY>

Making a squirrel...

<BR>

<SCRIPT LANGUAGE="javascript">

var brownSquirrel = new squirrel("brown");

document.writeln("brownSquirrel.color = "+brownSquirrel.color);

document.writeln("<BR>brownSquirrel.running = "+brownSquirrel.running);

document.writeln("<BR>brownSquirrel.tormentingDog = "+brownSquirrel.tormentingDog);

</SCRIPT>

</BODY>

</HTML>


Figure 35.1 : The squirrel page creates a simple object and displays its properties.

Class

A class represents the definition for a type of object. Although classes are in Java and not in JavaScript, it is helpful to understand classes because many discussions about either language may refer to them. Simply stated, a class relates to an object as a blueprint relates to a bicycle. A blueprint contains all the information about the bicycle, but you can't ride it. To ride a bicycle, you need to create an instance of it. In object-oriented terminology, this process is called instantiation.

Classes can also have inheritance, which means they take on the behavior of other classes. A 10-speed bicycle and a tandem bicycle have bicycle characteristics but different specific features and functions. They are considered subclasses of the bicycle class.

Although a JavaScript function has a definition similar to a class, it can operate without instantiation.

Property

Properties are the individual states of an object, typically represented as variables. In the squirrel example, color, running and tormentingDog all represent properties of squirrel. An object's properties can include any of the valid JavaScript variable types.

Which type is which?
A variable's type is the kind of value it holds. Several basic variable types are offered by JavaScript, including string, Boolean, integer, and floating-point decimal.
JavaScript utilizes loose casting, which means a variable can assume different types at will. For example:
squirrel.color = "pink"
...statements...
squirrel.color = 30
Both color values are valid. In Java, this would cause an error because it incorporates tight casting. After a variable gets assigned a type in Java, it can't be changed.
Loose casting can make life easier when working with JavaScript. When building strings, for example, you can add a string to an integer, and the result will be a string. For example:
value = 3;
theResult = value + "is the number." //Results in "3 is the number."
The downside is that sometimes you can easily forget what a variable thinks it is. It's a good idea to try and keep variables to their original type unless absolutely necessary.

Object properties are accessed using the object's name, followed by a period and the name of the property:


squirrel.color

Assigning a new value to the property will change it:


squirrel.color = "pink"

Function

A JavaScript function is a collection of statements that are invoked by using the name of the function and a list of arguments, if used. As a general rule, if you use a set of statements more than once as part of a page, it will probably be easier to include them as a function. Also, any activity used as part of an event handler should get defined as a function for ease of use.

Functions normally appear in the HEAD portion of the HTML document to ensure that they are loaded and interpreted before the user has a chance to interact with them.

The syntax to define a function is as follows:


function functionName ([arg1] [,arg2] [,...]) {

...statements...

}

An example of a function that automatically generates a link to an anchor called top at the top of the current page could look like this:


function makeTopLink (topLinkText) {

    var topURL = "#top";

    document.writeln(topLinkText.link(topURL));

}

This function accepts a text string as its one argument, and it generates a hypertext link similar to using the HTML <A HREF> tags:


makeTopLink("Return to the top.");

makeTopLink("top");

Method

If properties represent the current conditions of the object, methods serve as the knobs and levers that make it perform. Consider the squirrel example again. Defining a squirrel seemed easy enough, but what about making it do something? First, the methods need to be defined as JavaScript functions.

The first method for the squirrel makes him run and quit tormenting the dog:


function runAway() {

    this.running = true;

    this.tormentingDog = false;

    document.writeln("The squirrel is running away.");

}

The second method makes the squirrel stop moving and tease the dog:


function twitchTailChatter () {

    this.tormentingDog = true;

    this.running = false;

    document.writeln("The squirrel is being annoying.");

}

A third method levels the playing field between the squirrel and the dog:


function dogGetsLucky () {

    this.tormentingDog = false;

    this.running = true;

    document.writeln("The squirrel's tail is a couple of inches shorter.");

}

One more method would help you see what happens to the squirrel as his state changes:


function showState() {

    document.writeln("<HR><BR>The state of the squirrel is:<UL>")

    document.writeln("<LI>Color: "+this.color+"</LI>");

    document.writeln("<LI>Running: "+this.running+"</LI>");

    document.writeln("<LI>Tormenting dog: "+this.tormentingDog+"</LI>");

    document.writeln("</UL><HR>");

}

Tip
You can include HTML tags in text written to the browser screen using JavaScript's write and writeln methods. These methods get interpreted like any other HTML text, so formatting can occur for generated content.

Now that you have three methods defined, you need to make them a part of the object. This step amounts to including the method names as part of the object definition:


function squirrel(color) {

    this.color = color;

    this.running = false;

    this.tormentingDog = false;

    this.runAway = runAway;

    this.twitchTailChatter = twitchTailChatter;

    this.showState = showState;

}

The final step is including the whole package as part of an HTML document, such as Listing 35.3, and seeing whether it works (see Figure 35.2).


Listing 35.3. Using the JavaScript definition of a squirrel and its behavior requires an HTML document similar to this one.

<HTML>

<HEAD>

<TITLE>The Squirrel Page</TITLE>

<SCRIPT language="javascript">

<!--

function runAway() {

    this.running = true;

    this.tormentingDog = false;

    document.writeln("The squirrel is running away.");

}



function twitchTailChatter () {

    this.tormentingDog = true;

    this.running = false;

    document.writeln("The squirrel is being annoying.");

}



function showState() {

    document.writeln("The state of "+this.name+" is:<UL>")

    document.writeln("<LI>"+this.name+".color: "+this.color+"</LI>");

    document.writeln("<LI>"+this.name+".running: "+this.running+"</LI>");

    document.writeln("<LI>"+this.name+".tormenting dog: "+this.tormentingDog+"</LI>");

    document.writeln("</UL><HR>");

}



function squirrel(color,squirrelName) {

    this.name = squirrelName;

    this.color = color;

    this.running = false;

    this.tormentingDog = false;

    this.runAway = runAway;

    this.twitchTailChatter = twitchTailChatter;

    this.showState = showState;

    document.writeln("A squirrel is born...");

}



// -->

</SCRIPT>

</HEAD>

<BODY>

<SCRIPT LANGUAGE="javascript">

var brownSquirrel = new squirrel("brown","brownSquirrel");

brownSquirrel.showState();

brownSquirrel.twitchTailChatter();

brownSquirrel.showState();

brownSquirrel.runAway();

brownSquirrel.showState();

</SCRIPT>

</BODY>

</HTML>


Figure 35.2 : The browser screen displays the activity of the JavaScript object as each method is executed.

Event Handlers

One of the features that makes JavaScript so powerful is its ability to respond to events on the Web page. This includes form elements, links and buttons. Unlike the other JavaScript items, event handlers are not included within <SCRIPT> tags-they are added as an additional parameter to the item they're monitoring:


<INPUT TYPE="text" NAME="state" WIDTH="20" VALUE="MT" onChange="checkState(this.value)">

This tag creates a text field, loads it with a default value of MONTANA, and adds an event handler to call the function checkState when the value of the field changes (see Figure 35.3).

Figure 35.3 : An alert box with the appropriate message is generated when JavaScript detects a change in the form field.


function checkState(stateName) {

    if (stateName.toUpperCase() == "MT") {

        window.alert("Glad you're in Montana"); }

    else {

        window.alert("Ride with me Mariah, in Montana."); }

}

This function looks at the value of the field. If it matches the default, it greets the user. Otherwise, it extends an invitation. This function is invoked only if the field changes from its current value. So, if the user changes the field to Alaska, then to Nebraska, then to Wyoming, the function is called three times.

Another useful event handler is the onClick event, which can be used for buttons, radio buttons, and lists. One popular use is to call a validation routine before submitting the form contents back to the server. This simplifies your CGI script on the server side by ensuring it receives only good data, and speeds the operation on the user's side.


<INPUT TYPE="button" NAME="submit" VALUE="Submit" onClick="validate(this)">

Note the difference in the two tags. One includes this.value and the other just this. When used within the confines of a form, this refers to the entire form, while this.value refers to the specific form element it's used in. More on validating forms is covered later in this chapter.

Javascript and Document Arrays
JavaScript represents the various items on an HTML page using arrays. For example, a form is an array of the various elements within it. Consider the following form definition:
<FORM NAME="GUEST_INFO">
<INPUT TYPE="TEXT" NAME="Guest_Name">
<INPUT TYPE="TEXT" NAME="Guest_Email">
<SELECT NAME="Background" MULTIPLE>
    <OPTION VALUE="hardcore">Seasoned Web Surfer
    <OPTION VALUE="liar">Business Only
    <OPTION VALUE="newbie">Not For Sure How I Got Here
</SELECT>
There are several arrays created when a form is included in a document. The first is an array of forms in the document (document.forms[index]). The second is an array of the elements within the form (document.forms[index].elements[index]). The last is for list elements (document.forms[index].elements[index].options[index]).
The preceding form example results in an array called document.Guest_Info, which is also referenced by its position in the document. If it's the first form on the document, it is also called document.forms[0] or document.forms["Guest_Info"].
Each of the form elements is an item within another array in the form. So, the second form element is called document.Guest_Info.Guest_Email, or another option, document.Guest_Info.elements[1].
The last array represented by this form is for the select elements. The naming of the specific element follows the preceding example, document.Guest_Info.Background, followed by one more object, options[index]. So, the second item in the select list is the preamble plus options[1] or options["liar"].
Although it seems like a terrible amount of typing, this ordering of your documents removes the ambiguity from identifying any item.

Tip
Keep in mind that entire books have been written about JavaScript-don't expect to learn all of the intricacies in one chapter in this book.

Validating Forms

Using CGI scripts to validate forms wastes precious user time and server time to conduct a process that, using JavaScript, is easier and faster on the client's computer. The time required for client-server communication gets reduced, along with the lengthy development cycle necessary for CGI scripts.

With its capability to interact with form elements, JavaScript seems ideally suited to validate information directly on the HTML page. This setup localizes the process and takes advantage of the underutilized client machine. Checking information on the client side also makes it much harder for users to send incompatible or damaging data to the server.

Tip
Generally it's easier to check for valid values than invalid values. If you make a practice of checking for only valid information and rejecting the rest, you should be able to avoid most problems.

Several methods exist to implement form validation, and most include adding a JavaScript function as the action of a submit button. The HTML definition of the submit button could look like this:


<INPUT TYPE="BUTTON" NAME="SUBMIT" VALUE="SUBMIT" 

onClick="checkInformation(this.form)">

checkInformation is a function that provides verification for the form to ensure that the information meets CGI script expectations. If not, it should return to the document without submitting the form contents to the server. It can also return focus to the offending items. If everything passes inspection, then the function can also use the submit method.


function checkInformation(thisForm) {

    ...validation statements ...;

    if (validationPassed) {

        thisForm.submit(); }

    return;

}

Tip
The submit() method sends the contents of the referenced form contents back to the server by the get or post operation.
You can review or change the submission method through the method property of the form, this.method. If you want to make sure the contents are sent using get, then use a JavaScript command such as thisForm.method = "get".

As mentioned earlier, each form element becomes part of a form object with JavaScript. By using the name of the form as the name of the object, you can access each of the elements. If a name is not used, you can also use the forms array. The first form on the page is forms[0], the next is forms[1], and so on.

For an example, look at the following form definition:


<FORM NAME="validation">

Enter your user name and identification in the boxes.<BR>

Your name: <INPUT TYPE="text" NAME="userName" VALUE=""><BR>

User ID: <INPUT TYPE="text" NAME="userID" WIDTH="9" VALUE=""><BR>

<INPUT TYPE="button" NAME="button" VALUE="Submit" onClick="checkID(this.form)">

</FORM>

Each element in this form is represented in JavaScript as


document.validation.userName

document.validation.userID

document.validation.button

The last element, a button, includes an event handler that calls the function checkID with the current form as the argument. Note that you don't need the name of the form in the call because the contents are passed as an argument in this.form. In the function (see Listing 35.6), the form is referred to as the name of the argument, formID.


Listing 35.6. A function that checks to make sure the lengths of two form elements are correct before submitting the form.

function checkID(formID) {

    var validUser = true;

    var validID = true;

    if (formID.userName.length != 10) {

        validUser = false;

        formID.userName.value = "Invalid Entry"; }

    if (formID.userID.length != 9) w        validID = false;

        formID.userName.value = "Error"; }

    if (validUser && validID) {

        formID.submit(); }

    else {

        alert("Please try again."); }

}


To understand the function, work through it section by section. First, two Boolean variables are initialized. These flags indicate whether the validation has been passed when it comes time to check at the end of the function.

Next, the length of a form element named userName gets checked. If the value doesn't equal (represented in JavaScript by !=) 10, then the valid flag is set to false, and the form element receives a new value, which is reflected immediately on the page.

The same process gets repeated for the next form element, userID. At the end, if both flags are true (logical and is represented by &&), the form is submitted using the submit method. If either or both of the flags are false, then an alert screen appears.

Caution
JavaScript is not a secure way to validate private information, such as passwords and credit-card numbers. Any value you wanted to compare the user's entries to would need to be represented within the script, making it available to prying eyes simply by viewing the document source code.

A Little Math

JavaScript offers a whole host of mathematic operators and functions to help perform whatever computations you need within your scripts.

Operators

The first place to start is with the basic operators used by JavaScript. Like other features of Java and JavaScript, operators borrow their usage and syntax from the C and C+ programming languages.

Basic mathematical operators are called binary operators-they need two operands in order to function (see Table 35.1).

Table 35.1. JavaScript binary operators, in order of precedence.

Operator
Function
* / %
Multiplication, division, modulus
+ -
Addition, subtraction
<< >> >>>
Bitwise shift left, shift right, shift right/zero fill

There are a few on this list that might not be familiar to you. Modulus is a simple division process that returns only the remainder of the operation.


6 % 2 //Returns 0 (2 goes into 6 three times with no remainder)

6 % 4 //Returns 2 (4 goes into 6 once with two leftover)

The last set, bitwise operators, shift the bits representing a number left or right. The numbers on both sides are converted to 32-bit integers, and then the bits on the left are moved the number of positions indicated by the number on the right. Bits at the end are discarded.

Note
Remember bits and bytes from the early days of computers? They haven't gone away. JavaScript convert numbers in bitwise operations into 32-bit integers. For example, the number 156 is represented as 16 zeros plus 0000000010011100.
Each bit represents a power of two, beginning on the far right with 2^0 and ending with 2^31. To decipher the number, add up the value of each position with a 1. In the 156 example, moving from right to left you would add 0+0+4+8+16+0+0+128.

You can combine all of the binary operators with the assignment operator (=) to simplify other types of equations. For example, to increment a variable by 3 typically requires a statement such as


counter = counter + 3

This gets the job done, but it does require some extra typing. Combining the assignment and addition operator results in


counter += 3

The result is exactly the same. This processes the variable on the left and the value on the right using the operator, and it assigns the result to the variable.

The next set of operators you'll use most often are unary-they work on a single operand (see Table 35.2).

Table 35.2. JavaScript unary operators.

Operator
Function
++ --
Increment, decrement
!
Complement (Boolean)
-
Negation

The increment and decrement operators are used to increase or decrease the value of a number by one. The placement of the operator determines when the calculation takes place. If it is placed after the operand, the operation happens after any other calculation involving it is completed. If placed before, the value is updated, and then the rest of the calculation is finished.


count = 1

newValue = count++ //newValue = 1, count = 2

newValue = ++count //newValue = 3, count = 3

The complement is used to reverse the value of a Boolean. In the following example, if ready is false, then !ready is true. The text representation of the statement is, "If not ready then..." This is an easier representation than if (ready == false).


if (!ready) {

    ... }

The last operator reverses the sign of a number from positive to negative and vice versa.

Relational operators are used to compare two values and return a true or false. There are several different options, listing in Table 35.3.

Table 35.3. JavaScript relational operators.

Operator
Function
> <
Less than, greater than
<= >=
Less than or equal, greater than or equal
== !=
Equals, doesn't equal
?:
Conditional

The first three sets are easy enough to understand. The last one is a special use of the relation, and it is often used to assign a value to a variable. The full syntax is


condition ? value if true : value if false

This is a shorthand for an if-then-else statement. The condition portion of the statement is any operation that results in a Boolean true or false.

Tip
As an alternative to true and false, JavaScript also accepts 1 and 0, respectively. As a general rule, however, using a Boolean expression results in greater clarity.


status =   (age>=21) ? "Legal Drinking Age" : "Not Old Enough"

This statement evaluates the value of age. If the value is at least 21, then status is assigned the value Legal Drinking Age. If age is less than 21, then status is assigned Not Old Enough.

Functions and Constants

JavaScript includes a built-in object called Math. This object contains a whole host of useful functions and constants to save you time and typing. Here are a few of the items you'll find in Math.

First are the functions. These provide a handy method for easily computing several different types of equations:

In addition to the methods built into the Math object, a set of constant values is also supplied. Because these are not methods and do not accept arguments, they do not use parentheses.

These constant values represent values that are commonly used in math formulas. The most common of these is the value of pi-the ratio of the diameter of the circle to the circumference. The value is approximately 3.1415927 and referred to as Math.PI.

JavaScript Internet Resources

It never hurts to have a little help in this world, and working with new technologies and languages like JavaScript is no different. In addition to the resources listed at the end of Chapter 34, here are some other sites you should take a look at to help get you up to speed and productive with scripting on your Web pages.

Netscape

It was mentioned in the last chapter, but it never hurts to mention it again. Netscape developed JavaScript. If you want the latest information on what's new with the language, it always helps to look here. The complete JavaScript online documentation, located at http://home.netscape.com/eng/mozilla/3.0/handbook/javascript/index.html (see Figure 35.4), is no longer available for an easy download, but you can save the pages for offline use.

Figure 35.4: The Netscape site has an online manual on JavaScript, including information on integrating Java and JavaScript.

Voodoo JavaScript Tutorial

The Voodoo JavaScript Tutorial (see Figure 35.5) contains a set of lessons covering the various aspects of including JavaScript on your Web pages. This project continues to evolve (with new lessons added periodically), so you may want to check back to see what's new.

Figure 35.5: The Voodoo JavaScript tutorial provides a good place to pick up the basics of working with JavaScript, in addition to other HTML features such as frames.

You won't find much in the way of advanced material here, but what you find gives you more than enough to get beyond the beginner level.

You can access the site at http://rummelplatz.uni-mannheim.de/~skoch/js/index.htm.

JavaScript Newsgroup

This group is frequented by many of the JavaScript gurus, and it provides an excellent source of information, tips, and workarounds. A high level of activity occurs and the threads move quickly, so make sure to check every day if possible.

You can reach the JavaScript Newsgroup at news://comp.lang.javascript.

netscape.navigator

It never hurts to have a direct line monitored by the folks who developed JavaScript at Netscape, and netscape.navigator remains the closest thing to that line. JavaScript topics are definitely in the minority in this group, but you can find them if you look.

Note the different news server. The title implies it's secure, but it seems to be readily available for browsing and posting.

To get there, go to: news://secnews.netscape.com.

JavaScript Digest

Much like a chain letter, this site serves as a running interactive discussion similar to the newsgroup. Formerly available only in a digest format, it now also comes in a standard form.

To subscribe, send a message to listproc@inquiry.com with the message set javascript mail ack.

If you have problems receiving the digest, send a message to listproc@inquiry.com with the message body help. To unsubscribe to the list, send a message to listproc@inquiry.com with the message body unsubscribe JAVASCRIPT.

Summary

JavaScript is a lot like Java. If you understand Java already, you'll pick up JavaScript that much quicker. If this is your first outing with JavaScript after working with HTML, the learning process may last a little longer, but it is still within easy reach. Once you get used to an object-oriented view of the world, the rest of the process becomes much easier, and you're well on your way to creating interactive and useful Web pages that don't put a huge load on your server.