Learn java scripts, Javascripts, Java, Java with examples.

Earn Money for free

Thursday, October 30, 2008

Learn Java Scripts

Events in JavaScript

Now that you know how to organize programs using functions and build your own objects, you are ready to take a look at events.

Events provide the basis of interacting with the Navigator window and the currently loaded document. Events are triggered in the browser primarily by user actions, including finishing loading a page, entering data in a form, and clicking on form buttons.

Using event handlers built into JavaScript, you can write functions to perform specific actions based on the occurrence of selected events.

In this chapter, we will cover:

  • What events are
  • What event handlers are
  • How to use event handlers
  • How to emulate events
  • The load and unload events and the onLoad and onUnload event handlers
  • The basics of using events to interact with forms

What Are Events?

Events are signals generated when specific actions occur. JavaScript is aware of these signals and scripts can be built to react to these events.

Examples of events include when a user clicks on a hypertext link, changes data in a form entry field, or when a page finishes loading. A complete list of the events available in JavaScript appears in Table 5.1.

Table 5.1. Events in JavaScript.


Event


 

Description


 

blur

Occurs when input focus is removed from a form element (when the user clicks outside a field)

click

Occurs when the user clicks on a link or form element

change

Occurs when the value of a form field is changed by the user

focus

Occurs when input focus is given to a form element

load

Occurs when a page is loaded into Navigator

mouseover

Occurs when the user moves the pointer over a hypertext link

select

Occurs when the user selects a form element's field

submit

Occurs when a form is submitted (i.e. when the user clicks on a submit button)

unload

Occurs when the user leaves a page


 

New Term


Input focus refers to the act of clicking on or in a form element or field. This can be done by clicking in a text field or by tabbing between text fields.


 

What Are Event Handlers?

In order to take advantage of events in JavaScript, it is necessary to use event handlers. Event handlers are scripts, in the form of attributes of specific HTML tags, which you as the programmer can write.

The event handlers you write are executed when the specified events occur. The basic format of an event handler is:

<HTML_TAG OTHER_ATTRIBUTES eventHandler="JavaScript Program">

While any JavaScript statements, methods, or functions can appear inside the quotation marks of an event handler, typically, the JavaScript script that makes up the event handler is actually a call to a function defined in the header of the document or a single JavaScript command. Essentially, though, anything that appears inside a command block (inside curly braces ({}) can appear between the quotation marks).

For instance, if you have a form with a text field and want to call the function checkField() whenever the value of the text field changes, you could define your text field as follows:

<INPUT TYPE="text" onChange="checkField(this)">


 

The onChange event handler is one of many event handlers available in JavaScript. onChange and other event handlers are discussed in more depth later in this chapter.


 

Nonetheless, the entire code for the function could appear in quotation marks rather than a function call:

<INPUT TYPE="text" onChange="


 

if (parseInt(this.value) <= 5) {


 

alert('Please enter a number greater than 5.');


 

}


 

">

To separate multiple commands in an event handler, use semi-colons, as shown in the following lines:

<INPUT TYPE="text" onChange="


 

alert('Thanks for the entry.');


 

confirm('Do you want to continue?');


 

">

The advantage of using functions as event handlers, however, is that you can use the same event handler code for multiple items in your document and, (as you saw earlier in Chapter 4, "Functions and Objects"), functions make your code easier to read and understand.

For instance, you may have a form with several text entry fields and in each, the user can only enter numbers. You could use an event handler to check the value of any field if the content changes. By having a single function to check the value of a field, you don't have to write the complete code in the event handler for each text field.

this Keyword

Notice in the examples in the preceding section, that you used the this keyword which you first encountered when you learned to build your own objects in Chapter 4.

The this keyword refers to the current object. In the case of

<INPUT TYPE="text" onChange="checkField(this)">

this refers to the current field object. In JavaScript, forms are objects and, as you'll learn in Chapter 6, "Creating Interactive Forms," they have objects for each element as properties. These form elements include text fields, checkboxes, radio buttons, buttons, and selection lists.

Which Event Handlers Can Be Used?

The names of event handlers are directly connected to the events introduced earlier in the chapter. For instance, the click event is associated with the onClick event handler, and the load event with the onLoad event handler.

Table 5.2 outlines which window and form elements have event handlers available to them. All of these elements are dealt with later in this book when we cover forms, the document object, and the window object (see Chapter 8, "Frames, Documents, and Windows").

Table 5.2. Event handlers in JavaScript.


Object


 

Event Handlers Available


 

Selection List

onBlur, onChange, onFocus

Text Element

onBlur, onChange, onFocus, onSelect

Textarea Element

onBlur, onChange, onFocus, onSelect

Button Element

onClick

Checkbox

onClick

Radio Button

onClick

Hypertext Link

onClick, onMouseOver

Reset Button

onClick

Submit Button

onClick

Document

onLoad, onUnload

Window

onLoad, onUnload

Form

onSubmit

Emulating Events

In addition to event handlers, it is possible to emulate events. This can prove particularly useful to submit a form without requiring the user to click on a submit button or to force the input focus into a particular form field based on user actions.

For instance, if a clothing company had on its Web site an on-line order form for ordering designer clothes and it wanted to ensure that the users provided a name, address, phone number, and fax number before sending the order to the company's server for processing, then using event emulation could be useful.

When a user fills in the form and clicks on the Order button, a JavaScript script could then check if the form is correctly filled out. If it is, then it could emulate a submit event to cause the content of the form to be sent to the company's server.

On the other hand, if there is a missing piece of information, the script could alert the user and then emulate a focus event to put input focus into the text field in question.

The following list outlines the event methods available in JavaScript.


 

The select(), focus(), and blur(), methods display inconsistent behavior on different platforms. For instance, on Windows 95, blur() removes focus from a field but will leave the cursor displayed in the field even though users won't be able to enter information into the text field.


 

It is important to note that events generated with these methods do invoke their corresponding event handlers. This can lead to infinite loops, as illustrated in the following script:


 

Don't try to run this code! It is for illustration purposes only.


 

<HTML>


 

<HEAD>


 

<TITLE>Events</TITLE>


 

<SCRIPT>


 

<!-- HIDE FROM OTHER BROWSERS


 

function react(field) {


 

alert("Please Enter a Value");


 

field.focus();


 

}


 

// STOP HIDING FROM OTHER BROWSERS -->


 

</SCRIPT>


 

</HEAD>


 

<BODY>


 

<FORM METHOD=POST>


 

<INPUT TYPE=text NAME=stuff onFocus="react(this);">


 

</FORM>


 

</BODY>


 

</HTML>

You can see that because field.focus() invokes the onFocus event handler, you face a situation of infinite recursion with react() being continually called until it caused Navigator 2 to crash.

Using the onLoad and onUnload Event Handlers

The first events you will learn to work with are load and unload. The load event is generated when a page has completed loading. Likewise, the unload event occurs when the user exits a page.

The onLoad and onUnload event handlers enable you to script JavaScript program code to execute at these times. The onLoad event handler, for instance, enables you to be sure a page has loaded completely, including associated graphics, before executing the event handler.

This ability to control the timing of certain actions is important. For instance, if you want an alert message to appear after a page has loaded, it would be simple to place a script at the end of the HTML file. However, it is still possible for the alert box to appear before the page, particularly in-line graphics, has completely loaded and been displayed on the screen.

The onLoad event solves that problem. Similarly, onUnload enables a script to be executed before a new page loads.

The onLoad and onUnload events are used as an attribute of the BODY HTML tag. For instance, in

<BODY onLoad="hello()" onUnload="goodbye()">

the function hello() is executed after the page is loaded and goodbye() is called when the page is exited.

In Listing 5.1, you simply generate a welcome message after a page has loaded and generate a farewell message when the user decides to move on to another page.

Input

Listing 5.1. Using the onLoad and onUnload event handlers.

<HTML>


 

<HEAD>


 

<TITLE>Example 5.1</TITLE>


 

</HEAD>


 

<BODY onLoad="alert('Welcome to my page!');"


 

onUnload="alert('Goodbye! Sorry to see you go!');">


 

<IMG SRC="title.gif">


 

</BODY>


 

</HTML>

Analysis

This script provides a simple example of how event handlers are used.

Once the page has completed loading, the onLoad event handler causes the welcome alert dialog box to be displayed. Then, when the user leaves the page, such as by opening another URL, the good-bye dialog box is displayed by the onUnload event handler.

This script could be expanded and personalized as you did in using the prompt() method in the "Welcome to Netscape Navigator 2!" examples earlier:

<HTML>


 

<HEAD>


 

<TITLE>Example 5.1</TITLE>


 

<SCRIPT LANGUAGE="JavaScript">


 

<!-- HIDE FROM OTHER BROWSERS


 

var name = "";


 

// STOP HIDING FROM OTHER BROWSERS -->


 

</SCRIPT>


 

</HEAD>


 

<BODY onLoad="


 

name = prompt('Enter Your Name:','Name');


 

alert('Greetings ' + name + ', welcome to my page!');"


 

onUnload=" alert(Goodbye ' + name + ', sorry to see you go!');">


 

<IMG SRC="title.gif">


 

</BODY>


 

</HTML>

Likewise, you could use functions for this script to make it easier to read:

<HTML>


 

<HEAD>


 

<TITLE>Example 5.1</TITLE>


 

<SCRIPT LANGUAGE="JavaScript">


 

<!-- HIDE FROM OTHER BROWSERS


 

// DEFINE GLOBAL VARIABLE


 

var name = "";


 

function hello() {


 

name = prompt('Enter Your Name:','Name');


 

alert('Greetings ' + name + ', welcome to my page!');


 

}


 

function goodbye() {


 

alert(Goodbye ' + name + ', sorry to see you go!');


 

}


 

// STOP HIDING FROM OTHER BROWSERS -->


 

</SCRIPT>


 

</HEAD>


 

<BODY onLoad="hello();" onUnload="goodbye();">


 

<IMG SRC="title.gif">


 

</BODY>


 

</HTML>

Web-Hopping with window.open()

In this example, you take a closer look at using the onLoad event handler for a more complex task. You are going to produce a random page. That is, when the user comes to the page a "Please Wait. . .Selecting Destination" message is displayed and shortly after that a randomly selected site from the Internet is loaded in a new window. In Listing 5.2, the program chooses from a list of five possible sites to jump to.

In order to achieve this, you need to use a new method: window.open(). The window.open() method takes two required arguments:

window.open("URL","window name")

The window.open() method is covered in more detail in Chapter 8 where we also discuss a third argument available for the window.open() method. For this example, you need to ensure that the window you open the URL in is the same one your message appeared in. Because you don't know how many windows are currently open when the user opens your Web page, you will open both the message and the subsequent URL in a new window by using window.open("URL","new_window_name").

Input

Listing 5.2. A random page selector.

<HTML>


 

<HEAD>


 

<TITLE>Example 5.2</TITLE>


 

<SCRIPT LANGUAGE="JavaScript">


 

<!-- HIDE FROM OTHER BROWSERS


 

function urlList(a,b,c,d,e) {


 

// DEFINE FIVE-ELEMENT OBJECT


 

this[0] = a;


 

this[1] = b;


 

this[2] = c;


 

this[3] = d;


 

this[4] = e;


 

}


 

function selectPage(list) {


 

// SELECT RANDOM PAGE


 

var today = new Date();


 

var page = today.getSeconds() % 5;


 

// MAKE page AN INTEGER (GET RID OF THE STUFF AFTER THE DECIMAL POINT


 

// OPEN PAGE


 

window.open(list[page],"Random_Page");


 

}


 

// DEFINE SELECTION LIST


 

choices = new urlList("http://www.yahoo.com",


 

"http://www.cnn.com",


 

"http://www.dataphile.com.hk",


 

"http://home.netscape.com",


 

"http://www.landegg.org/landegg");


 

// STOP HIDING FROM OTHER BROWSERS -->


 

</SCRIPT>


 

</HEAD>


 

<BODY onLoad = "selectPage(choices);">


 

<H1>


 

<HR>


 

Please Wait ... Selecting Page.


 

<HR>


 

</H1>


 

</BODY>


 

</HTML>

Analysis

In this example you learn several useful techniques. The script is built out of two functions and a main body of JavaScript code. The function urlList() is an object constructor used to build an array of five URL strings. It takes five arguments and builds a five-element array.

You will notice that you don't use any property names in defining the object, but instead use numeric indexes to reference each of the five properties. This is done because you will only be using numeric references throughout the script to access the URLs in the array.

The selectPage() function is a little more complex. The function generates a pseudo-random number by calculating the number of seconds modulo five. This produces an integer in the range of zero to four:

var today = new Date();


 

var page = today.getSeconds() % 5;

This number is then used in the command window.open(list[page],"Random_Page") to open the selected page in a new window called Random_Page.

Following the two functions, you define the five sites you have to choose from and store them in an array called choices. You use the constructor function urlList() to create the array.

Finally, the script contains a good example of using the onLoad event handler. The message Please Wait .. Selecting Page. is displayed in the original browser window and then selectPage() is called from the event handler. For users on slower dial-up connections, the message may display for a few seconds, and users on fast direct connections may barely have time to see the message.

Events and Forms

Now that you understand the basics of events, let's take a look at working with forms.

Today, most JavaScript programmers are using forms and event handlers to produce complex applications. The events generated by forms provide a fairly complete set of tools for reacting to user actions in forms.

Common Form Events

The most common events used for processing forms are the focus, blur and change events with their corresponding event handlers onFocus, onBlur and onChange. Using these events, it is possible for a program to keep track of when a user moves between fields in a form and when he or she changes the value of an input field.

Other Form Events

There are other events available in forms, which we will cover in Chapter 6 when we take a detailed look at working with forms. These include click and submit with their corresponding onClick and onSubmit event handlers.

Using Event Handlers with Form Tags

Event handlers are included as attributes of form and field tags. For instance, the following tag defines a text input field with three event handlers.

<INPUT TYPE=text NAME="test" VALUE="test"


 

onBlur="alert('Thank You!');"


 

onChange="check(this);">

When the user moves the focus out of the field by clicking anywhere outside the field (or using the tab button where there are multiple text fields in a form), an alert dialog box with the message Thank You! is displayed.

When the value of the field is changed, the function check() is called. This function would be defined elsewhere in the HTML page—probably in the header. Note the use of the this keyword to pass the current field object to the function.

You first saw the this keyword in Chapter 4, when you learned to build constructor functions. The this keyword refers to the current object. In the case of an event handler, this refers to the object the event handler applies to. For instance, in a form field definition, this refers to the object for the form element (which we discuss in the Chapter 6 in detail). You can then refer to properties and methods for the current object as this.methodName() or this.propertyName.

An Interactive Calculator

In this example, you will use event handlers and text input fields to produce a simple calculator. You will use a form which consists of two fields: one for the user to enter a mathematical expression and another for the results to be displayed.

If the user moves the focus into the results field, a prompt dialog box is displayed asking the user for a mathematical expression which is then displayed in the entry field with the evaluated result in the results field.

You already have learned all the methods, properties, and event handlers necessary to produce the script in Listing 5.3.

Input

Listing 5.3. Using event handlers to create a JavaScript calculator.

<HTML>


 

<HEAD>


 


<TITLE>Example 5.3</TITLE>


 

<SCRIPT LANGUAGE="JavaScript">


 

<!-- HIDE FROM OTHER BROWSERS


 

function calculate(form) {


 

form.results.value = eval(form.entry.value);


 

}


 

function getExpression(form) {


 

form.entry.blur();


 

form.entry.value = prompt("Please enter a JavaScript mathematical expression","");


 

calculate(form);


 

}


 

// STOP HIDING FROM OTHER BROWSERS -->


 

</SCRIPT>


 

</HEAD>


 

<BODY>


 

<FORM METHOD=POST>


 

Enter a JavaScript mathematical expression:


 

<INPUT TYPE=text NAME="entry" VALUE=""


 

onFocus="getExpression(this.form);">


 

<BR>


 

The result of this expression is:


 

<INPUT TYPE=text NAME="results" VALUE=""


 

onFocus="this.blur();">


 

</FORM>


 

</BODY>


 

</HTML>

Analysis

There are several techniques employed in this script that are worth noting. In the HTML form, you have two fields, each with a single event handler. The entry field has an onFocus event handler which calls the function getExpression(), which handles the input of the expression. Notice that the function is passed this.form as an argument. Where this refers to the object for the current field in the HTML form, this.form refers to the object for the form containing the current field.

The second field's onFocus event handler calls this.blur() which immediately removes focus so that the user cannot alter the contents of the field. Remember that on some platforms, the cursor will actually appear in the field, but the user will be unable to enter information.

The getExpression() function takes a single form object as an argument. The first thing it does is remove focus from the entry field. You do this so you don't get into an infinite loop with the prompt dialog box. If you don't, then focus is removed from the field when the dialog box appears and returns to the field when the dialog box closes. This triggers another focus event and would invoke the event handler again.

After you remove focus from the entry field, you prompt the user for an expression and store the results in the entry field to display them. Then you call the function calculate() and pass it the form object.

The calculate() function uses the eval() function to calculate the result of the expression in the entry field and displays the result in the appropriate field in the form.

Throughout both functions, you will notice that you can refer to particular fields in a form as properties of the form object:

formObjectName.fieldname

Likewise, you can directly address, and change, the value of a field by using its value property (remember that while fields are properties of the form object, they are objects in their own right with properties of their own):

formObjectName.fieldname.value

It is also important to realize that with JavaScript, authors often want to create forms that actually do not submit any data back to the server with the ACTION attribute of the FORM tag. For instance, a JavaScript application may implement a simple currency calculator that uses HTML forms for its interface. All calculations and displaying of the results are done by a JavaScript script, and the contents of the forms never need to be sent to the server.

To accommodate this use of forms, it is sufficient to have no attributes in the FORM tag or to simply have the METHOD=POST attribute without an ACTION attribute in the FORM tag.

End of Analysis

Summary

In this chapter, you have made a big step toward being able to write the type of interactive Web pages and scripts that JavaScript is widely used for today.

You learned about events and event handlers. Event handlers react to actions by the user or events generated by the browser. Scripts can also emulate many events such as the click() method and submit() method.

In particular, you used the onLoad and onUnload event handlers to react to the loading of the page and the user opening another URL. You also began to look at events in relationship to HTML forms and learned to use onFocus, onBlur and onChange.

In Chapter 6, you look at the forms object in more detail and work more with the events and event handlers in relationship to forms.

Commands and Extensions Review

Command/Extension


 

Type


 

Description


 

blur()

JavaScript method

Removes focus from a specified object

click()

JavaScript method

Emulates a mouse click on an object

focus()

JavaScript method

Emulates the user focusing on a particular form field

submit()

JavaScript method

Emulates a click on the submit button of a form

select()

JavaScript method

Selects the input area of a particular form field

onLoad

Event Handler

Specifies JavaScript code to execute when a page finishes loading

onUnload

Event Handler

Specifies JavaScript code to execute when the user opens a new URL

Math.random()

JavaScript method

Generates a random number between 0 and 1

Math.sqrt()

JavaScript method

Calculates the square root of a number

window.open()

JavaScript method

Opens a URL in a named window or frame

Math.round()

JavaScript method

Rounds a floating point value to the closest integer

onFocus

Event Handler

Specifies JavaScript code to execute when the user gives focus to a form field

onBlur

Event Handler

Specifies JavaScript code to execute when the user removes focus from a form field

onChange

Event Handler

Specifies JavaScript code to execute when the user changes the value of a form field

Q&A

Q: Can I ensure my page elements, including large graphics and
tables, have been displayed before the onLoad script is

executed?

A: Yes. onLoad is executed when all elements of the page have
been loaded and displayed.

Q: You used getSeconds() to simulate a random number. I have
seen a random number method in other languages such as Perl.
Does JavaScript have one?

A: Yes and No. According to the specifications of JavaScript, the
Math object will include a random() method. However, in the
release of Navigator 2.0 currently available, the method is
only implemented on the UNIX platforms.

Exercises

  1. Which of the following are legitimate uses of event handlers?

    a. <BODY onClick="doSomething();">

    b. <INPUT TYPE=text onFocus="doSomething();">

    c. <INPUT TYPE=textarea onLoad="doSomething();">

    d. <BODY onUnload="doSomething();">

    e. <FORM onLoad="doSomething();">

    f. <FORM onSubmit="doSomething();">
  2. What happens with the following script?

    <HTML>

    <HEAD>
    <TITLE>Exercise 5.2</TITLE>

    <SCRIPT LANGUAGE="JavaScript">
    <!-- HIDE FROM OTHER BROWSERS

    var name = "";

    function welcome() {

    name = prompt("Welcome to my page! What's Your Name?","name");

    }

    function farewell() {

    alert("Goodbye " + name + ". Thanks for visiting my page.");

    }

    // STOP HIDING FROM OTHER BROWSERS -->
    </SCRIPT>

    </HEAD>

    <BODY onLoad="welcome();" onUnload="farewell();";>

    <IMG SRC="welcome.gif">

    </BODY>

    </HTML>
  3. Create an HTML page and JavaScript script that includes a form with three input fields. The relationship of the value of the fields is that the second field is twice the value of the first field, and the third field is the square of the first field.

    If a user enters a value in the second or third field, the script should calculate the appropriate value in the other fields.


 

To make this script easier, you will probably want to use the Math.sqrt() method, which returns the square root of the argument passed to it.


 

Answers

  1. Lines b, d, and f are valid according to Table 5.2. Choices a, c, and e all use event handlers which are not available for the particular objects in question.
  2. The script welcomes the user and asks for a name after the page (and graphic) have loaded. When the user moves on to another URL, a good-bye message is displayed in an alert dialog box.
  3. The following script would achieve the desired results:

    <HTML>

    <HEAD>
    <TITLE>Exercise 5.3</TITLE>

    <SCRIPT>
    <!-- HIDE FROM OTHER BROWSERS

    function calculate(form) {

    form.twice.value = form.entry.value * 2;
    form.square.value = form.entry.value * form.entry.value;

    }

    // STOP HIDING FROM OTHER BROWSERS -->
    </SCRIPT>

    </HEAD>

    <BODY>

    <FORM METHOD=POST>

    Value: <INPUT TYPE=text NAME="entry" VALUE=0
    onChange="calculate(this.form);">
    <BR>
    Double: <INPUT TYPE=text NAME="twice" VALUE=0
    onChange="this.form.entry.value = this.value / 2; calculate(this.form);">
    <BR>
    Square: <INPUT TYPE=text NAME="square" VALUE=0
    onChange="this.form.entry.value = Math.sqrt(this.value); calculate(this.form);">

    </FORM>

    </BODY>

    </HTML>



    Notice the use of the this.form argument again in the calls to the calculate() function. In addition, the onChange event handlers for both the double and square fields have multiple line scripts for their event handlers. The semi-colons separate the lines of the script, even though the script appears on a single physical line.

    The onChange event handlers in both the double and square fields first calculate the value of the entry field and then call calculate() which calculates the value of both double and square based on the value of the entry field. While this technique works, it has a couple of problems.

    First, you end up replacing the value the user has entered in the double or square field with a new value calculated when you call calculate(). This is an extra, unnecessary step.

    Second, due to limitations in floating point calculations, it is possible that if a user enters a value in the square field, for example, the result of calculating the square root and then recalculating the value of the square field may produce a result slightly different from the original value the user entered.

    This can be remedied with the following script. At first glance, these changes make the script seem more complex, but they stop the script from calculating the value the user has just entered, preventing both these problems.

    <HTML>

    <HEAD>
    <TITLE>Exercise 5.3</TITLE>

    <SCRIPT>
    <!-- HIDE FROM OTHER BROWSERS

    function calculate(form,currentField) {

    if (currentField == "square") {
    form.entry.value = Math.sqrt(form.square.value);
    form.twice.value = form.entry.value * 2;
    } else if (currentField == "twice") {
    form.entry.value = form.twice.value / 2;
    form.square.value = form.entry.value * form.entry.value;
    } else {
    form.twice.value = form.entry.value * 2;
    form.square.value = form.entry.value * form.entry.value;
    }

    }

    // STOP HIDING FROM OTHER BROWSERS -->
    </SCRIPT>

    </HEAD>

    <BODY>

    <FORM METHOD=POST>

    Value: <INPUT TYPE=text NAME="entry" VALUE=0
    onChange="calculate(this.form,'entry');">
    Double: <INPUT TYPE=text NAME="twice" VALUE=0
    onChange="calculate(this.form,'twice');">
    Square: <INPUT TYPE=text NAME="square" VALUE=0
    onChange="calculate(this.form,'square');">

    </FORM>

    </BODY>

    </HTML>

    Here you see that you have added a second argument passing an indicator of which field's event handler called the calculate() function. The function uses this in a complex if ... else construct to do only the necessary calculations and not rewrite the values just entered by the users.

    The if ... else construct used in the calculate() function shows how it is possible to have more than one alternative:

    if (condition1) {
    JavaScript commands
    } else if (condition2) {
    JavaScript commands
    } else if (condition3) {
    JavaScript commands
    } else {
    JavaScript commands
    }

    This example can be extended to any number of conditions.

    The script can be made easier to use and more general purpose by using the name property of the text field object. For instance, you can pass this.name to the function in all three event handlers (because the current object in each case is a text field):

    <FORM METHOD=POST>

    Value: <INPUT TYPE=text NAME="entry" VALUE=0
    onChange="calculate(this.form,this.name);">
    Double: <INPUT TYPE=text NAME="twice" VALUE=0
    onChange="calculate(this.form,this.name);">
    Square: <INPUT TYPE=text NAME="square" VALUE=0
    onChange="calculate(this.form,this.name);">

    </FORM>

Learn JavaScripts

Strings, Math, and the History List

Up to this point in the book, you have learned about the major objects and tools of JavaScript. Even so, this leaves several useful objects undiscovered.

In this chapter you are going to take a detailed look at some of the objects that you have been introduced to only briefly earlier in the book. These include the string object, the Math object and the history object.

Every string in JavaScript is an object. The string object offers properties and methods to perform a variety of manipulations on a given string. These include methods for searching a string, extracting substrings and applying HTML tags to the content of the string.

The Math object provides those functions and methods necessary to perform mathematical calculations. These range from the PI value to methods for all the trigonometric functions.

The history object is a bit different in that it doesn't involve the manipulation of information the way the string and Math objects do. The history object reflects the information in the browser's history list.

In this chapter you will learn the details of each of these object's properties and methods plus:

The string Object

You already have considerable experience working with strings. You have used them throughout the book, you understand how to represent string literals, and you even know some of the basic techniques for examining the content of strings.

Even with the substring() and indexOf() methods which you have seen earlier, though, you haven't reached the true possibilities of working with the string object.

The length Property

The string object only has one property: length. The length property is an integer value reflecting the number of characters in the string. Because the index of the first character in a string is zero, this means the length property is one greater than the index of the last character in the string.

For example, the string "Hello" has a length of five. The index of the first character ("H") is 0 and the index of the last character ("o") is 4.

Methods of the string Object

The flexibility and power of the string object rests in the wide variety of methods available to manipulate the content of the string. Table 10.1 outlines the methods available in the string object.

Table 10.1. Methods of the string object.


Name


 

Description


 

anchor()

Surrounds the string with an anchor A tag

big()

Surrounds the string with the HTML BIG tag.

blink()

Surrounds the string with the HTML BLINK tag.

bold()

Surrounds the string with the HTML B tag.

charAt()

Given an index as an argument, returns the character at the specified index.

fixed()

Surrounds the string with the HTML TT tag to make it display as a fixed-width font.

fontcolor()

Surrounds the string with the HTML <FONT COLOR=color> and </FONT> tags to make it display in the specified color.

fontsize()

Surrounds the string with the HTML <FONT SIZE=size> and </FONT> tags to make it display in the desired font size.

indexOf()

Given a string and an initial index, returns the index of the next occurrence of the string after the initial index.

italics()

Surrounds the string with the HTML I tag.

lastIndexOf()

Given a string and a starting index, returns the index of the last occurrence of the string starting the search backwards at the starting index.

link()

Given a URL, surrounds the string with an A tag to create a hypertext link.

small()

Surrounds the string with the HTML SMALL tag.

strike()

Surrounds the string with the HTML STRIKE tag.

sub()

Surrounds the string with the HTML SUB tag.

substring()

Given two indexes, returns the substring starting at the first index and ending with the character before the last index. If the second index is greater, the substring starts with the second index and ends with the character before the first index; if the two indexes are equal, returns the empty string.

sup()

Surrounds the string with the HTML SUP tag.

toLowerCase()

Makes the entire string lowercase.

toUpperCase()

Makes the entire string uppercase.

The HTML Methods

As you can see in Table 10.1, many of the methods of the string object are designed to add HTML tags to the content of the string so that when you display the string, it is suitably formatted. This can make the JavaScript code easier to read than if all the string assignments contained HTML tags, with the actual text to be displayed using document.write() or document.writeln().

The way these functions work is to return a new string containing the additional HTML tags. So, if you have a string named sample with the value "test", sample.big() returns "<BIG>test</BIG>" but sample still has a value of "test".

For instance, the following JavaScript commands output the text "Hello!" in large, blinking, bold letters

var sample = "Hello!";


 

var sampleBig = sample.big();


 

var sampleBlink = sampleBig.blink();


 

var sampleBold = sampleBlink.bold();


 

document.write(sampleBold);

and the following text displays the same word but as a hypertext link to the file http://some.domain/some/file.html.

var sample = "Hello!";


 

sample = sample.link("http://some.domain/some/file.html");


 

document.write(sample);

Because these methods return strings, you can also string together a series of methods and rewrite the first example as

var sample = "Hello!";


 

document.write(sample.big().blink().bold());

To give you a better idea of what these methods actually do to the content of your strings, the script in Listing 10.1 displays the actual content of the strings using the XMP tag to force the browser not to interpret any HTML in the output:

Input

Listing 10.1. Applying HTML tags with JavaScript's string object.

<HTML>


 

<HEAD>


 

<TITLE>HTML method example</TITLE>


 

</HEAD>


 

<BODY>


 

<SCRIPT LANGUAGE="JavaScript">


 

<!-- HIDE FROM OTHER BROWSERS


 

var sample = "hello";


 

document.write("<XMP>" + sample.italics() + "</XMP>");


 

document.write(sample.italics());


 

document.write("<XMP>" + sample.blink() + "</XMP>");


 

document.write(sample.italics());


 

document.write("<XMP>" + sample.anchor("test") + "</XMP>");


 

document.write(sample.anchor("test"));


 

document.write("<XMP>" + sample.fontsize(7) + "</XMP>");


 

document.write(sample.fontsize(7));


 

document.write("<XMP>" + sample.bold().strike() + "</XMP>");


 

document.write(sample.bold().strike());


 

document.write("<XMP>" + sample.fontcolor("iceblue").big().sup() + "</XMP>");


 

document.write(sample.fontcolor("iceblue").big().sup());


 

// STOP HIDING FROM OTHER BROWSERS -->


 

</SCRIPT>


 

</BODY>


 

</HTML>


 

Analysis

In this script, you are using various methods of the string object that the value returned by these methods. The script contains the examples in pairs of document.write() statements. The first output is the result of a method call surrounded by the XMP HTML container tags. The XMP tag ensures that any content inside the container is displayed without any processing. In this way, any HTML inside the container are simply displayed as regular text rather than treated as HTML.

The second line of each pair calls the same method but this time without the surrounding XMP tags so that the user can see what the result looks like when treated as HTML.

End of Analysis

The substring() Method

You have seen the substring() method several times in previous chapters. You first saw the substring() method in Exercise 6.3 when you used it to verify input in a form.

To review, the method takes two integer arguments and returns the string starting at the first argument and ending at the character before the second argument. Where the first argument is larger, the process is reversed and the substring starts at the second argument and continues until one before the first argument. When both arguments are equal, an empty string is returned.

For instance, if you have a string named sample with a value "Hello!", then sample.substring(0,3) is "Hel", sample.substring(3,0) is "Hel" and sample.substring(2,4) has the value "ll".

The Case Methods

The string object has two methods for changing the case of characters in a string. toLowerCase() returns a new string with all characters in lower case. Similarly, toUpperCase() returns a copy of the string with all characters upper case.

For instance, if the variable sample is "tEsT", then sample.toLowerCase() is "test" and sample.toUpperCase() is "TEST".

Using a combination of these methods and the substring() method, you can achieve more interesting results. If you want to take a string and make the first character upper case and the rest lower case, you could use the following technique:

var sample = "tEsT";


 

var newSample = sample.substring(0,1).toUpperCase() + sample.substring(1,sample.length).toLowerCase();

Other Methods

The string object has three other methods: indexOf(), lastIndexOf(), and charAt().

You saw the indexOf() method in Chapter 9, "XXX." Simply, given two arguments (a string and an index) the method starts searching the string object from the index and looks for the first occurrence of the string which has been passed to it as an argument. It returns the index of this occurrence.

This is best understood by example: If you have a string named sample with the value "Greetings! Welcome to Navigator 2.0! Enjoy!", then sample.indexOf("Wel",2) would return a value of 13 and sample.lastIndexOf("!",sample.length - 3) would return a value of 35.

What happens in the first example is that the method starts searching the string sample from index 2 (the first "e" in "Greetings"). It checks if the phrase "Wel" starts at that index and if not, it moves to the next character (index 3) and tries again. This is repeated until the character at index 13, where a match is found.

The send example is similar, but it moves backwards through the string looking for a match. In this case it starts at the 3 character from the end ("o" in "Enjoy") and moves back until it finds a "!".

The other method, charAt(), is almost the reverse of this process. Given an index as an argument, it returns the character at that location. This is easier to use to extract a single character from a string than the substring() method.

For instance, with the above string, both sample.charAt(3) and sample.substring(3,4) have the value of "e".

With these methods, you can now develop tools to enable users to play with HTML to see how it looks. Using two frames, you will build an application that enables the user to enter text in the left frame and select from a list of HTML attributes. They will see the text displayed with the combined attributes in the right frame, along with the actual HTML code needed to produce the results. Listings 10.2 through 10.4 contain the script files for the program.

In order to do this, you need a top-level frameset which looks like Listing 10.2.

Input

Listing 10.2. Top-level frameset.

<HTML>


 

<HEAD>


 

<TITLE>Listing 10.2</TITLE>


 

</HEAD>


 

<FRAMESET COLS="50%,*">


 

<FRAME SRC="htmlform.html" NAME="choose">


 

<FRAME SRC="sample.html" NAME="output">


 

</FRAMESET>


 

</HTML>

The htmlform.html file is where all the work is done.

Input

Listing 10.3. The htmlform.html file.

<HTML>


 

<HEAD>


 

<SCRIPT LANGUAGE="JavaScript">


 

<!-- HIDE FROM OTHER BROWSERS


 

function display(form) {


 

var format = form.toDisplay.value;


 

var doc = parent.output;


 

format = (form.big.checked) ? format.big() : format;


 

format = (form.blink.checked) ? format.blink() : format;


 

format = (form.bold.checked) ? format.bold() : format;


 

format = (form.fixed.checked) ? format.fixed() : format;


 

format = (form.italics.checked) ? format.italics() : format;


 

format = (form.small.checked) ? format.small() : format;


 

format = (form.strike.checked) ? format.strike() : format;


 

format = (form.sup.checked) ? format.sup() : format;


 

format = (form.sub.checked) ? format.sub() : format;


 

format = (form.color.value == "") ? format.fontcolor("black") : format.fontcolor(form.color.value);


 

format = (form.size.value == "") ? format.fontsize(3) : format.fontsize(form.size.value);


 

var result = "<CENTER>The HTML code: <XMP>";


 

result += format;


 

result += "</XMP> looks like:<P>"


 

result += format;


 

result += "</CENTER>";


 

doc.document.open("text/html");


 

doc.document.write(result);


 

doc.document.close();


 

}


 

// STOP HIDING -->


 

</SCRIPT>


 

<BODY BGCOLOR="aquamarine">


 

<CENTER>


 

<H1>The HTML tester page</H1>


 

Please enter some text, select some attributes and enter a color and size (from 1 to 7).


 

The display will update dynamically.


 

<BR>


 

</CENTER>


 

<FORM METHOD=POST>


 

<TEXTAREA NAME="toDisplay" ROWS=10 COLS=35 WRAP=SOFT onChange="display(this.form);">


 

Enter Text Here


 

</TEXTAREA><BR>


 

<INPUT TYPE="checkbox" NAME="big" onClick="display(this.form);">Big<BR>


 

<INPUT TYPE="checkbox" NAME="blink" onClick="display(this.form);">Blinking<BR>


 

<INPUT TYPE="checkbox" NAME="bold" onClick="display(this.form);">Bold<BR>


 

<INPUT TYPE="checkbox" NAME="fixed" onClick="display(this.form);">Fixed Width<BR>


 

<INPUT TYPE="checkbox" NAME="italics" onClick="display(this.form);">Italics<BR>


 

<INPUT TYPE="checkbox" NAME="small" onClick="display(this.form);">Small<BR>


 

<INPUT TYPE="checkbox" NAME="strike" onClick="display(this.form);">Striked Out<BR>


 

<INPUT TYPE="checkbox" NAME="sub" onClick="display(this.form);">Subscript<BR>


 

<INPUT TYPE="checkbox" NAME="sup" onClick="display(this.form);">SuperScript<BR>


 

Font Color: <INPUT TYPE="text" NAME="color" VALUE="black" onChange="display(this.form);"><BR>


 

Font Size (1 to 7): <INPUT TYPE="text" NAME="size" VALUE="3" onChange="display(this.form);">


 

</FORM>


 

<SCRIPT LANGUAGE="JavaScript">


 

<!-- HIDE FROM OTHER BROWSERS


 

display(document.forms[0]);


 

// STOP HIDING -->


 

</SCRIPT>


 

</BODY>


 

</HTML>

The file sample.html is just a blank HTML file to fill the window when the frame is initially loaded.

Input

Listing 10.4. The source code for sample.html.

<HTML>


 

<BODY BGCOLOR="#FFFFFF">


 

</BODY>


 

</HTML>

Analysis

This program not only highlights the effect of the previous example but also of some of the methods and techniques you learned in previous chapters.

All the work is done in the file htmlform.html (Listing 10.3). The program only really does one task—display information based on the content of a form—so only one function, display(), is necessary.

function display(form) {


 

var format = form.toDisplay.value;


 

var doc = parent.output;

You start by setting up the global variable format. You use this variable to hold the entire text and HTML tags to be tested. You start by assigning the content of the textarea input field, which contains the text you are going to test.

You also define doc to be equal to the object parent.output. parent.output refers to the second frame in the frameset and is effectively the window object for that frame. In this way, you can use doc instead of parent.output. For instance, doc.document.write() is the same as parent.output.document.write().

format = (form.big.checked) ? format.big() : format;


 

format = (form.blink.checked) ? format.blink() : format;


 

format = (form.bold.checked) ? format.bold() : format;


 

format = (form.fixed.checked) ? format.fixed() : format;


 

format = (form.italics.checked) ? format.italics() : format;


 

format = (form.small.checked) ? format.small() : format;


 

format = (form.strike.checked) ? format.strike() : format;


 

format = (form.sup.checked) ? format.sup() : format;


 

format = (form.sub.checked) ? format.sub() : format;


 

format = (form.color.value == "") ? format.fontcolor("black") : format.fontcolor(form.color.value);


 

format = (form.size.value == "") ? format.fontsize(3) : format.fontsize(form.size.value);

This section of code looks complex at first glance, but in reality, it is simple. You start by checking whether any of the checkboxes are checked. Because the checkbox object's checked property is a boolean value, you can use it as the condition for a conditional expression, which performs the appropriate method and then assigns the result back to format.

Next, you apply the appropriate fontcolor() and fontsize() methods based on the form content. If either field is empty, you use a default value.

var result = "<CENTER>The HTML code: <XMP>";


 

result += format;


 

result += "</XMP> looks like:<P>"


 

result += format;


 

result += "</CENTER>";


 

doc.document.open("text/html");


 

doc.document.write(result);


 

doc.document.close();

The final task is to output the results. The string result holds the complete output for the second frame. Then you use document.open() to open a new output stream in the second frame for the HTML MIME type. You write the results to the frame and close the stream with document.close().

<FORM METHOD=POST>


 

<TEXTAREA NAME="toDisplay" ROWS=10 COLS=35 WRAP=SOFT onChange="display(this.form);">


 

Enter Text Here


 

</TEXTAREA><BR>


 

<INPUT TYPE="checkbox" NAME="big" onClick="display(this.form);">Big<BR>


 

<INPUT TYPE="checkbox" NAME="blink" onClick="display(this.form);">Blinking<BR>


 

<INPUT TYPE="checkbox" NAME="bold" onClick="display(this.form);">Bold<BR>


 

<INPUT TYPE="checkbox" NAME="fixed" onClick="display(this.form);">Fixed Width<BR>


 

<INPUT TYPE="checkbox" NAME="italics" onClick="display(this.form);">Italics<BR>


 

<INPUT TYPE="checkbox" NAME="small" onClick="display(this.form);">Small<BR>


 

<INPUT TYPE="checkbox" NAME="strike" onClick="display(this.form);">Striked Out<BR>


 

<INPUT TYPE="checkbox" NAME="sub" onClick="display(this.form);">Subscript<BR>


 

<INPUT TYPE="checkbox" NAME="sup" onClick="display(this.form);">SuperScript<BR>


 

Font Color: <INPUT TYPE="text" NAME="color" VALUE="black" onChange="display(this.form);"><BR>


 

Font Size (1 to 7): <INPUT TYPE="text" NAME="size" VALUE="3" onChange="display(this.form);">

The form is simple. When any text field changes, you call display() and when any checkbox is clicked, you also call display(). No buttons are needed.


 

When using a form with no buttons like this, it is important to realize that in the version of Navigator 2.0 currently available, it is necessary to remove focus from a text field for a change event to be triggered.


 

<SCRIPT LANGUAGE="JavaScript">


 

<!-- HIDE FROM OTHER BROWSERS


 

display(document.forms[0]);


 

// STOP HIDING -->


 

</SCRIPT>

You end the body of the HTML file with a one-line script that calls display() for the first time to update the second frame with the contents of the form. This also could have been done in the onLoad event handler.

End of Analysis

Creating Search and Replace Tools

Anyone familiar with UNIX will miss many of the powerful text searching and matching tools found in the operating system and in scripting languages such as Perl, Awk, and sed. Although JavaScript provides the indexOf(), lastIndexOf(), charAt(), and substring() methods to help manipulate string contents, it doesn't provide powerful search and replace capabilities.

In this example, you extend the functionality of JavaScript's text manipulation capabilities with simple search and replace functions.

The search function should be able to search for words both in a case sensitive and case insensitive manner and should be able to search for whole words or substrings in words. Likewise, the replace function should be able to replace a word or substring, paying attention to case in the original text or ignoring it.

The search function should return true or false, and the replace function should return a new string with the result of the replace.

Listing 10.5 is the source code for these search and replace functions.

Input

Listing 10.5. Searching and replacing in JavaScript.

<SCRIPT LANGUAGE="JavaScript">


 

<!-- HIDE FROM OTHER BROWSERS


 

// SET UP ARGUMENTS FOR FUNCTION CALLS


 

//


 

var caseSensitive = true;


 

var notCaseSensitive = false;


 

var wholeWords = true;


 

var anySubstring = false;


 

// SEARCH FOR A TERM IN A TARGET STRING


 

//


 

// search(targetString,searchTerm,caseSensitive,wordOrSubstring)


 

//


 

// where caseSenstive is a boolean value and wordOrSubstring is a boolean


 

// value and true means whole words, false means substrings


 

//


 

function search(target,term,caseSens,wordOnly) {


 

var ind = 0;


 

var next = 0;


 

if (!caseSens) {


 

term = term.toLowerCase();


 

target = target.toLowerCase();


 

}


 

while ((ind = target.indexOf(term,next)) >= 0) {


 

if (wordOnly) {


 

var before = ind - 1;


 

var after = ind + term.length;


 

if (!(space(target.charAt(before)) && space(target.charAt(after)))) {


 

next = ind + term.length;


 

continue;


 

}


 

}


 

return true;


 

}


 

return false;


 

}


 

// SEARCH FOR A TERM IN A TARGET STRING AND REPLACE IT


 

//


 

// replace(targetString,oldTerm,newTerm,caseSensitive,wordOrSubstring)


 

//


 

// where caseSenstive is a boolean value and wordOrSubstring is a boolean


 

// value and true means whole words, false means substrings


 

//


 

function replace(target,oldTerm,newTerm,caseSens,wordOnly) {


 

var work = target;


 

var ind = 0;


 

var next = 0;


 

if (!caseSens) {


 

oldTerm = oldTerm.toLowerCase();


 

work = target.toLowerCase();


 

}


 

while ((ind = work.indexOf(oldTerm,next)) >= 0) {


 

if (wordOnly) {


 

var before = ind - 1;


 

var after = ind + oldTerm.length;


 

if (!(space(work.charAt(before)) && space(work.charAt(after)))) {


 

next = ind + oldTerm.length;


 

continue;


 

}


 

}


 

target = target.substring(0,ind) + newTerm + target.substring(ind+oldTerm.length,target.length);


 

work = work.substring(0,ind) + newTerm + work.substring(ind+oldTerm.length,work.length);


 

next = ind + newTerm.length;


 

if (next >= work.length) { break; }


 

}


 

return target;


 

}


 

// CHECK IF A CHARACTER IS A WORD BREAK AND RETURN A BOOLEAN VALUE


 

//


 

function space(check) {


 

var space = " .,/<>?!`';:@#$%^&*()=-|[]{}" + '"' + "\\\n\t";


 

for (var i = 0; i < space.length; i++)


 

if (check == space.charAt(i)) { return true; }


 

if (check == "") { return true; }


 

if (check == null) { return true; }


 

return false;


 

}


 

// STOP HIDING -->


 

</SCRIPT>

To demonstrate how these functions work, you can set up a simple search and replace application using the functions in Listing 10.6

Input

Listing 10.6. Using the search and replace functions.

<HTML>


 

<HEAD>


 

<TITLE>Listing 10.6</TITLE>


 

<SCRIPT LANGUAGE="JavaScript">


 

<!-- HIDE FROM OTHER BROWSERS


 

// SET UP ARGUMENTS FOR FUNCTION CALLS


 

//


 

var caseSensitive = true;


 

var notCaseSensitive = false;


 

var wholeWords = true;


 

var anySubstring = false;


 

// SEARCH FOR A TERM IN A TARGET STRING


 

//


 

// search(targetString,searchTerm,caseSensitive,wordOrSubstring)


 

//


 

// where caseSenstive is a boolean value and wordOrSubstring is a boolean


 

// value and true means whole words, false means substrings


 

//


 

function search(target,term,caseSens,wordOnly) {


 

var ind = 0;


 

var next = 0;


 

if (!caseSens) {


 

term = term.toLowerCase();


 

target = target.toLowerCase();


 

}


 

while ((ind = target.indexOf(term,next)) >= 0) {


 

if (wordOnly) {


 

var before = ind - 1;


 

var after = ind + term.length;


 

if (!(space(target.charAt(before)) && space(target.charAt(after)))) {


 

next = ind + term.length;


 

continue;


 

}


 

}


 

return true;


 

}


 

return false;


 

}


 

// SEARCH FOR A TERM IN A TARGET STRING AND REPLACE IT


 

//


 

// replace(targetString,oldTerm,newTerm,caseSensitive,wordOrSubstring)


 

//


 

// where caseSenstive is a boolean value and wordOrSubstring is a boolean


 

// value and true means whole words, false means substrings


 

//


 

function replace(target,oldTerm,newTerm,caseSens,wordOnly) {


 

var work = target;


 

var ind = 0;


 

var next = 0;


 

if (!caseSens) {


 

oldTerm = oldTerm.toLowerCase();


 

work = target.toLowerCase();


 

}


 

while ((ind = work.indexOf(oldTerm,next)) >= 0) {


 

if (wordOnly) {


 

var before = ind - 1;


 

var after = ind + oldTerm.length;


 

if (!(space(work.charAt(before)) && space(work.charAt(after)))) {


 

next = ind + oldTerm.length;


 

continue;


 

}


 

}


 

target = target.substring(0,ind) + newTerm + target.substring(ind+oldTerm.length,target.length);


 

work = work.substring(0,ind) + newTerm + work.substring(ind+oldTerm.length,work.length);


 

next = ind + newTerm.length;


 

if (next >= work.length) { break; }


 

}


 

return target;


 

}


 

// CHECK IF A CHARACTER IS A WORD BREAK AND RETURN A BOOLEAN VALUE


 

//


 

function space(check) {


 

var space = " .,/<>?!`';:@#$%^&*()=-|[]{}" + '"' + "\\\n\t";


 

for (var i = 0; i < space.length; i++)


 

if (check == space.charAt(i)) { return true; }


 

if (check == "") { return true; }


 

if (check == null) { return true; }


 

return false;


 

}


 

// STOP HIDING -->


 

</SCRIPT>


 

</HEAD>


 

<BODY>


 

<TABLE WIDTH=100%>


 

<TR>


 

<TD VALIGN=TOP>


 

<DIV ALIGN=CENTER>


 

<H1>Search</H1>


 

<FORM METHOD=POST>


 

<SCRIPT LANGUAGE="JavaScript">


 

<!-- HIDE FROM OTHER BROWSERS


 

function doSearch(form) {


 

var result = search(form.initial.value,form.term.value,form.casesens.checked,form.word.checked);


 

alert ((result) ? "Found!" : "Not Found!");


 

}


 

// STOP HIDING -->


 

</SCRIPT>


 

<TEXTAREA NAME="initial" ROWS=2 COLS=30>Search Text</TEXTAREA><BR>


 

Search For: <INPUT TYPE="text" NAME="term"><BR>


 

<INPUT TYPE="checkbox" NAME="casesens"> Case Sensitive


 

<INPUT TYPE="checkbox" NAME="word"> Whole Word Search<BR>


 

<INPUT TYPE="button" VALUE="SEARCH" onClick="doSearch(this.form);">


 

</FORM>


 

</DIV>


 

</TD>


 

<TD VALIGN=TOP>


 

<DIV ALIGN=CENTER>


 

<H1>Replace</H1>


 

<FORM METHOD=POST>


 

<SCRIPT LANGUAGE="JavaScript">


 

<!-- HIDE FROM OTHER BROWSERS


 

function doReplace(form) {


 

form.result.value = replace(form.initial.value,form.oldterm.value,form.newterm.value,form.casesens.checked,form.word.checked);


 

}


 

// STOP HIDING -->


 

</SCRIPT>


 

<TEXTAREA NAME="initial" ROWS=2 COLS=30>Search Text</TEXTAREA><BR>


 

<TEXTAREA NAME="result" ROWS=2 COLS=30>Result Text</TEXTAREA><BR>


 

Search For: <INPUT TYPE="text" NAME="oldterm"><BR>


 

Replace With: <INPUT TYPE="text" NAME="newterm"><BR>


 

<INPUT TYPE="checkbox" NAME="casesens"> Case Sensitive


 

<INPUT TYPE="checkbox" NAME="word"> Whole Word Search<BR>


 

<INPUT TYPE="button" VALUE="REPLACE" onClick="doReplace(this.form);">


 

</FORM>


 

</DIV>


 

</TD>


 

</TR>


 

</TABLE>


 

</BODY>


 

</HTML>

Analysis

You use three functions to implement the search and replace system: search(), replace(), and space().

search() and replace() use a similar approach to handling their tasks, but differ in the specific actions they take when they find the term they are looking for.

The replace() Function

The replace() function takes five arguments: the string to work on, the term to search for, the term to replace it with, and two boolean values. The two boolean values indicate whether to pay attention to the case of letters in searching and whether to search only for whole words (if not, substrings will be matched and replaced).

var work = target;


 

var ind = 0;


 

var next = 0;

As would be expected, you start by setting up the work variables.

if (!caseSens) {


 

oldTerm = oldTerm.toLowerCase();


 

work = target.toLowerCase();


 

}

Then you check if you are paying attention to case. If not, you change the search term and the string to search to lower case, using the toLowerCase() method. This means that case is ignored in the searches because any variation in case in either string has been removed.

while ((ind = work.indexOf(oldTerm,next)) >= 0) {


 

if (wordOnly) {


 

var before = ind - 1;


 

var after = ind + oldTerm.length;


 

if (!(space(work.charAt(before)) && space(work.charAt(after)))) {


 

next = ind + oldTerm.length;


 

continue;


 

}


 

}

All the work is done in the preceding while loop. In the condition of the while loop, you search the target string for the next occurrence of the search term, store the index in ind, and see if it is greater than zero.

If you have found an occurrence of the term, you next check if you are searching for whole words or substrings. If you are searching for whole words, you use the space() function to check if the characters before and after the word boundary are word breaks. If they aren't, you update next to the index of the character after the term you just found and start the loop again.

target = target.substring(0,ind) + newTerm + target.substring(ind+oldTerm.length,target.length);


 

work = work.substring(0,ind) + newTerm + work.substring(ind+oldTerm.length,work.length);


 

next = ind + newTerm.length;


 

if (next >= work.length) { break; }


 

}

If you reach this point in the loop, then you have found a term you want to replace. You use the substring method to update both the string itself and change the variable next to the index of the character after the term you have just added.

Finally, you check if you have reached the end of the target string and if not, you run the loop again to look for another occurrence.

The search() Function

This function is similar in structure to the replace() function. The differences lie in the while loop:

while ((ind = target.indexOf(term,next)) >= 0) {


 

if (wordOnly) {


 

var before = ind - 1;


 

var after = ind + term.length;


 

if (!(space(target.charAt(before)) && space(target.charAt(after)))) {


 

next = ind + term.length;


 

continue;


 

}


 

}


 

return true;


 

}


 

return false;

As before, you perform the search for the search term using the indexOf() method in the condition of the while loop. Again, you check if you are searching for whole words and if you are, you check for word boundaries. If you haven't found a complete word you prepare to search again and return to the top of the loop with the continue statement.

If you get beyond the if statements then you have found an occurrence of the term and return a true value from the function. If you finish the while loop without returning true, then you haven't found a match and you return a false value.

The space() Function

The space() function plays a support role for search() and replace().

Given a character as an argument, the function checks if it is one of a series of characters considered word breaks or delimiters. If it is, the function returns true—otherwise, it returns a false value.

The way this is done is simple. All the possible word breaks are stored in the string space. A for loop goes through the string character by character and compares each character to the argument. If there is a match, a true result is returned.

After the loop, a comparison is made between the argument and either the empty string or the null value. If these are true, the function returns a true value as well.

If you have failed all these conditions, then a false value is returned because the argument character is not a word break.

If the programmer wants to change the definition of a word break, they simply have to change the declaration of the variable space.

End of Analysis

The Math Object

Where the string object enables you to work with text literals, the Math object provides methods and properties to move beyond the simple arithmetic manipulations offered by the arithmetic operators.

Among the features offered by the Math object are several special values such as PI, natural logarithms, and common square roots, trigonometric methods, rounding methods, an absolute value method, and more.

Table 10.2 outlines all the properties and methods of the Math object.

Table 10.2. Properties and methods of the Math object.


Name


 

Description


 

E

Euler's constant—the base of natural logarithms (roughly 2.718).

LN10

The natural logarithm of 10 (roughly 2.302).

LN2

The natural logarithm of 2 (roughly 0.693).

PI

The ratio of the circumference of a circle to the diameter of the same circle (roughly 3.1415).

SQRT1_2

The square root of 1/2 (roughly 0.707).

SQRT2

The square root of 2 (roughly 1.414).

abs()

Calculates the absolute value of a number.

acos()

Calculates the arc cosine of a number—returns result in radians.

asin()

Calculates the arc sine of a number—returns result in radians.

atan()

Calculates the arc tangent of a number—returns result in radians.

ceil()

Returns the next integer greater than or equal to a number.

cos()

Calculates the cosine of a number.

exp()

Calculates e to the power of a number.

floor()

Returns the next integer less than or equal to a number.

log()

Calculates the natural logarithm of a number.

max()

Returns the greater of two numbers—takes two arguments.

min()

Returns the least of two numbers—takes two arguments

pow()

Calculates the value of one number to the power of a second number—takes two arguments.

random()

Returns a random number between zero and one. Presently, this is only implemented in UNIX versions of Navigator 2.0.

round()

Rounds a number to the nearest integer.

sin()

Calculates the sine of a number.

sqrt()

Calculates the square root of a number.

tan()

Calculates the tangent of a number.

Some of these functions require further discussion.

The Trigonometric Methods

You will notice that the trigonometric methods, such as acos() and sin() use radians to measure the size of angles instead of the more familiar degrees.

This isn't too difficult to handle. Where you have 360 degrees in a circle, there are 2xPI (or roughly 6.283) radians in a circle.

So, where the arc tangent of 1 is 45 degrees, in radians, the result is roughly 0.785398.

The log() and exp() Methods

The log() and exp() functions are related in that they use e, Euler's constant, as their base.

The relationship between logarithms and exponential expressions is that if log(a) = b, then exp(b) = a.

The abs() Method

The absolute value method returns the positive value of a number. That is, it removes a negative sign from a number so that abs(4) and abs(-4) both have a value of 4.

Calculating Geometric Measurements

To highlight some of those math functions, you are going to build a simple calculator that calculates the angles and the lengths of the sides of a right angle triangle and calculates the area, diameter, and circumference of a circle.

In order to do this, you will use the trigonometric functions and PI.

As a reminder, with a right angle triangle, if you want to calculates the sine, cosine, or tangent of any of the other two angles, you can use the following formulas:

sine = opposite side / hypotenuse

cosine = adjacent side / hypotenuse

tangent = opposite side / adjacent side

The script should be able to fill in all the information about the shapes when there is sufficient information in the relevant form. The results of Listing 10.7 look like Figure 10.4.

Input

Listing 10.7. Using the trigonometric functions.

<HTML>


 

<HEAD>


 

<TITLE>Example 10.3</TITLE>


 

<SCRIPT LANGUAGE="JavaScript">


 

<!-- HIDE FROM OTHER BROWSERS


 

function circle(form,changed) {


 

with (Math) {


 

var area = form.area.value;


 

var diameter = form.diameter.value;


 

var circumfrence = form.circumfrence.value;


 

if (changed == "area") {


 

var radius = sqrt(area / PI);


 

diameter = 2 * radius;


 

circumfrence = PI * diameter;


 

}


 

if (changed == "diameter") {


 

area = PI * (diameter / 2) * (diameter / 2);


 

circumfrence = PI * diameter;


 

}


 

if (changed == "circumfrence") {


 

diameter = circumfrence / PI;


 

area = PI * (diameter / 2) * (diameter / 2);


 

}


 

form.area.value = area;


 

form.diameter.value = diameter;


 

form.circumfrence.value = circumfrence;


 

}


 

}


 

var toDegrees = 360 / (Math.PI * 2);


 

var toRadians = (Math.PI * 2) / 360;


 

function angle(form,changed) {


 

with (Math) {


 

var angle = (changed == "angleA") ? form.angleA.value * toRadians : form.angleB.value;


 

var otherAngle = (90 * toRadians) - angle;


 

var hypotenuse = form.hypotenuse.value;


 

var sine = sin(angle);


 

var opposite = sine * hypotenuse;


 

var cosine = cos(angle);


 

var adjacent = cosine * hypotenuse;


 

if (changed == "angleA") {


 

form.angleB.value = otherAngle * toDegrees;


 

form.sideA.value = adjacent;


 

form.sideB.value = opposite;


 

} else {


 

form.angleA.value = otherAngle * toDegrees;


 

form.sideB.value = adjacent;


 

form.sideC.value = opposite;


 

}


 

}


 

}


 

function side(form,changed) {


 

with (Math) {


 

var side = (changed == "sideA") ? form.sideA.value : form.sideB.value;


 

var hypotenuse = form.hypotenuse.value;


 

var otherSide = sqrt(pow(hypotenuse,2) - pow(side,2));


 

var angle = acos(side/hypotenuse);


 

var otherAngle = acos(otherSide/hypotenuse);


 

if (changed == "sideA") {


 

form.sideB.value = otherSide;


 

form.angleA.value = angle * toDegrees;


 

form.angleB.value = otherAngle * toDegrees;


 

} else {


 

form.sideA.value = otherSide;


 

form.angleB.value = angle * toDegrees;


 

form.angleA.value = otherAngle * toDegrees;


 

}


 

}


 

}


 

function hyp(form) {


 

angle(form,"angleA");


 

}


 

// STOP HIDING FROM OTHER BROWSERS -->


 

</SCRIPT>


 

</HEAD>


 

<BODY>


 

<TABLE WIDTH="100%">


 

<TR>


 

<TD>


 

<H1>Circle</H1>


 

<FORM METHOD=POST>


 

Area: <INPUT TYPE="text" NAME="area" VALUE=0 onChange="circle(this.form,this.name);"><BR>


 

Diameter: <INPUT TYPE="text" NAME="diameter" VALUE=0 onChange="circle(this.form,this.name);"><BR>


 

Circumfrence: <INPUT TYPE="text" NAME="circumfrence" VALUE=0 onChange="circle(this.form,this.name);">


 

</FORM>


 

</TD>


 

<TD>


 

<H1>Triangle</H1>


 

<FORM METHOD=POST>


 

Angle A: <INPUT TYPE="text" NAME="angleA" VALUE=45 onChange="angle(this.form,this.name);"><BR>


 

Angle B: <INPUT TYPE="text" NAME="angleB" VALUE=45 onChange="angle(this.form,this.name);"><BR>


 

Side A: <INPUT TYPE="text" NAME="sideA" VALUE=1 onChange="side(this.form,this.name);"><BR>


 

Side B: <INPUT TYPE="text" NAME="sideB" VALUE=1 onChange="side(this.form,this.name);"><BR>


 

Hypotenuse: <INPUT TYPE="text" NAME="hypotenuse" VALUE=1.414 onChange="hyp(this.form);">


 

</FORM>


 

</TD>


 

</TR>


 

</TABLE>


 

</BODY>


 

</HTML>

This script is rather simple, but it shows how to use the methods and properties available in the Math object.

Of the two forms, the circle form is the simpler because it has less information to deal with. The following two sections analyze the two functions.

The circle() Function

The circle() function takes two arguments: the form object and the name of the field that was just changed. The calculations are based on the name of this field.

with (Math) {


 

var area = form.area.value;


 

var diameter = form.diameter.value;


 

var circumfrence = form.circumfrence.value;

You start by extracting whatever information is in the form and storing it in local variables. Notice the use of the with (Math) command. This enables all of the Math properties and methods in the function to be used without the Math prefix.


 

The with command makes it easy to write command blocks which use properties and methods of a single object repeatedly. For instance, if you use with (object) { command block } then inside the command block the methods and properties of object can be referred to as methodName and propertyName without the leading object.


 

if (changed == "area") {


 

var radius = sqrt(area / PI);


 

diameter = 2 * radius;


 

circumfrence = PI * diameter;


 

}


 

if (changed == "diameter") {


 

area = PI * (diameter / 2) * (diameter / 2);


 

circumfrence = PI * diameter;


 

}


 

if (changed == "circumfrence") {


 

diameter = circumfrence / PI;


 

area = PI * (diameter / 2) * (diameter / 2);


 

}

The three if statement blocks simply calculate the other two fields based on the value of the changed field. All of these use two basic formulas:

Area of Circle = PI x radius x radius

Circumference of Circle = PI x xdiameter

Notice the use of the sqrt() method without the preceding Math prefix, which is made possible with the earlier with (Math) command.

form.area.value = area;


 

form.diameter.value = diameter;


 

form.circumfrence.value = circumfrence;

Once the calculation is done, you can reassign the results to the form.

Working with the Triangle

The triangle function assumes that you are working with a right angle triangle. This means the angle across from the hypotenuse is always 90 degrees.

The relationship between the remaining angles and sides is that sideA is adjacent to angleA and sideB is adjacent to angleB.

Before you can proceed to calculate the information in this form, you need to be able to convert between degrees and radians. All the trigonometric functions either take a radian value as a parameter or return a radian value. Users, on the other hand, are likely to prefer working in degrees.

You get around this by using the variables toDegrees and toRadians which represent the number of degrees per radian and the number of radians per degree:

var toDegrees = 360 / (Math.PI * 2);


 

var toRadians = (Math.PI * 2) / 360;

The angle() function is called whenever you change one of the two angle values. It uses the fact that all the angles of a triangle add up to 180 degrees to calculate the remaining angle. Then, using the sin() and cos() methods and the formulas for sine and cosine, the program calculates the length of the opposite and adjacent sides for the changed angle.

Finally, based on which angle was changed, the results are assigned to the correct form field.

The side() function plays a similar role when either sideA or sideB is changed. Using the value of the changed side and the value of the hypotenuse, you can calculate the value of the third side using the formula

sideA x sideA + sideB x sideB = hypotenuse x hypotenuse

Once you have the value for the three sides, you can use the acos() method and the formula for cosine to calculate the value of the two angles.

The hypotenuse function simply calculates what the value of sideA and sideB should be based on the current angle settings by calling angle(form,"angleA"). You could just as easily have made the call angle(form,"angleB").

The forms in the body of the HTML file are fairly simple. They call the appropriate function in the onChange event handler for each text field.

End of Analysis

Working with the History List

When you use the Navigator browser, you will notice the history list which is accessible under the Go menu.

The history object makes this list accessible in JavaScript. Early versions of JavaScript made the actual URLs in the list available to the script, but this was too large a security hole because it could be used by malicious scripts to steal information to access some secure Web sites. In addition, it could be used to breach privacy by supplying a page author with information about what sites a visitor had previously been at.

The current version of the history object provides methods for working with the list without actually reflecting the value of URLs and entries into a script.

Properties and Methods of the history Object

Table 10.3 outlines the properties and methods available in the history object.

Table 10.3. Properties and methods of the history object.


Name


 

Description


 

length

The length of the history list

back()

Loads the previous URL in the history list

forward()

Loads the next URL in the history list

go()

Loads the URL indicated by an offset from the current place in the history list

For instance, history.back() goes to the previous page while history.go(-3) goes back to the page visited three pages ago (like clicking the Back button three times on the Navigator toolbar) and history.go(2) goes two URLs forward in the list.

The history.go() method can also take a string instead of an integer as an argument. When a string is used, the method loads the nearest entry in the history list which contains the string as part of its URL. The matching of the string against the URL is case insensitive.

One of the more popular uses of the history object is to provide back and forward buttons in individual frames or dynamic back buttons which take users back to the last page they were on.

Summary

Manipulating data has been the focus of much of this chapter.

Using the string object, you now know how to add HTML tags using methods, to change the case of a string and how to search for the string and perform basic search and replace functions.

The Math object enables you to extend the type of mathematical calculations you can perform to include trigonometry, logarithms, and square roots and also provides several values as properties including PI, E, and LN2.

The history object is a little different. By providing the ability to jump to URLs in the history list (without breaching security by providing the actual URL information), it is possible to build dynamic back and forward buttons into documents.

In the next chapter you will put everything you have learned together into producing a fun cartoon face drawing program.

Commands and Extensions Review

Command/Extension


 

Type


 

Description


 

anchor()

JavaScript method

Surrounds the string with an anchor A tag.

big()

JavaScript method

Surrounds the string with the HTML BIG tag.

blink()

JavaScript method

Surrounds the string with the HTML BLINK tag.

bold()

JavaScript method

Surrounds the string with the HTML B tag.

charAt()

JavaScript method

Given an index as an argument, returns the character at the specified index.

fixed()

JavaScript method

Surrounds the string with the HTML TT tag to make it display as a fixed-width font.

fontcolor()

JavaScript method

Surrounds the string with the HTML <FONT COLOR=color> and </FONT> tags to make it display in the specified color.

fontsize()

JavaScript method

Surrounds the string with the HTML <FONT SIZE=size> and </FONT> tags to make it display in the desired font size.

indexOf()

JavaScript method

Given a string and an initial index, returns the index of the next occurrence of the string after the initial index.

italics()

JavaScript method

Surrounds the string with the HTML I tag.

lastIndexOf()

JavaScript method

Given a string and a starting index, returns the index of the last occurrence of the string starting the search backward at the starting index.

link()

JavaScript method

Given a URL, surrounds the string with an A tag to create a hypertext link

small()

JavaScript method

Surrounds the string with the HTML SMALL tag.

strike()

JavaScript method

Surrounds the string with the HTML STRIKE tag.

sub()

JavaScript method

Surrounds the string with the HTML SUB tag.

substring()

JavaScript method

Given two indexes, returns the substring starting at the first index and ending with the character before the last index. If the second index is greater, the substring starts with the second index and ends with the character before the first index; if the two indexes are equal, returns the empty string.

sup()

JavaScript method

Surrounds the string with the HTML SUP tag.

toLowerCase()

JavaScript method

Makes the entire string lowercase.

toUpperCase()

JavaScript method

Makes the entire string uppercase.

E

JavaScript property

Euler's constant—the base of natural logarithms (roughly 2.718).

LN10

JavaScript property

The natural logarithm of 10 (roughly 2.302).

LN2

JavaScript property

The natural logarithm of 2 (roughly 0.693).

PI

JavaScript property

The ratio of the circumference of a circle to the diameter of the same circle (roughly 3.1415).

SQRT1_2

JavaScript property

The square root of 1/2 (roughly 0.707).

SQRT2

JavaScript property

The square root of 2 (roughly 1.414).

abs()

JavaScript method

Calculates the absolute value of a number.

acos()

JavaScript method

Calculates the arc cosine of a number—returns result in radians.

asin()

JavaScript method

Calculates the arc sine of a number—returns result in radians.

atan()

JavaScript method

Calculates the arc tangent of a number—returns result in radians.

ceil()

JavaScript method

Returns the next integer greater than or equal to a number.

cos()

JavaScript method

Calculates the cosine of a number.

exp()

JavaScript method

Calculates e to the power of a number.

floor()

JavaScript method

Returns the next integer less than or equal to a number.

log()

JavaScript method

Calculates the natural logarithm of a number.

max()

JavaScript method

Returns the greater of two numbers—takes two arguments.

min()

JavaScript method

Returns the least of two numbers—takes two arguments.

pow()

JavaScript method

Calculates the value of one number to the power of a second number—takes two arguments.

random()

JavaScript method

Returns a random number between zero and one. Presently, this is only implemented in UNIX versions of Navigator 2.0.

round()

JavaScript method

Rounds a number to the nearest integer.

sin()

JavaScript method

Calculates the sine of a number.

sqrt()

JavaScript method

Calculates the square root of a number.

tan()

JavaScript method

Calculates the tangent of a number.

length

JavaScript method

The length of the history list. Also used in the string object to provide the value of the string.

   

back()

JavaScript method

Loads the previous URL in the history list.

forward()

JavaScript method

Loads the next URL in the history list.

go()

JavaScript method

Loads the URL indicated by an offset from the current place in the history list.

Exercises

  1. What would the output of the following code segment look like assuming there were no HTML tags elsewhere in the file affecting the output?

    var sample = "test.";
    sample.big();
    sample.blink();
    sample.bold();
    sample.strike();
    sample.fontsize(7);
    document.write(sample.italics());
  2. In the text searching and replacing functions (Listing 10.X through 10.Y), we have left out a critical feature: a wildcard. Extend our search and replace script to add a simple wildcard capability to the search() function. Use the following criteria:

    Use the asterisk character for your wildcard.

    The wildcard represents zero or more of any letter.

    Only one wildcard is enabled in a search term.

    Wildcards are only valid in the middle of a search term: "text*" and "*text" are not valid—catch this and inform the user.

    If we search the string "Hello there" for "lo*e" we should get a match as we would with "H*lo", but "the*h" would not succeed.
  3. What are the lines of code necessary to implement a dynamic forward and back button in an HTML page. The buttons should work just like the ones in the Navigator toolbar. (Hint: you only need one form with two buttons to do this).

Answers

  1. The phrase "test." would print in italics. All the other method() calls are useless. Remember that these methods return the new value. They do not directly alter the string. So, the results of all the other method calls went unassigned and unused. If we change the code to read

    var sample = "test.";
    sample = sample.big();
    sample = sample.blink();
    sample = sample.bold();
    sample = sample.strike();
    sample = sample.fontsize(7);
    document.write(sample.italics());

    Then all the attributes will be applied to the displayed text.
  2. The new search function would look like this:

    function search(target,term,caseSens,wordOnly) {

    var ind = 0;
    var ind2 = 0;
    var next = 0;
    var wildcard = -1;
    var firstTerm = "";
    var secondTerm = "";

    if (!caseSens) {
    term = term.toLowerCase();
    target = target.toLowerCase();
    }

    if ((wildcard = term.indexOf("*",0)) >= 0) {

    if (!checkWildCards(term)) {
    alert("Improper use of the wildcard character.");
    return false;
    }

    firstTerm = term.substring(0,wildcard);
    secondTerm = term.substring(wildcard+1,term.length);

    while ((ind = target.indexOf(firstTerm,next)) >= 0) {
    var afterFirst = ind + firstTerm.length;

    ind2 = target.indexOf(secondTerm,afterFirst);
    if (ind2 < 0) { break; }

    if (wordOnly) {
    for (var i = ind+firstTerm.length; i <= ind2 - 1; i++)
    if (space(target.charAt(i))) {
    next = i + 1;
    continue;
    }

    var before = ind - 1;
    var after = ind2 + secondTerm.length;
    if (!(space(target.charAt(before)) && space(target.charAt(after)))) {
    next = ind2 + secondTerm.length;
    if (next >= target.length) { break; }
    continue;
    }
    }
    return true;
    }

    return false;

    }

    while ((ind = target.indexOf(term,next)) >= 0) {
    if (wordOnly) {
    var before = ind - 1;
    var after = ind + term.length;
    if (!(space(target.charAt(before)) && space(target.charAt(after)))) {
    next = ind + term.length;
    continue;
    }
    }
    return true;
    }

    return false;
    }

    You would also need to add the checkWildCards() function:

    function checkWildCards(term) {


    if (term.charAt(0) == "*") { return false; }

    if (term.charAt(term.length-1) == "*") { return false; }


    var first = term.indexOf("*",0);

    if (term.indexOf("*",first+1) >= 0) { return false; }


    return true;


    }


    You have not changed the basic functionality of the search() function. Rather, you have added a component in the middle which handles the wild card searches. If there is no wildcard in the search term, our search functions operates in the same way as it did before, simply bypassing the wildcard section.

    Assuming you have found a wildcard character, you perform an altered search which is based on the simple search performed when there is no wildcard.

    You start by checking that the use of the wildcard character is valid by calling checkWildCards(). If everything is correct, then you split the search term into two terms: the portion before the wildcard and the portion after it.
  3. You then search for the first term in the condition of the while loop. If the first term occurs, you look for the second term. If the second term isn't there, you have no match and break out of the loop. Otherwise, you check if you are doing a whole word search. If you are, the function performs a check on the character before the occurrence of the first term and after the occurrence of the second term for word delimiter characters using the space() function. You also check that there are no word delimiters between the two terms. If the search fails either of these tests, you jump back to the top of the loop to continue searching the target string.

    Otherwise, if you get past the wordOnly if statement, you know you have found a match and return a true value from the function.
  4. The code

    <FORM METHOD=POST>
    <INPUT TYPE=button VALUE="BACK" onClick="history.back();">
    <INPUT TYPE=button VALUE="FORWARD" onClick="history.forward();">
    </FORM>

    will implement dynamic forward and back buttons.