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.
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:
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.
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>
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>
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.
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 yourJavaScript 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"
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 usegraphics 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.
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.9Frame 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.
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.
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.
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 getFREE 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.
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.
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.
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 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. EachOPTION 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 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.12Eggs 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 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.
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 forDinner 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.
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.
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 forInternet 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.
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>
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.
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 targetframe 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.
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.
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>
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 "nobody walks in L.A."</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.
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.13Tri-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 forTri-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.14Tri-Eye FTP Auto Dialer will make multiple attempts to make an
FTP connection. This should increase your chances for success.
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:
For technical support for our books and software contact support@mcp.com
Copyright ©1996, Que Corporation