JavaScript SE: Chapter 7 Copyright ©1996, Que Corporation. All rights reserved. No part of this book may be used or reproduced in any form or by any means, or stored in a database or retrieval system without prior written permission of the publisher except in the case of brief quotations embodied in critical articles and reviews. Making copies of any part of this book for any purpose other than your own personal use is a violation of United States copyright laws. For information, address Que Corporation, 201 West 103rd Street, Indianapolis, IN 46290 or at support@mcp.com.

Notice: This material is excerpted from Special Edition Using JavaScript, ISBN: 0-7897-0789-6. The electronic version of this material has not been through the final proof reading stage that the book goes through before being published in printed form. Some errors may exist here that are corrected before the book is published. This material is provided "as is" without any warranty of any kind.


CHAPTER 7 - Advanced HTML Objects and Navigation

HTML Navigation Elements

Your users will demand quicker response time as you add more interactivity. Before JavaScript, most interactive features required your Web page to invoke a CGI script on the server. The more interactivity, the more the users have to wait on the server to deliver new documents. The response time improves dramatically as JavaScript handles interactivity on the browser side instead of waiting on CGI scripts.

To meet this increasing demand for better response time, you will increase the size of your Web documents with JavaScript. This is because your pages are more like applications and less like plain reading material. As your document gets larger, you will incorporate more navigational aids. You will create dynamic elements with JavaScript to let users quickly see the material they want and skip irrelevant information. And you will do this without waiting on the server.

Controlling the flow of user interaction is critical to good design. You can confuse your users with the multiple windows and frames possible in the new browsers. The dynamic capability of JavaScript allows you to create new documents in response to your users' preferences. For example, if the viewer selects a favorite sport, the hyperlink named "Last Year's Champion" could vary based on the viewer's selection.

With JavaScript features, you can transform the browser from static displays to interactive applications. There are a variety of examples in this chapter which let you try out the new dynamics of hyperlinks, anchors, and selection lists. The chapter concludes with a much larger application that shows you the possibilities of the new browser.

In this chapter, you will learn about the following:

Link In with JavaScript

Click and follow the designer's lead. That's how people navigate the Web: they follow the links chosen by the designer. Click the same link a hundred times and it takes you to the same page every time. Every user is different and has different expectations. For example, a link that's appropriate for an adult might be too complex for a young child.

This limitation of HTML drives many people to build "a better Web page." You probably looked at a few poorly designed Web pages and were frustrated by the hyperlinks designed into those pages. As a designer, you might have chosen other sites to link to. So people build other Web pages and try to make them perfect for their audiences. They still end up with pages in which the viewer follows the designer.

Your links are now dynamic with JavaScript. Based on options a user can select, clicking the link takes the user to different places without waiting on a CGI script to feed a page from the server. Also, by using the frames and windows, your existing page is not necessarily replaced by the new page. Your browser can be a kaleidoscope on the Web simultaneously viewing multiple sites around the world. Or you can pull in different publications based on the day of the week.

Additions to the LINK Syntax

You are probably familiar with using the link tag in a HTML document. A very simple example is the following:

<A HREF="http://www.yoursite.com">Click here</A>

Your browser would display "Click here" as a hyperlink.

The reference of a LINK is a URL or a location. You know the World Wide Web protocol, which is http:// as you see in the preceding example. You could also have used the MailTo protocol (for example, mailto:info@mailcall.com). There are formats for FTP, Gopher, and File.

A new URL type is now defined for JavaScript. The protocol is simply javascript:. For example, you could specify javascript: history.go(-1) as the URL. When used as the URL for a LINK, the browser execute the statement following the colon. In the following example it executes: history.go(-1). As a useful example, try adding the following line to any page:

<A HREF="javascript: history.go(-1)>Go back to previous page</A>

This is particularly useful on documents displayed in browser windows where you have disabled the toolbar.

When you click this hyperlink, the browser takes you back to the previous page in your history list. If you want to test this, open your browser and load your default home page. Then load the page in listing 7.1. Clicking the hyperlink returns you to your defalut home page.

Listing 7.1 Demo of javascript URL 
<HTML><HEAD><TITLE>history.htm by Ray Daly</TITLE>
</HEAD><BODY>
<P>Juno said, "<A HREF="javascript:history.go(-1)">
History will repeat itself.</A>"<P>
</BODY></HTML>

The limitation on the javascript: protocol is that it evaluates its expression to a location. In other words, the result of the expression should be a string that represents a location. For example, earlier in your code you could set a variable equal to a URL. Then use the javascript: protocol in a link to jump to that location.

Var demoloc="http://www.netscape.com" 
<A HREF="javascript:demoloc">

The other new protocol is the about: protocol. When used as a location for a link, it provides Navigator information ( see listing 7.2). In its basic format without any arguments, it is the same as selecting About Netscape from the Help menu. When used with the plug-ins argument, the page displayed is the same as About Plugs from the Help window. The last usage is with the argument cache which is suppose to display the disk cache statistics.

On Windows NT, this features does not work.
Listing 7.2 about.htm Demo of about: Protocol 

<HTML><HEAD><TITLE>about.htm by Ray Daly</TITLE>
</HEAD><BODY>
<P>Demo of the <I>about:</I> protocol:
<UL><LI><A HREF="about:">about:</A></LI>
<LI><A HREF="about:cache">about:cache</A></LI>
<LI><A HREF="about:plug-ins">about:plug-ins</A></LI>
</UL><P>
</BODY></HTML>

Properties of the LINK Object

Each object has properties. The properties of the LINK object tell you about the URL. There is also property to tell you the target for the document. I have created a small page that shows all of the LINK properties in action (see fig. 7.1 and listing 7.3).

FIG. 7.1

All of the properties, except TARGET, extract substrings from the HREF property.

Listing 7.3 Demo of LINK Object Properties
<HTML><HEAD><TITLE>linkprop.htm by Ray Daly</TITLE></HEAD><BODY><P>
<B>LINK[0]:  </B>
<A HREF="http://www.yoursite.com:80/mystuff/index.html?search=htmljive" 
TARGET="parent.bottom">
http://www.yoursite.com:80/mystuff/index.html:80?search=htmljive</A>
<BR><B>LINK[1]:  </B>
<A HREF="http://www.yoursite.com:80/mystuff/index.html#anchorhere" 
TARGET="parent.bottom">
http://www.yoursite.com:80/mystuff/index.html:80#anchorhere</A>
<BR><BR>>This demonstrates the properties of the LINK[0] object.
<SCRIPT LANGUAGE="JavaScript">
document.write( "<BR>hash = " + document.links[0].hash)
document.write( "<BR>host = " + document.links[0].host)
document.write( "<BR>hostname = " + document.links[0].hostname)
document.write( "<BR>href = " + document.links[0].href)
document.write( "<BR>pathname = " + document.links[0].pathname)
document.write( "<BR>port = " + document.links[0].port)
document.write( "<BR>protocol = " + document.links[0].protocol)
document.write( "<BR>search = " + document.links[0].search)
document.write( "<BR>target = " + document.links[0].target)
document.write( "<P>>The LINK[0] has no hash.  ")
document.write("Howver the LINK[1] has:<BR>")
document.write( "hash = " + document.links[1].hash)
document.write("<BR><BR>The numbr of links is the length = ")
document.write( document.links.length)
</SCRIPT></BODY></HTML>

The NAME Attribute has New Significance

Prior to putting JavaScript into HTML pages, there was not much point of using the NAME attribute, so my tags remained nameless. NAME was only used for anchors and when sending form information to a CGI script.

As you use JavaScript to make your links dynamic, you need to distinguish between the various links on your page. The properties of the link object are accessible using the following format:

document.links[index].propertyname

But in using this format, you need to know the index number. The index number is assigned to each LINK object in sequence as it is loaded by the browser. The first link loaded has the index of 0, the second is 1, and so on. So you need to keep track of the order the LINK objects are loaded. This is the default method of accessing properties.

Often, a simpler means is to name the elements that are referenced by your JavaScript code. Therefore, using our first example, add the NAME attribute:

<A NAME="myname" HREF="http://www.yoursite.com">Click here</A>

Now your JavaScript code can access the properties of this object without having to know the index number. Simply use the following format:

document.name.propertyName

Using the NAME attribute is probably familiar to you if you have used anchors in your HTML documents. It is the identical format and is still how you create anchors. So whenever you use the NAME attribute for your JavaScript code, you are also adding a new Anchor.

LINK Events: onMouseOver and onClick

JavaScript code executes when the browser recognizes certain events. The link object recognizes two events: onClick and onMouseOver. You will probably use onClick in most of your code and onMouseOver only occassionally. This will remind you of the format of these events used with the LINK tag.

In debugging code involving the status bar, make sure you included the statement, return true.

The format is the same as for other events. Use our example, as follows:

<A NAME="myname" HREF="http://www.yoursite.com"
onMouseOver="window.status='Please visit my site.'; return true">
Click here</A>

This places the message, Please visit my site., in the status bar when the viewer places the mouse pointer over the hyperlink. This overrides most browsers that would display the URL in the status bar in this event.

You can use this feature the change the look and feel of your pages. Instead of showing the URL, which is geek talk to many, change your links to verbally tell people where the links take them. So instead of displaying something like

http://www.cris.com/~raydaly/sponsors.html

you can display an easier to understand message in the status bar, such as

Hyperlink to "Sponsor of the Day"

The onClick event uses the same format. Also, the example application for this chapter makes frequent use of the onClick event. The following is a short example:

<A NAME="mymessage" HREF="http://www.newsite.com"
onClick="alert('Thanks for visiting.  Enjoy the new site.')">
Visit Newsite</A>

This code displays an alert dialog box prior to jumping to the new site (see fig. 7.2). Only after the user clicks OK in the dialog box does the browser hyperlink to www.newsite.com.

FIG. 7.2

You can display a dialog box prior to hyperlinking to a new site.
You can confuse your users by changing the HREF using onClick. Users often look to the status bar to see the URL that the hyperlink will take them to. When you assign the HREF attribute of the LINK, it is displayed in the status bar. When using the onClick event you can set the HREF to a different URL. By reading the status bar the user may assume he is going to the first URL, but instead your JavaScript code takes him to the URL specified by the onClick statement.
In the following example, the status bar makes it appear that the link is to Yahoo's site, but the code takes you to Infoseek. It goes to show that you can not even trust links anymore.
<A NAME="searchme" HREF="http://www.yahoo.com"
onClick="this.href='http://www.infoseek.com'">
Search Internet for a Topic</A>
To avoid such a disception in the status bar, just add onMouseOver to change the contents of status bar. For the preceding example, just insert the following as the second line:
onMouseOver="window.status='Will take you to a search engine.'; return true"

Change Link URLs not the Displayed Text

Unlike text boxes, JavaScript cannot change the hyperlink text displayed by the browser. In listing 7.4, the hyperlink text is Yahoo!. Regardless of the changes you make to this object, this stays on the screen.

As you design your dynamic links, consider the words and images that reflect the new nature of your hyperlinks. For example, you could write a simple random URL function. When you click the link, it takes you to a random search site. You might use the words, "Spin the wheel to a random search site," or add a graphic image of a roulette wheel.

Listing 7.4 is an example showing how to make a dynamic link to Yahoo. The browser simply displays the hyperlink text Yahoo! When you click this link before 6:00 p.m., you link to the text-only version of Yahoo! But after 6:00 p.m., you link to the regular graphic version of Yahoo! So the HREF changes, but the displayed text stays the same.

Listing 7.4 Page with Alternative Yahoo! Links
<HTML>
<HEAD><SCRIPT Language="JavaScript">
function timeText () {
   today=new Date()
   hour = today.getHours()   //…get hour of the dat
   if (hour>18 ) {
        //…after 6:00 p.m use graphics
        yahooURL= "http://www.yahoo.com/"
   } else {
      //…all other times use test mode
       yahooURL = "http://www.yahoo.com/text/"
   }
   return yahooURL   //…result of function is a URL
}
</SCRIPT></HEAD>
<BODY>
<A NAME="yahooLink" HREF=""
onClick="this.href=timeText()"   //…get the right URL
onMouseOver="window.status='Hyperlink to Yahoo!'; return true">
Yahoo!</A>
</BODY></HTML>

The URLs are not just for the Web. For example, suppose you have a fairly lengthy form to be completed by a customer, and one of the first entries asks about the customer's location. Based on that entry, you might dynamically change the mailto address. Then any e-mail the customer might send is directed to the proper salesperson. Listing 7.5 asks the user where he is located. Based on his selection, e-mail goes to a different address. Figure 7.3 shows the result of listing 7.5.

Listing 7.5 Page that Switches Mailto: Addresses
<HTML><HEAD></HEAD>
<BODY>
<FORM>
<B>Where are you located?</B><BR>
<INPUT TYPE="radio" NAME="country" onClick="salespersonMailto=
     'mailto:worldsales@company.com'"> Outside North America<BR>
<INPUT TYPE="radio" NAME="country" onClick="salespersonMailto=
     'mailto:nasales@company.com'"> North America<BR>
</FORM>
<A NAME="salesperson" HREF="mailto:info@yoursite.com" onClick="this.href=salespersonMailto">
Email your salesperson.</A>
</BODY></HTML>

FIG. 7.3

Depending on the selection, e-mail goes to a different address.  
Remember to include a default address or use a dialog box to ask 
the user to make a choice before trying to send e-mail.

Create Documents into Frames and Windows

The LINK tag now enables the designer to specify the TARGET for the URL. This is an optional attribute. If it is not used, the new page simply replaces the previous page as before. But JavaScript allows you to display these new pages in frames or new windows.

One target for your link can be a new browser window. The windows will generally look and function as if you opened a second browser. Therefore, the original page is still displayed in your first window, and the new page is displayed in the second. You can reduce the functionality of these windows by changing their features when the windows are open.

A frame is the other possible target for your link. Frames divide your browser window into two or more areas. Inside these frames you can display standard Web pages or create your own documents. The applications constructed in this chapter use frames.

The following code displays the Yahoo page in the frame labeled "three."

<A HREF=" "onClick="this.href=http://www.yahoo.com" " TARGET="three">Show picture Tri</A>

Windows and frames are often a vital part of a design with dynamic links. Using JavaScript code behind a link, you can build new types of browsers. You can also build new tools. For example, you might bring a page into a frame, analysis it, and display the results in another frame.

Often when using frames, one area is like a control panel that can control the display in another. For example, researchers constantly use different search engines on the Web, and these sites are bookmarked. But it would be handier if these sites were always available like the Directory buttons in Netscape Navigator. Listings 7.6, 7.7, and 7.8, called SearchDr, show how the top frame contains one line with hyperlinks to eight different search engines. This frame is like a control panel with the documents targeted at the lower frame. Figure 7.4 shows the result.

Listing 7.6 Top Page for SearchDr 
<HTML><HEAD><TITLE> searchdr.htm </TITLE></HEAD>
<FRAMESET ROWS="60,*">
   <FRAME SRC="search.htm" NAME="buttons">
   <FRAME SRC="display.htm" NAME="display">
</FRAMESET>
</HTML>

Listing 7.7 Initial Screen in Display Frame
<HTML><HEAD><TITLE>Part of searchdr.htm: display.htm</TITLE></HEAD>
<BODY><H1>Display Area</H1>
<P>Click on any hyperlink above to display a search engine here.
</BODY></HTML>


Listing 7.8 Frame for SearchDr with Hyperlinks
<HTML><HEAD><TITLE>Part of searchdr.htm:  search.htm</TITLE></HEAD>
<BODY>
<A HREF="http://www.altavista.digital.com/" TARGET="display"> Alta Vista</A>  --  
<A HREF="http://www.excite.com" TARGET="display">Excite</A>  --  
<A HREF="http://www.lycos.com/" TARGET="display">Lycos</A>  --  
<A HREF="http://www.mckinley.com/" TARGET="display">Magellan</A>  --  
<A HREF="http://www.nlightn.com/" TARGET="display">NlightN</A>  --  
<A HREF="http://www.opentext.com:8080/" TARGET="display">Open Text</A>  --  
<A HREF="http://www.webcrawler.com" TARGET="display">WebCrawler</A>  --  
<A HREF="http://www.yahoo.com" TARGET="display">Yahoo!</A>
</BODY>
</HTML>

FIG. 7.4

SearchDr puts any of the listed search engines in the frame marked Display. 
When you create frames, let the default frames provide instructions to the 
new users.

For a more substantial example, we will construct an application in this chapter called Internet Tri-Eye. It will truly give you a different view of the world. In listing 7.9 and its corresponding figure 7.5, you see the frames used in creating Internet Tri-Eye.

Although this will be displayed using your browser, it is not the same old browser anymore. Frames and dynamic hyperlinks let you reshape the browser.

Listing 7.9 Frame Document for Internet Tri-Eye
<HTML><HEAD><TITLE>Internet Tri-Eye</TITLE></HEAD>
<FRAMESET ROWS="*,200">
   <FRAMESET COLS="33%,34%, 33%">
      <FRAME SRC="one.htm" NAME="one">
      <FRAME SRC="two.htm" NAME="two">
      <FRAME SRC="three.htm" NAME="three">
   </FRAMESET>
   <FRAME SRC="guide.htm" NAME="guide">

<NOFRAMES>
<H1>Internet Tri-Eye</H1>
<P><B>Internet Tri-Eye</B> is a demonstration of several features of 
Javascript.  To view and use this program you need a Javascript 
compatible browser like Netscape 2.0.
</NOFRAMES>

</FRAMESET></HTML>

FIG. 7.5

The frames used to create Internet Tri-Eye will contain the control panel 
at the bottom and display Internet camera pictures from around the world. 
The contents of frames can be .GIF and .JPEG files as well as HTML documents.

Creating and Using Anchors

Anchors are not commonly used on most Web pages. If you have an alphabetical listing, an anchor might take you to a particular section. However, most sites have tended to use rather short pages. These pages might be one or two screens in length and do not often need anchors.

Your HTML Elements

The pages you design with JavaScript are fundamentally different from most other HTML pages. Because they are so interactive, your viewers will spend more time on your pages than the average HTML page. They may also save the page because it is not just a page of text anymore, but an application.

These difference should make you consider making your pages bigger than before. The user may be willing to wait a little longer for a page to load if that means it will be richer.

Since your pages are now applications, users will expect quick responses to their inputs; you cannot deliver that promise if you have to keep requesting documents from the server. Instead, take what you might have normally put on several different pages and build it into one big page. This can also benefit users because when they save the page, they can have the complete application.

For example, with your Great JavaScript Application you might have a page of help and documentation. Given the sophistication of your application, this could be fairly lengthy, and normally you might consider separating it from the application page. However, if you follow that course, when users save the application, they will not have the help when loading it from their hard drives. Instead, consider making a bigger page that includes all of the help information and documentation. Then set up anchors to the help topics so people can easily refer to them.

FIG. 7.6 

By combining multiple pages into one, your JavaScript application 
becomes more responsive. The fewer the requests to the server, 
the more responsive your application is.

When you have longer documents, anchors become crucial for navigating around the document. Instead of scrolling through screen after screen, click the keyword and you have found your place. Use this technique for documentation, help, or other reference material.

Anchor Any Text or Element

Use anchors in the standard way and in new ways with JavaScript. Anchors enable you to specify a destination for a hyperlink within a document. For example, assume you want to be able to jump to the words, "Part two." Then you would put this code in your document:

<A NAME="jumphere">Part Two</A>

Note that the name does not have to be the same as the text. In this example the name is jumphere, and the text displayed by the browser is "Part Two." To create the hyperlink to this section, use the following code:

<A HREF="#jumphere"> Go To Part Two</A>

This is useful not only within the current document, but also when pulling up information within frames or in other windows. For example, take the case of a form in which you are verifying the input. You would probably use a dialog box to notify the viewer that the input is out of range; then use an anchor at the description of the text box, and link the browser to it with hypertext. Now the text box is right at the top of the screen awaiting a new input.

You can use the anchor to scroll the page to the place you want. The FOCUS and the SELECT methods can do the same with form elements. However, if your form elements have labels, these methods will move the element to the top of the screen cutting off your label. If you want your users to be able to read the labels, anchor the labels and jump to them.

Anchors can also provide you a new way to control the flow in completing a form, as shown in listing 7.10 and figure 7.7. Many times in completing paper forms, you see such instruction as "If you answered NO to question 6, skip to question 9." With JavaScript and anchors, you can look at the response to a question, then-depending on the answer-automatically jump to the anchor for the next appropriate question.

Listing 7.10 Anchors in Form Verification
<HTML><HEAD><TITLE>verfname.htm by Ray Daly</TITLE>
<SCRIPT LANGUAGE="JavaScript">
function skip2 (form) {
    if (form.q1.value>11) {
       alert ('You get FREE Overnite Shipping.  Skip to question 12.')
        form.q2.value="FREE Overnight"
        window.location="#a12"
        //...jump to anchor a12
    }
    if (form.q1.value<0) {
       alert ('You can not return these items')
       form.q1.value=""
       form.q1.focus()
       form.q1.select()
       //...instead of jumping to an anchor, this uses focus and select method
    }
  }
</SCRIPT></HEAD><BODY><FORM>
<P>Try filling in quanties of 16, 8 and -3.  </P>
<B>1.)  How many do you want?</B><BR>
FREE Overnite shipping when ordering 12 or more.<BR>
<INPUT NAME="q1" TYPE="Text" onBlur="skip2(this.form)"><BR>
<a NAME="a2">
<B>2.)  How do you want it shipped?</B><BR>
<INPUT NAME="q2" TYPE="Text" ><BR>
<BR><BR><BR><BR><BR><BR>
<I>(more questions are listed here)
<BR><BR><BR><BR><BR><BR>
<BR><BR><BR><BR><BR><BR>
<B>12.)  What color do you want?</B><BR>
<A NAME="a12"><INPUT NAME="q12" TYPE="Text" ><BR>
<BR><BR><BR><BR><BR><BR>
<I>(more questions are listed here)
<BR><BR><BR><BR><BR><BR>
<BR><BR><BR><BR><BR><BR>
</FORM>
</BODY></HTML>

FIG. 7.7

You will see a visual difference in comparing the use of anchors to control 
the flow or the use of the FOCUS and SELECT methods.
In debugging your JavaScript, check you quotes. While double quotes and single quotes work the same, you cannot start with a double quote and end with a single quote. Or vice versa. Your quotes must match or you will end up with errors several lines later.

Using Selection or Scrolling-Your Option

What kind of test did you prefer in school: multiple choice or essay? You probably found multiple choice easier. Certainly, your teacher found multiple choice easier to grade.

When you design interactive forms, your viewers probably also find your requests easier to understand in a multiple choice format. Understanding this aspect of form design, you have probably used radio buttons and checkboxes. These are excellent devices for presenting a limited number of choices.

When you present the viewer with a large number of choices, use the SELECT element. This enables you to present a large list without cluttering up your page. A good use would be geographical lists, such as states or countries in address forms.

Syntax in Review

Although using the SELECT element makes it easier for your viewer, you have to do more work. Remember, SELECT is an element within a form, so it must be between the <FORM>...</FORM> tags. The syntax of SELECT is one of the most complicated of all the HTML elements. You should be familiar with most of this specification.

Listing head...
<SELECT
   NAME="selectName"
   [SIZE="integer"]
   [MULTIPLE]
   [onBlur="handlerText"]
   [onChange="handlerText"]
   [onFocus="handlerText"]>
   <OPTION VALUE="optionValue" [SELECTED]> textToDisplay
      [ ... <OPTION> textToDisplay]
</SELECT>

The SELECT tag has one required attribute: NAME. This name and a value associated with the selected OPTION element are sent to the server when a form is submitted. The NAME attribute can also be used as an anchor. An optional attribute is SIZE, which tells the browser how many options to visibly display.

MULTIPLE is an optional attribute of SELECT, which changes the list so that one or multiple items can be selected by the user. This type of list is called a scrolling list.

The SELECT tag always contains two or more OPTION elements. This is where you list the items for the user to select. Each OPTION has a text property that is displayed in the select box. There is also an associated VALUE property that is sent to the server when the form is submitted along with the name of the SELECT tag. The last attribute of OPTION is itself optional. The SELECTED attribute is a means to have one of the items in your selection list be the default when the page is displayed.The only addition to this specification for JavaScript is the events discussed in the next section.

onChange, onBlur, and onFocus Events for SELECT

Like other objects in JavaScript, the SELECT object responds to events. Here you will learn specifics uses of onFocus, onChange, and onBlur with the SELECT objects.

onChange

onChange is the most common event that you monitor in SELECT. It looks for change from one selection to another. When the event is triggered, your code executes. An example of using onChange, by selecting a country, is shown in listing 7.11 and figure 7.8. Say you change a country selection from the United States to Mexico. Then onChange triggers a JavaScript function that changes the currency type from U.S. dollars to pesos. However, if you did not change the selection, the event does not trigger.

When using SELECT, you have a built-in associate array. Each OPTION value relates to a selection.
Listing 7.11 Currency by Country using onChange
<HTML><HEAD><TITLE>money.htm by Ray Daly</TITLE>
<SCRIPT LANGUAGE="JavaScript">
function changeCurrency(form) {
      form.currency.value=form.country.options[form.country.selectedIndex].value
}
</SCRIPT></HEAD>
<BODY><FORM>
<P>Demonstrates <I>onChange</I> event.  After you make a country selection,
the currency does not change until you click somewhere else.</P>
<B>Select your country</B><BR>
<SELECT NAME="country" onChange="changeCurrency(this.form)">
<OPTION VALUE="US Dollars">USA
<OPTION VALUE="Canadian Dollars">Canada
<OPTION VALUE="Peso">Mexico
</SELECT>
<P><B>Prices are displayed in:</B><BR>
<INPUT TYPE="text" NAME="currency">
</FORM></BODY>
</HTML>


FIG. 7.8

You will probably find that onChange does not work as you expect with SELECT. 
You have to click somewhere outside the SELECT box for the change 
to take effect.

onBlur

onBlur is a good way to verify proper selections. This event looks for when the focus is no longer on the SELECT object. In other words, it looks for when you click somewhere other than on the current element. When the event is triggered, you could execute a verification function. Although you can use the onChange event to verify selections, using onBlur might ensure the viewer's choice. This is because the onBlur event triggers JavaScript code even if a change has not occurred.

Verification is not always simply an either/or choice. For example, you might have a selection with some uncommon, but acceptable answers. This might be an unusual color for a piece of merchandise. For this circumstance, you might verify that this is indeed the correct selection, even if the user made no change in his selection. In listing 7.12, the user is simply notified with an alert box if he wants to buy less than a dozen eggs (see fig. 7.9)

Listing 7.12 Eggs Come by the Dozen Using onBlur
<HTML><HEAD><TITLE>eggs.htm by Ray Daly</TITLE>
<SCRIPT LANGUAGE="JavaScript">
function checkEggs(form) {
    form.eggs.value=form.quantity.options[form.quantity.selectedIndex].value 
    if (form.quantity.selectedIndex==0) {
        alert ('People usually order eggs by the dozen.')
     }
}
</SCRIPT></HEAD>
<BODY><FORM>
<P>Demonstrates <I>onBlur</I> event.  After you select a quanity,
the number on-hold is not updated until you click somewhere else.</P>
<B>How many eggs do you want:</B><BR>
<SELECT NAME="quantity" onBlur="checkEggs(this.form)">
   <OPTION VALUE="6">Half dozen
   <OPTION VALUE="12">Dozen
   <OPTION VALUE="24">Two dozen
</SELECT>
<P><B>We are holding this many eggs for you:</B><BR>
<INPUT TYPE="text" NAME="eggs">
</FORM></BODY>
</HTML>

FIG. 7.9

The event onBlur works almost exactly like onChange, except the JavaScript code is executed even if the selection does not change.  

onFocus

onFocus is an excellent way to assist the viewer in completing your form. It looks for the viewer moving the cursor to the SELECT element and then triggers code prior to any entry by the viewer.

For example, each question in your form can include particular instructions that assist the viewer in making a proper selection. When onFocus is triggered, your code could display in a separate window or frame the instructions related to that question. Or if you require a numeric answer to be calculated, why not pop up a calculator in a new window? That's what happens in the math word problem presented in listing 7.13 (see fig. 7.10).

It is possible to create an endless loop using the onBlur event. To avoid this trap, create a flag variable. Initially set it to zero. Every time you call the routine, check the value of the flag. If the flag is zero, then execute the rest of the routine and set the flag to one. If the flag is not zero, then the routine has already been executed once so you don't need to execute it again.
Listing 7.13 Tricky Math Word Problem Using onFocus
<HTML><HEAD><TITLE>wordprob.htm by Dr. Ray Daly III </TITLE>
<SCRIPT LANGUAGE="JavaScript">
function giveAnswer(form) {
    if (form.answer.selectedIndex==2) {
        alert ('People usually forget trains run on two tracks.')
     }
}
already=0
function callCalculator(form) {
if (already==0) {
   already = 1  //...only need to open this window once
newWindow=window.open("http://www.netscape.com/comprod/products/navigator/
version_2.0/script/calc.html")
}
}
</SCRIPT></HEAD>
<BODY><FORM>
<P>Demonstrates <I>onFocus</I> event.  As soon as you put click on the SELECT
element, then a calculator pops up.</P>
<P><B>Railroad track is ordered for three sections of track.  The first is 15 
miles long.  The second is 23 miles long and the third is 6 miles long.  How 
many miles of track needs to be ordered to complete construction?
</B></P>
<P><B>What is your answer:</B><BR>
<SELECT NAME="answer" onFocus="callCalculator(this.form)" 
    onBlur="giveAnswer(this.form)">
   <OPTION VALUE="21">21
   <OPTION VALUE="29">29
   <OPTION VALUE="88">88
</SELECT>
</FORM></BODY>
</HTML>

FIG. 7.10

When you design your JavaScript applications, remember that you can call up 
other people's applications like calculators.

Dynamically Change the Selection Not the Text

Unlike its textbox cousins, TEXT and TEXTAREA, your code cannot change the text displayed in the SELECT list. Although your viewer may have chosen Canada as the country, your code cannot substitute the name of the provinces for the names of the states as the text displayed by the options.

However, your code can dynamically change the selection made. The selected property reflects the selection status of an option. You can set selected which immediately changes the selection displayed on the browser display. You can see how this works by using radio buttons to change a SELECT list dynamically (see listing 7.14 and fig. 7.11).

Listing 7.14 Pizza for Dinner Using SELECTED Property
<HTML><HEAD><TITLE>dinner.htm by Red Daly</TITLE></HEAD>
<BODY><FORM>
<P>Demonstrates <I>selected</I> property.  See what you can afford for dinner.  Click on the radio button for a dollar amount and show your dinner in the select box..</P>
<P><B>How much money do you have for dinner?</B><BR>
<INPUT TYPE="radio" NAME="a" onClick="this.form.meal.options[0].selected=1">$10<BR>
<INPUT TYPE="radio" NAME="a"onClick="this.form.meal.options[1].selected=1">$15<BR>
<INPUT TYPE="radio" NAME="a"onClick="this.form.meal.options[2].selected=1">$20<BR></P>
<B>Your dinner tonite is:</B><BR>
<SELECT NAME="meal" >
<OPTION VALUE="$10">Pizza
<OPTION VALUE="$15">Extra Cheese Pizza
<OPTION VALUE="$20">Extra Veggies Pizza
</SELECT>
</FORM></BODY>
</HTML>

FIG. 7.11

You can really confuse your users by having one form element change another. 
Be sure to think through your design.
With text boxes, the information displayed in the box is the value property. With select, the value property is not displayed. This is like radio buttons and checkboxes. So don't change the value property of select and expect the display to change.

Example: An Application Using Advanced Navigation

This example is designed to explain the concepts discussed in this chapter. There are several suggestions on how you can make them more robust, but the key is the explanation. You will see how links, as well as anchors, can be dynamic. The select is also used.

Internet Tri-Eye is truly a kaleidoscope on the Web. With a few clicks, you can see New York, Hollywood, and Pike's Peak; Hong Kong, the Antarctic, and the Netherlands; or fish, a cat, and some ants. It is a great way to demonstrate not only JavaScript, but also the Web.

The purpose of Internet Tri-Eye is to simultaneously display pictures from multiple cameras connected to the Internet. You select a set, say the U.S., International, or Animals. Then you click Show Picture to display one view of the world. Further information about each camera is also available.

Expand the View with Frames

Listing 7.15 shows the basic layout for the browser window. This layout is defined by the HTML page. The window is divided into two frames with the top frame divided into three additional frames.

Listing 7.15 Frameset for Internet Tri-Eye Application 
<HTML><HEAD><TITLE>Internet Tri-Eye</TITLE></HEAD>

<FRAMESET ROWS="*,200">
   <FRAMESET COLS="33%,34%, 33%">
      <FRAME SRC="one.htm" NAME="one">
      <FRAME SRC="two.htm" NAME="two">
      <FRAME SRC="three.htm" NAME="three">
   </FRAMESET>
   <FRAME SRC="guide.htm" NAME="guide">

<NOFRAMES>
<H1>Internet Tri-Eye</H1>
<P><B>Internet Tri-Eye</B> is a demonstration of several features of 
JavaScript.  To view and use this program you need a Javascript 
compatible browser like Netscape 2.0.
</NOFRAMES>

</FRAMESET>
</HTML>

The content of the top three frames, the eyes, are files one.htm, two.htm, and three.htm (see listings 7.16, 7.17, and 7.18). These are extremely small files that are only used when the application is first loaded.

Listing 7.16 Initial Contents of Frame One for  Tri-Eye 
<HTML><HEAD></HEAD><BODY>
<H1>Eye One</H2>
</BODY></HTML>

Listing 7.17 Initial Contents of Frame Two for Tri-Eye 
<HTML><HEAD></HEAD><BODY>
<H1>Eye Two</H2>
</BODY></HTML>

Listing 7.18 Initial Contents of Frame Three for Tri-Eye 
<HTML><HEAD></HEAD><BODY>
<H1>Eye Tri</H2>

Files two.htm and three.htm are identical to the file one.htm except that the headline is changed to "Eye Two" and "Eye Tri," respectively. The guts of Tri-Eye and all of the JavaScript code is found in the file guide.htm. This file is the contents of the lower frame. As we progress in building the application, all of the changes are made to this file. So far, the four files, trieye.htm, one.htm, two.htm and three.htm, are complete.

Most people find it easier to write JavaScript after doing the layout. Do your frames, your tables, your controls, and even some windows; then write the code to pull it all together.

Objects for Tri-Eye

Now that we have the framework, the next step is to set up objects for each "eye" or camera. We start by defining an object called cam. The object has three properties: the description of the camera, the name for the anchor (more later), and the URL for the image. The code in guide.htm starts with the standard header, the SCRIPT tag and then defines the cam object (see listing 7.19).

Listing 7.19 Start of the Coding for Tri-Eye 
<HTML><HEAD><TITLE>Internet Tri-Eye by Ray Daly</HEAD>
<SCRIPT LANGUAGE="JavaScript">
<!--
function cam (name, anchor, rul) {
     this.name = name
     this. anchor = anchor
     this.url = url
}

Then for each camera, a new object is established. In this example, there are nine different cameras, so create nine different objects labeled cam1 to cam9 (see listing 7.20). You can add more if you like.

Listing 7.20 Setting Properties for Cam Objects for Tri-Eye 
     cam1 = new cam ("Hollywood, CA", "#Hollywood", "http://hollywood.bhi.hollywood.ca.us:8000/pictures/image01.gif")
     cam2 = new cam ("Pikes Pike, CO",  "#Pikes", 
"http://www.softronics.com/peak_cam/cam.jpg")
     cam3 = new cam ("New York City, NY", "#New York City", 
"http://www.metaverse.com/gate/images/empire.jpg")
     cam4 = new cam ("Zandvoort, NE", "#Zandvoort", 
"http://www.dataplace.nl//images/zandv-gr.jpg")
     cam5 = new cam ("Hong Kong",  "#Hong Kong", 
"http://www.hkstar.com/images/capture1.jpg")
     cam6 = new cam (" Australian Antarctic",  "#Antartic", "http://www.antdiv.gov.au/aad/exop/sfo/mawson/video.gif")
     cam7 = new cam ("Fishcam", "#Fishcam", 
"http://www.netscape.com/fishcam/fishcam.gif")
     cam8 = new cam ("Mojo - Cat",  "#Mojo", 
"http://www.lowcomdom.com/mojo.gif")
     cam9 = new cam ("Steve's Ant Farm", "#Ant Farm", 
"http://sec.dgsys.com/images/zANTPIX/Untitled.jpeg")

We now have nine different objects. In order to make it easier to reference these objects, create another object called camset (see listing 7.21). From this object, an object called camindex is created. The first property in camindex is cam1, the second is cam2, etc. Thus, to get the contents of cam5, you reference the fifth element in camindex.

Listing 7.21 Putting Nine Objects Into One for Tri-Eye 
function camset (eye1, eye2, eye3, eye4, eye5, eye6, eye7, eye8, eye9 ) {
   this.eye1 = eye1
   this.eye2 = eye2
   this.eye3 = eye3
   this.eye4 = eye4
   this.eye5 = eye5
   this.eye6 = eye6
   this.eye7 = eye7
   this.eye8 = eye8
   this.eye9 = eye9
}
camindex = new camset (cam1, cam2, cam3, cam4, cam5, cam6, cam7, cam8, cam9)

We do not need to create so many different objects, but this method seems more straight forward that the other options. If you are good with objects, have fun minimizing.

The final two lines of the JavaScript for this section initialize two variables to one, as follows:

     var setnumber=1
     var camnumber=1
//-->
</SCRIPT>
</HEAD>

Controls

To make anything happen with Internet Tri-Eye, controls need to be added. So far, all we have in guide.htm is the JavaScript defining the objects. Now the HTML code is added for the controls (see listing 7.22).

To hold the controls, there is a table of three rows and three columns. Across the entire first row is a button and a select element. The button is very simple and labeled About. When you click it, an alert window tells you about Internet Tri-Eye.

The next element in the top row is a SELECT box. Here you select which set of cameras you want to look at. The first three cameras are locations in the United States, the next three are international, and the last three are pets. When you make a selection, it sets the variable setnumber to 1 or 2 or 3.

Listing 7.22 Laying Out the Control Table for Tri-Eye 
<BODY><FORM>
<TABLE BORDER="1" WIDTH="100%">
<TR>
   <TD ALIGN=CENTER COLSPAN=3>
      <A NAME="top">   
      <INPUT TYPE="button" NAME="aboutTE"  VALUE="About Tri-Eye"
 onClick="alert('Tri-Eye is a demo from the book:  JavaScript Special Edition')">
      <SELECT
         NAME="setselect"
          onBlur="setnumber=setselect.selectedIndex+1">
         <OPTION VALUE="US" SELECTED> U.S.
         <OPTION VALUE="World">World
         <OPTION VALUE="Pets">Pets
      </SELECT>
   </TD>
</TR><TR>
   <TD ALIGN=CENTER VALIGN=TOP WIDTH="33%">
<A HREF=" "onClick="this.href=findHREF(1)" " TARGET="one">Show picture One </A>
        </TD>
          <TD ALIGN=CENTER VALIGN=TOP WIDTH="34%">
<A HREF=" "onClick="this.href=findHREF(2)" " TARGET="two">Show picture Two</A>
   </TD>
   <TD ALIGN=CENTER VALIGN=TOP WIDTH="33%">
<A HREF=" "onClick="this.href=findHREF(3)" " TARGET="three">Show picture Tri</A>
   </TD>
</TR><TR>
    <TD ALIGN=CENTER>
      <A HREF=" "onClick="this.href=findHASH(1)" " NAME="Info1">--- Info ---</A>
     </TD>
     <TD ALIGN=CENTER>
      <A HREF=" "onClick="this.href=findHASH(2)" " NAME="Info1">--- Info ---</A>
     </TD>
     <TD ALIGN=CENTER>
      <A HREF=" "onClick="this.href=findHASH(2)" " NAME="Info1">--- Info ---</A>
     </TD></TR>
</TABLE>

The final two rows of controls are for demonstrating dynamic links and anchors.

Dynamic Links

The middle row of controls is for the dynamic links. When you press on these links, one picture from one a camera is displayed. There is one control for each of the "eyes." The code we need pulls in the proper URL, given "eye" 1, 2, or 3, and is based on the set chosen with the SELECT box (see listing 7.23). These variables are camnumber and setnumber.

Listing 7.23 findHREF Funciton for Tri-Eye 
function findHREF (eye) {
     // ...eye is 1, 2 or 3  -- the target frame
     indexnumber = (eye-1) +( 3 * (setnumber -1)
     //the value of indexnumber is between 0 and 8
     return camindex[indexnumber].url
}     //returns the url of the camera

This code is added between the <SCRIPT> tags. Once you have the URL, the code is fairly simple. When the hyperlink is clicked, the findHREF function is called. It returns the URL, and the href property is changed. The target for the URL is the appropriate "eye" frame. Change the href property to the URL. For "eye" 3, the code is:

<A HREF=" "onClick="this.href=findHREF(3)" " TARGET="three">Show picture Tri</A>

For simplicity, the hyperlink text is "Show picture one" or "two" or "tri." To polish up the application, an icon could be used here.

Anchors to Complete the Story

So far, Internet Tri-Eye is already spectacular. It is a true kaleidoscope on the world. However, it does not tell us anything about these pictures. Anchors are used two different ways to complete the story.

Anchors to the Reference Information

The final row of the controls is for information links. Press the text "---Info--" and the frame scrolls down to a description of the site. For this example, there is a short, three-line description with a link to the host site if you would like more information.

When the objects were created for this page, anchors were included. So the same technique that was used above for links is now used for anchors. The function has only a minor difference: it returns the anchor property.

function findHASH (eye) {
       // ...eye is 1, 2 or 3 -- the target frame
       indexnumber = (eye-1) + ( 3 * (setnumber -1))
       return camindex[indexnumber].anchor
}

The control itself is also similar:

 <A HREF=" "onClick="this.href=findHASH(3)" " NAME="Info1">--- Info ---</A>

Anchors to Take Me Back

Once you read the information on the picture, you probably want to go back to the controls. Notice that the title of each description is followed by a hyperlink labeled "(top)." What you may not have noticed is that there is no anchor with the name top. Instead, (top) is the name of the About button. So press on (top), and the About button is at the top of the page.

Listing 7.24 Anchor Section for Tri-Eye 
<CENTER><H1>Tri-Eye Guide</H1></CENTER>
<DL><DT><A NAME="Hollywood">Hollywood, CA</A>   <I><A HREF="#top">(top)</A></I></DT>
<DD>Not your typical American street corner, this is
<A HREF="http://www.geocities.com/cgi-bin/main/BHI/look.html">Hollywood and
Vine from GeoCities</A>.  Just remember that &quot;nobody walks in L.A.&quot;</DD>
<DT><A NAME="Pikes">Pikes Pike, CO</A>   <I><A HREF="#top">(top)</A></I></DT>
<DD>One of America's most famous mountains. 
<A HREF="http://www.softronics.com/peak_cam.html">Pikes Peak Cam from
Softronics</A> gives you the view from Colorado Springs.</DD>
<DT><A NAME="NYC">New York City, NY</A>   <I><A HREF="#top">(top)</A></I></DT>
<DD>New York City's most famous building. 
<A HREF="http://www.metaverse.com/empire.html">Empire Cam from Metaverse</A>
has a view across part of the skyline.  Check the weather.</DD>
<DT><A NAME="Zandvoort">Zandvoort, the Netherlands</A>   <I><A HREF="#top">(top)</A></I></DT>
<DD>No close ups of the people on the beach.  This
<A HREF="http://www.dataplace.nl/dp/pages/foto.htm">Livecam from Dataplace</A>
points northwest across a traffic circle and up the beach.</DD>
<DT><A NAME="Hong">Hong Kong</A>   <I><A HREF="#top">(top)</A></I></DT>
<DD>Street scene that is colorful almost anytime.  The
<A HREF="http://www.hkstar.com/starcam.html">STARcam from HK Star Internet Ltd.</A>
shows more cars than people.</DD>
<DT><A NAME="Antartic">Australian Antarctic</A>   <I><A HREF="#top">(top)</A></I></DT>
<DD>While often black, some previous pictures are available.  The
<A HREF="http://www.antdiv.gov.au/aad/exop/sfo/mawson/video.html">camera at
Mawson Station</A> captures the pictures and though a variety of technology gets
it to your desk.</DD>
<DT><A NAME="Fishcam">Fishcam</A>   <I><A HREF="#top">(top)</A></I></DT>
<DD>Perhaps the most famous fish in the world. 
<A HREF="http://www.netscape.com/fishcam/fishcam.html">Fishcam from Netscape</A>
now has multiple cameras and formats.  Who ever imagined an aquarium as a
revenue source?</DD>
<DT><A NAME="Mojo">Mojo</A>   <I><A HREF="#top">(top)</A></I></DT>
<DD>You won't believe the technology used to bring you these images.  
<A HREF="http://www.lowcomdom.com/mojo_cam.html">Mojo-Cam</A> isn't from a
fixed view so it worth following.</DD>
<DT><A NAME="Ant">Ant Farm</A>   <I><A HREF="#top">(top)</A></I></DT>
<DD>Some people won't even think that this is a safe distance away. 
<A HREF="http://sec.dgsys.com/AntFarm.html">Steve's Ant Farm</A> also has a
movie available.</DD></DL></FORM></BODY></HTML>

Now Internet Tri-Eye is complete.

Example: Tri-Eye FTP Auto Dialer

Trying to FTP a popular new piece of Internet software can be frustrating. You press on a link, and it seems like minutes before you're asked to try again later because the site is busy.

FIG. 7.13

Tri-Eye FTP Auto Dialer looks rather bland when you start it up.  
The action comes from the user interacting.
Tri-Eye FTP Auto Dialer uses the same files as Internet Tri-Eye.

You can create the Tri-Eye FTP Auto Dialer with a simple modification to one file of the Internet Tri-Eye application. Simply change the values of the properties for each cam object in the guide.htm file. These properties are the URLs for the information displayed in each of the upper frames. For example, for Netscape's FTP site, use the Windows NT/95 version of Navigator 2.0:

ftp://ftp2.netscape.com/2.0/windows/n32e20.exe

Do the same for each FTP location by just changing the host from ftp2 to ftp3, and so on; the last one is ftp10. The function looks nearly the same only the contents of the properties have changed (see listing 7.25).

Listing 7.25  Redefined cam Object for Tri-Eye FTP-Auto Dialer 
function cam (name, anchor, url) {
   this.name = name
   this.anchor = anchor
   this.url = url
}
cam1 = new cam ("FTP2", "#Netscape FTP", "ftp://ftp2.netscape.com/2.0/windows/n32e20.exe")
cam2 = new cam ("FTP3", "#Netscape FTP", "ftp://ftp3.netscape.com/2.0/windows/n32e20.exe")
cam3 = new cam ("FTP4", "#Netscape FTP", "ftp://ftp4.netscape.com/2.0/windows/n32e20.exe")
cam4 = new cam ("FTP5", "#Netscape FTP", "ftp://ftp5.netscape.com/2.0/windows/n32e20.exe")
cam5 = new cam ("FTP6", "#Netscape FTP", "ftp://ftp6.netscape.com/2.0/windows/n32e20.exe")
cam6 = new cam ("FTP7", "#Netscape FTP", "ftp://ftp7.netscape.com/2.0/windows/n32e20.exe")
cam7 = new cam ("FTP8", "#Netscape FTP", "ftp://ftp8.netscape.com/2.0/windows/n32e20.exe")
cam8 = new cam ("FTP9", "#Netscape FTP", "ftp://ftp9.netscape.com/2.0/windows/n32e20.exe")
cam9 = new cam ("FTP10", "#Netscape FTP", "ftp://ftp10.netscape.com/2.0/windows/n32e20.exe")


FIG. 7.14

Tri-Eye FTP Auto Dialer will make multiple attempts to make an FTP connection.  
This should increase your chances for success.

Other Possible Improvements to and Uses of Internet Tri-Eye

Internet Tri-Eye was written to keep the code simple to explain, not dazzle you with graphics. The following are several suggestions for improving Tri-Eye or expanding its use:


Internet & New Technologies Home Page - Que Home Page
For technical support for our books and software contact support@mcp.com
© 1996, Que Corporation