Chapter 14

Controlling Web Page Appearance


As you are already aware, HTML is not desktop publishing. It provides structure and style to your Web page, but no control of the page width, size, or typography. This is what enables the Web to work on so many different platforms. Now with JavaScript and recent extensions to the HTML specification, you have more control over page appearance. In fact, your whole site can almost be considered as one application.

This chapter focuses on the appearance of text on your user's Web browser. The first section covers building JavaScript applications with a control panel. Next, text properties, font colors, and font methods are discussed. The chapter ends with a detailed example of a message editor, which uses all of the font methods of JavaScript.

Page Building with JavaScript

Before applying specific JavaScript properties, methods, and techniques, you must be aware of layout. This includes how the browser processes a page and its related documents as well as some design principles about good layout. You can build multiple pages with JavaScript to design your application.

Even the First Page Can Come Alive

The first time a user requests a page from your site the user has not yet given you any feedback, so you simply serve the page. When the page reaches the browser, however, the following two facts become available and can make the page come alive:

Listing 14.1  greeting.htm  JavaScript Only Greeting and Menu

<HTML><HEAD><TITLE>greeting.htm by Ray Daly</TITLE></HEAD>
<BODY><H1>WTFIN:  Where to Find it Now</H1>
<!-- hidden from other browsers
today=new Date()     //..get data and time
x=today.getHours()    //..pull out the hours
document.write ('<H2>Welcome JavaScript Surfers</H2>')
if (x<12) {
   document.write('<H3>Good Morning!</H3>')
} else {
   document.write('<H3>Hello on this beautiful day!</H3>')
// could substitute graphics instead of text greetings.  
document.write('<P>Hidden away for your use only are several 
document.write('<OL><LI><A HREF="messedit.htm">Message Editor</A></LI>')
document.write('<LI>More applications here.</LI></OL>')
//  all done with JavaScript-->
<A HREF="nextpage.htm">Continue to <I>Find it Now</I>.</A>

One of the first things you learn about JavaScript is that you cannot really change much about a page that is already displayed. Change a property and most likely it doesn't change the display. The text and layout of form elements are fixed.

You can, however, change the background color. For most pages, this may seem trivial and it probably is. But you can be creative with this feature. This is covered in more detail later in the section, "Practical Uses of Text Properties."

First Page as a Control Panel

Although the user can't control the currently displayed page, data from this page can change the appearance and content of related documents. In many ways, you can consider the first page to be a control panel that enables the user to make a choice that affects all related documents.

As an example, you can create a frameset in which one frame is the "control panel." In this frame, the user can click a choice of font and background colors. The rest of the documents in the other frames are then displayed using this selection.

With frames, you have the frame document and related documents. You may not want the user to be able to load the related documents without the frameset. In these related documents, you can use the onLoad event handler to verify that the document was loaded with the frameset.

The first page can also control content. For example, a sports site might start by asking which sports interest you. The rest of the site can omit links and information on teams and games that don't match your interest.

JavaScript Enhanced Pages as an Application

These "control panels" could be more sophisticated. You might develop a whole series of questions, like on a registration page, and all subsequent documents could be modified by the registration data from the control panel. These control panels are coming up more and more on sites (see fig. 14.3).

Figure 14.3 : Dave's Tekno Dive ( gets better with each visit. If you register, he saves your background preference for 30 days. The control panel changes the way you browse his site.

It is possible to build very advanced JavaScript applications. I envision that URLs of frame contents and new windows will force the loading of the "control panel." The dependence on data from the first page is like a parent-child relationship. (This is very different from today's Web sites in which most pages can stand on their own.) Although the server can send what appears to be static pages, the JavaScript in these pages makes them come alive in the browser.

As you will see in this chapter, you can create documents that are only a part of an application. Often, these pages make little or no sense on their own. Yet, all pages look the same to a search engine.
To discourage people from directly accessing these secondary documents, consider hiding these pages from the search engines. You should consult your Webmaster about how your system can hide files.
Or, you may want to read up on the robots.txt file. When a search engine indexes a site, it uses a program called a robot or a spider. When the engine visits a site, the first file it reads is robots.txt. Using the information in this file, the search engine's robot omits specified areas from its search on the site. Take a moment to read "A Standard for Robot Exclusion," which is available at

Storing Control Panel Information

As you develop JavaScript applications, you will have multiple related documents. Sharing information between these documents is part of the process of building these applications. But now that you have collected all of this information, you may want to start storing it.

Cookies Store Information in the Browser  One means of storing information between pages is to use cookies (client-side persistent information). The browser, not the server, maintains this information. When using cookies, each time the browser makes a certain request to a server, the request includes this stored information. The server may or may not use this information.

Let's look at a simple example. Say you want to store a customer's name-Smith. The information is stored by the browser, and when the browser requests another related page, this information is sent to the server by the browser.

Cookie data uses the format of NAME=VALUE. For this example it would be customer=Smith. If you have multiple pairs of data, just separate them with semi-colons-for example, customer=Smith ; phone=8005551212.

To store information in a cookie with JavaScript, you can use the cookie property of the document. To store a value use a statement like this

document.cookie = "customer=Smith"

In the default mode, the cookie information is maintained until a session ends. Also, the information is only sent when requesting pages from the same server. More details are available in Netscape's Preliminary Specification (

You retrieve information from the cookie also using the cookie property. Then, using string methods, you could extract the information. For our customer Smith example,

var pair=document.cookie
lastname = pair.substring(pair.indexOf("=")+1,pair.length)
///...lastname should now equal Smith

You can store cookie information two ways. First, as you gather important information, you might want to immediately store it in the cookie. The other method is to create an exit function. This function is called by an unLoad event and saves the information into the cookie.

While the cookie specification is considered preliminary, the standard is supported by a wide number of browsers. So while you should use it with some degree of caution, cookies will certainly become more common.

Bookmarks and URLs for Storage  Though it's infrequently used, you can store information in the URL for your page. Using the search property of a location, you can add text to the end of your URL. While extremely long URLs can cause server problems, storing small amounts of data should work flawlessly. Search data is the information after a question mark (?) in a URL. In the following example, ?info=htmljive is the search portion of the URL:  

After a user enters registration information, you can take him to a post-registration page. Have your code add registration information to the URL using the search property (see listing 14.2). Recommend to the user that he make that page a bookmark. This saves the user's registration information as part of the bookmark.

When the customer returns to your site using the bookmark, you can read the search property of the URL. Now you have the registration information and your user can be immediately directed into your site.

Listing 14.2  search.htm  Store Information in a URL

<HTML><HEAD><TITLE>search.htm by Ray Daly </TITLE></HEAD><BODY>
<P>Save this page as a bookmark to avoid the registration page on your next visit..</P>
<script language="JavaScript">
if (""){
   //...need this if control to avoid an endless loop"?infohere"
  //..add information to URL

Most often you will see search information stored in a format of associative pairs. In this format you have field=value. Multiple pairs are separated by the ampersand (&), and spaces are not permitted. Go to almost any search engine and do a simple search. The page that is returned to you will have search text in its URL. For example,

Though the format of associative pairs is common, there appears to be no requirement to use them. I've found that you can put almost any text or numeric data you want into this portion of the URL.

Parent Knows All  While cookies and bookmarks with search information allow user information to be stored between visits, you can also maintain information during the current visit using the control panel concept.

JavaScript works with both frames and multiple windows. As long as a window from your application stays open, the browser can store data. For example, a user can work within your application and then hyperlink to another site. You can design all of your external links to open up new browser windows. This way your original window is not unloaded and your data is retained.

Good Design

Whether a Web page looks good is a matter of taste: what you like, I might avoid. This factor should be part of your design. Enable users to change the appearance even to a style that you would not normally choose. For example, many of the people I work with set their word processor colors to vibrant green and rich purple. This is a style I might only use on Easter.

Although everyone has individual tastes, the following are different principles that can produce good-looking pages (see fig. 14.4):

Figure 14.4 : Almost everyone agrees that Yahoo!'s design is elegant and to the point. The graphic is all that is necessary and functional. The text is easy to read in multiple columns with spacing between the lines.

Text Properties and Color Values

Background color and tiles have forever changed the Web. A site without a background is considered old fashioned and behind the times. This puts a burden on the designer to be a color coordinator.

If you change the background color, you also need to be able to modify the colors used to display text. Having the background color match the text color makes the text invisible. Although you might want to use this as an effect, most of the time you will want a pleasant contrast between these two colors.

Text Properties

There are five text properties available from the browser. These all reflect the values of the TEXT attribute of the BODY tag. The first two are the color for the background and for the text of the document. Their properties are called bgColor and fgColor.

The three other text properties reflect the three different colors applied to hyperlink text. Usually you want your hyperlinks to stand out from the rest of the text. Although early browsers displayed these links by underlining the text, now most browsers distinguish these links by color. They also provide feedback to the user by changing this color momentarily when the user clicks the link. After a link is visited, the color is also changed. Respectively, these properties are called linkColor, alinkColor, and vlinkColor.

The syntax for these properties is as follows:

document.fgColor [= [<RGB Triplet> | <Color Name>]]
document.bgColor [= [<RGB Triplet> | <Color Name>]]
document.alinkColor [= [<RGB Triplet> | <Color Name>]]
document.linkColor [= [<RGB Triplet> | <Color Name>]]
document.vlinkColor [= [<RGB Triplet> | <Color Name>]]

Where <RGB Triplet> is a string of hexadecimal values representing a combination of the colors red, green, and blue; <Color Name> is a string representing a specific color's name as defined in the Color Table. See appendix D for both the hexadecimal and the literal names for predefined colors.

Color Values

You specify the color for TEXT properties just as you would any other color element. The general syntax is:

document.textproperty = "colorvalue"

where colorvalue is either a hexadecimal or a literal name representing a color.

Hexadecimal Values for Color  Prior to JavaScript, all color values were specified using the RGB hexadecimal values. This is a six-digit number. It is often called a triplet because it is divided into three sets of two digits each: the first two digits specify the amount of red, the second two the amount of green, and the last two the amount of blue.

Because the numbers are hexadecimal, the values range from 00 to FF. (255 is the decimal equivalent of FF hexadecimal.) For example, black is FFFFFF and white is 000000. Aqua, which is an equal mix of green and blue, is represented by 00FFFF:

document.fgColor = "00FFFF"

Using Color Names  JavaScript provides another option, besides hexadecimal numbers, for specifying color values: you can use names. Instead of coding

document.fgColor = "0000FF"

you can use the word blue like this:

document.fgColor = "blue"

You have a choice of over 150 predefined colors. Of course you have standard colors such as blue, violet, cyan, and maroon. But now, such colors as dodger blue, tomato, Navajo white, firebrick, peach puff, and Alice blue are hard coded into JavaScript.

You probably remember the primary colors: red, yellow, and blue. Why are the colors red, green, and blue used for computers? Why green instead of yellow?
Red, yellow, and blue paints are commonly used on paper to learn about primary colors. In that case, white light reflects off the mixture of paints to produce the desired color. No paint produces white, and equal amounts of each color absorbs all of the reflected light, producing black. The important point is the reflected light. The color you see is a result of reflected light.
Red, green, and blue (RGB) are the primary colors when the light itself provides the color. It doesn't matter whether you mix red, green, and blue lights on a darkened theatrical stage or from inside a monitor or television. No light produces black; an equal amount of all lights produces white.

Color Tools  As you work with color you will find having a few tools will make things easier. For example, what is the hexadecimal number for light purple? What color text looks good on a coral background?

A chart that shows the hexadecimal representation of a desired color is a great tool. There are numerous charts available. I use the RGB Hex Triplet Color Chart at I have saved this page on my hard drive. Whenever I need it I just load the page and really see what the color looks like on a monitor. (You can print it out, but the colors don't look the same as onscreen.)

A program that actually lets you experiment with color properties and background tiles is hIdaho Design's Color Center ( by Bill Dortch (see fig. 14.5). You select colors and actually see the results on your screen. Not only is it a great way to find pleasant color schemes, but it is also a brilliant JavaScript application.

Figure 14.5 : hIdaho Design's Color Center is even more brilliant on your monitor. You can work in hex, decimal, or percentage. The logo is an animated GIF file.

Practical Uses of Text Properties

Knowing the text properties of the current document, you can use these values to set the text properties for any new documents. Make the new documents the same as the current one, or create a new color by manipulating the current property values.

Another use is to provide feedback that the user's action was recognized. You can either replace the existing background or possibly flash the background. You can also use it with a countdown sequence like ticks of a clock.

For example, upon a user's action (say, clicking a hyperlink) you can make the background color change to the standard text color. This makes the text "disappear" and notifies the user that his action was accepted. The code for this example is in listing 14.3 and can also be found on the CD-ROM as color16.htm.

Listing 14.3  color16.htm  Changing Background Color

<HTML><HEAD><TITLE>color16.htm by Ray Daly</TITLE></HEAD>
<BODY bgColor="red" fgColor="black" >
<P>Simple example of changing background color.</P>
<P><FONT COLOR="green">Why did the chicken cross the road?</P>
<P><FONT COLOR="document.bgColor">To get to the other side.</P>
<!--...make color same as background to make invisible -->
<FORM><INPUT TYPE="button" VALUE="Red"  onclick='document.bgColor="red" 
<INPUT TYPE="button" VALUE="Green" onclick='document.bgColor="green"  '><BR>
<P><A HREF="" 
onClick='document.bgColor="black" '>Yahooligans</A>

Overriding fgColor

Normally, the color specified with fgColor is the color of all the text on the page, except hyperlinks. You can override this color by using the fontcolor element. For example, you can place one paragraph of text in between <FONT COLOR="chocolate"> and </FONT>. The text of this paragraph would then be displayed in the color chocolate instead of the color specified by fgColor.

JavaScript provides for a method for placing FONTCOLOR tags around a string. This is the topic for the next section.

Fonts and Font Methods

You certainly have used physical styles for your HTML pages, such as bold, fixed, and italics. JavaScript has methods for these three styles as well as blink, strikeout, subscript, and superscript. It also has methods for big, small, fontsize, and fontcolor. This chapter groups these methods under the name of font methods.

Description of Font Methods

The result of a font method places the appropriate tags at the front and end of the string. For example, for the physical style of bold, if testString="example", then the result of testString.bold() is <B>example</B>. In other words, the result of a font method is a new string with HTML code embedded in it.

Below you will see three figures that demonstrate all the JavaScript font methods. Listing 14.4 shows the use of each font method on the same string. Listing 14.5 shows the equivalent HTML code. Figure 14.3 is a screen shot showing the display of each style.

Using Font Methods

The font methods are useful in four primary ways, as follows:

Using Font Methods Directly  You create new documents using the document.write or document.writeln methods. As part of the string used in a document.write method, you can use the font methods instead of hard coding in the style tags.

It can be easier to debug using document.write (promptstring.bold()) than document.write ("<B>" + promptstring + "</B>"). It also allows for the browser to handle implementation of HTML tags, for which specifications may change in the future. In the following example, you see the JavaScript code using document.write (see listing 14.4), the equivalent HTML code (see listing 14.5), and the display of that HTML code (see fig. 14.6). This shows the use of each of the different font methods. Figure 14.6 shows how either one of these documents will display on a browser.

Figure 14.6: This is the preview window, which shows how your message will appear in a browser. Once you approve, then you submit your message.

Because the HTML code does not actually specify a font, the results will vary depending on your browser. The appearance also will depend on your browser preferences.

Listing 14.4  fontmeth.htm  All Font Methods in Use

<HTML><HEAD><TITLE>fontactu.htm by Ray Daly</TITLE></HEAD><BODY>
var testString = "JavaScript Font Methods "
document.write ('<P>')
document.write (testString.bold()+"<BR>")
document.write (testString.fixed()+"<BR>")
document.write (testString.italics()+"<BR>")
document.write (testString.blink()+"<BR>")
document.write (testString.strike()+"<BR>")
document.write (testString.sub()+"<BR>")
document.write (testString.sup()+"<BR>")
document.write (testString.big()+"<BR>")
document.write (testString.small()+"<BR>")
document.write (testString.fontsize(1)+"<BR>")
document.write (testString.fontsize(2)+"<BR>")
document.write (testString.fontsize(3)+"<BR>")
document.write (testString.fontsize(4)+"<BR>")
document.write (testString.fontsize(5)+"<BR>")
document.write (testString.fontsize(6)+"<BR>")
document.write (testString.fontsize(7)+"<BR>")
document.write (testString.fontcolor("FA8072")+"<BR>")
document.write (testString.fontcolor("salmon")+"<BR>")
document.write ('</P>')

You can combine font methods to act on one string. For example, to produce a bold, size 4 font in the color of salmon, use the following code:

Listing 14.5  fontactu.htm  Equivalent HTML Code to Font Methods

<HTML><HEAD><TITLE>fontactu.htm by Ray Daly</TITLE></HEAD><BODY>
<B>JavaScript Font Methods </B><BR>
<TT>JavaScript Font Methods </TT><BR>
<I>JavaScript Font Methods </I><BR>
<BLINK>JavaScript Font Methods </BLINK><BR>
<STRIKE>JavaScript Font Methods </STRIKE><BR>
<SUB>JavaScript Font Methods </SUB><BR>
<SUP>JavaScript Font Methods </SUP><BR>
<BIG>JavaScript Font Methods </BIG><BR>
<SMALL>JavaScript Font Methods </SMALL><BR>
<FONT SIZE="1">JavaScript Font Methods </FONT><BR>
<FONT SIZE="2">JavaScript Font Methods </FONT><BR>
<FONT SIZE="3">JavaScript Font Methods </FONT><BR>
<FONT SIZE="4">JavaScript Font Methods </FONT><BR>
<FONT SIZE="5">JavaScript Font Methods </FONT><BR>
<FONT SIZE="6">JavaScript Font Methods </FONT><BR>
<FONT SIZE="7">JavaScript Font Methods </FONT><BR>
<FONT COLOR="FA8072">JavaScript Font Methods </FONT><BR>
<FONT COLOR="salmon">JavaScript Font Methods </FONT><BR>

Using Font Methods Indirectly  There are many cases in which you want to build a document as user inputs are gathered, instead of immediately. This enables users to select components to be used for their documents. By putting the components together in different sequences, users create different HTML pages. Using an indirect technique, they can preview the page prior to finalizing it.

A very practical example is an HTML editor (see fig 14.7). The user builds the page using various form inputs, such as buttons. These activate functions that insert HTML tags using the font methods. As the user builds the page by making various choices, the raw HTML code is displayed in a text area of a form. The text area functions like a text editor in which the user can make changes prior to finalizing the document.

Figure 14.7 : HTMLJive is an HTML editor written in JavaScript. You build a document in the textarea with the option to preview it.

In other cases, you may not want the user to be capable of directly editing the HTML code. Instead of building the HTML page in a test area, you can use a hidden form element. Just use the value of that hidden element to store the code until it is ready to be directed to a new document (see fig. 14.8). The code for this example is in listing 14.6.

Figure 14.8 : In this example, code is stored in the hidden form element but you don't see it until you click the Show New Document button.

Listing 14.6  hidden.htm  Storing New Document in Hidden Value

<HTML><HEAD><TITLE>hidden.htm by Ray Daly</TITLE>
<!-- hide code from other browsers
function preview (form) {
     msg=open ("", "DisplayWindow","toolbar=yes,scrollbars=yes")
// end hiding -->
<P>Demo of building a hidden HTML document.  Click several times 
on the Holiday buttons before asking for a preview.</B>
<INPUT TYPE="hidden" NAME="storage" 
<!--...this hidden element is where the HTML document is created -->
<INPUT TYPE="button" VALUE="Happy Fourth" 
onClick=' += "<H1>Happy Fourth</H1>" '>
<INPUT TYPE="button" VALUE="Happy Halloween" 
onClick=' += "<H1>Happy Halloween</H1>" '>
<INPUT TYPE="button" VALUE="Show New Document" onClick="preview(this.form)">

HTML Strings as a Submission  There is also the case in which the new HTML code is never directly displayed by the browser. Instead, using the various user inputs, the HTML code is stored in either a text box or in a hidden value. When complete, the resulting code is submitted to the server, which processes it.

A practical example is a Web-based message board. Users can compose messages using a JavaScript-enhanced message editor. Because the messages become part of a Web page, they contain various physical styles, such as bold and italics. Buttons can be part of the form, so users do not necessarily need to know the HTML code to add italics or bold to their messages. When a message is complete, it can be sent to the server and appended to an existing page.

Another example is a salesperson's weekly report. A salesperson can complete a Web form about her activity. This might include invoice numbers, dollar amounts, and comments. When the report is complete, the JavaScript code adds HTML code to the various inputs. The final document is submitted to the server where it is simply appended to the sales manager's page for his review on Monday morning.

Font Methods on the Server  The primary purpose of the Web server is to respond to requests with HTML pages. LiveWire creates live pages by responding to user input. Because the server is building a live HTML page, the font methods are used extensively in LiveWire applications.

Design of JavaScript Message Editor

For a detailed and practical example, we are building a message editor. This JavaScript-enhanced page provides controls for the user to easily add HTML style tags to messages. This final text is then submitted to a server where the message is added to a guest book, a message board, or any other site that accepts HTML- enhanced messages.

Designing JavaScript applications often works best if you lay out the interface first. This is a way to decide not only the layout, but the events for which you need to write code. Once you have the layout, then write the code that works behind each event. This is a common technique for event-driven programs, and it is the approach taken for our message editor.

The initial release of JavaScript has limited methods available for text editing. First, the string methods are limited. For example, there is no search and replace method.
The other limitation relates to the fact that text editing takes place in a textarea. The textarea object has no properties related to the cursor position. Therefore, text functions can only append new text to the end of the text and not at the cursor.
Despite these considerable limitations, interesting applications can be created.

How the Message Editor Works

This application basically works like any other page with a text box in a form. The users complete their information, and they can edit it. When it is finalized, the text is submitted to a server where it is processed.

JavaScript enhances this process. We will design a control panel in which the user can select a text style. The program will then prompt the user for the text to highlight with a style. After the user has finished typing, the text and the HTML code is appended to the message in the text area.

The other main feature of the message editor is the preview window. Users will be able to preview their HTML documents prior to submitting them to the server. This will be activated by a button on the control panel. Because all of this activity takes place in the browser (on the client side), the load on the server is reduced. It also provides a much quicker response time than waiting for the server to return a previewed document.

Layout Decision

You must decide whether to create this application in one document or multiple documents. There are trade-offs with either choice.

You can make one long document with all of the HTML and JavaScript code. The user may then need to scroll around the page to use it. This choice can also be easier to code. The real benefit is that the user can save and recall the application in a single file on his hard drive.

The other option is to create a frame for the control panel and another for the text window. Users will not be able to easily save the application on their hard drives because it is now in several files. The real benefit is ease of use because the user will not have to scroll around as much.

For our example, we will use a page with frames. There will also be a dialog box and two other windows.

Framing the Message Editor

For the message editor, there are two main frames. The top frame displays the control panel. It is as wide as the browser allows and it has a fixed height large enough to contain all of the controls.

The top panel is subdivided into a left and right section. The left simply displays the last font color used. This is a fixed width. The right contains all of the controls and extends to the edge of the screen.

The second frame will contain the text box. This is where the message is edited. Like the other frame, the width is the same as the screen. Its height is variable, taking up the remainder of the vertical space.

Listing 14.7 is the code for creating the frames. To test the frames, three test documents are created (see listings 14.8, 14.9, and 14.10). These documents will be modified as we develop the application. Our test result is shown in figure 14.9.

Figure 14.9 : It's always a good idea to test your frames to see if they are the size you expect.

The message editor is an application written using frames. As such, the complete application consists of five files: messedit.htm, messarea.htm, messcolr.htm, and messcont.htm. The application starts by loading messedit.html. There is also a file for help information in messhelp.htm. These pages are developed as we go through to the end of this chapter. The CD-ROM contains the complete application and none of the development listings.

Listing 14.7  messedit.htm  Frameset Document for Message Editor

<HTML><HEAD><TITLE>Message Editor by Ray Daly</TITLE>
<FRAMESET ROWS = " 110, * ">
     <FRAMESET COLS="20,*">
     <!-- this is the upper frame, divided into two more frames -->     
              <FRAME NAME="messcolr" SCROLLING="no" NORESIZE
     <FRAME NAME="messcont" SCROLLING ="no" NORESIZE SRC =
     <FRAME NAME="messarea"  NORESIZE SRC="messarea.htm">
     <!-- this is the lower frame -->

Using frames with Netscape requires multiple documents. The primary document is a new type of HTML document because it has no <BODY>. Instead, the document uses the FRAMESET element. The contents of the FRAMESET tag are FRAME tags. The primary attribute of the FRAME is the source document, which is displayed in the frame. So for a page with two frames, you would have two FRAME elements, each specifying a source document.

One other optional element of a FRAMESET is another FRAMESET. You would use this in the case where you want to subdivide a frame into different frames. This is how we create the message editor example.

Listing 14.8  messcont.htm  Test Document for Upper Frame

<HTML><HEAD><TITLE>Message Editor by Ray Daly</TITLE>
<BODY bgcolor ="white">

Listing 14.9  messarea.htm  Test Document for Lower Frame

<HTML><HEAD><TITLE>Message Editor by Ray Daly</TITLE>
<BODY bgcolor ="white">

Listing 14.10  messcolr.htm  Test Document for Color Frame

<HTML><HEAD><TITLE>Message Editor by Ray Daly</TITLE>
<BODY bgcolor ="black">

Some Netscape Navigator browsers (on some platforms) cache frame information. If you modify the frame dimensions and just reload, this does not always change the frame sizing. To be certain, you have to exit Navigator, restart it, and then reload the page.

Framesets Nest, Frames Objects Don't

The message editor contains a case of nested framesets. The primary, or top, frameset contains another frameset. This is done to subdivide a frame into two other frames. You might think of these frames and framesets as a tree structure. Using the filenames from our example, a tree might break down to resemble the following:

Frameset: messedit.htm
Frame: messtext.htm
Frame: messcont.htm
Frame: messcolr.htm

Because the top file is considered the parent by JavaScript, you would consider messtext and the Frameset to be children. So the other two frames would be considered grandchildren, right? Surprisingly, the answer is no!

When JavaScript creates the objects from the framesets, all of the frames get "flattened." In other words, each frame, regardless of how deeply it is nested, is considered a child and is placed into the same frame array. All frames are placed into the array in the same sequence that they appear in the HTML file. All nesting is ignored, for example,

frames[0] is messcolr
frames[1] is messcont
frames[2] is messarea

This makes it easier to properly refer to a property in another frame. You don't need to know the relative relationship between frames since they are each a child to the parent.

Later in the chapter we will add to a value of a textarea (called messtext) in a form (called heavy) in a frame (named messarea) from a function in the other frame (called messcont). This value is referenced from the other frame using the following code:


Please note the word document in this code. Since a frame has several properties, you must specify that you are referring to the document property.

HTML Code for a Layout

In deciding on a layout, we will provide just enough code to see what the application will look like. For the text area, no further coding is needed other than layout. For the control pane, we will display the various buttons and other controls with practically no JavaScript coding.

HTML Code for the Text Area  This frame will consist primarily of a form. You can also select a background color for the form elements to sit on. There will also be one line of instruction at the top of the text area. As defined by the frame coding above, this document is called messarea.html.

Let's start with the standard tags and define the background color as aqua:

<HTML><HEAD><TITLE>Message Editor by Ray Daly</TITLE></HEAD>
<BODY bgcolor="aqua">

Next is the start of the form and the single line of instruction:

<FORM NAME="heavy"><P><B>Type your message in this box:</B><BR>

This form will contain only three elements. The first element of the form is the text area: this one is defined with a column width of 70 and a height of 16 lines. You can make these whatever dimensions you choose.

You can choose a text area that is longer that the frame. Then the user will have to scroll the frame to get to the Submit and Reset buttons. In this case, you might consider putting one set of buttons at the top of the text area and another at the bottom. This is a design choice.

The coding of the text area follows the standard format. There is also an attribute of wrap=virtual.

<TEXTAREA NAME="messtext" ROWS="10" COLS="70" WRAP="virtual">

A form enhancement was one of the less publicized additions to HTML that Netscape proposed and has implemented within Navigator 2.0 (
An attribute was added to the TEXTAREA tag called WRAP. There are three different options, as follows:
off-This is the default setting. There is no wrapping; lines are sent exactly as typed.
virtual-With this option, the display is word-wrapped, but the actual text is not. In other words, you see a long line wrapped, but the browser sends it as one long line to the server.
physical-With this option, the display is word-wrapped and the text is sent with all wrap points.
The syntax is:
<TEXTAREA WRAP="wrapvalue">

The final two elements are the buttons for submitting the document and an optional Reset button. The default wording is not used. Because this program is like a word processor or text editor, those types of terms are used.

<INPUT TYPE="submit" VALUE="Submit Message">
<INPUT TYPE="reset" VALUE="Reset:  Erase all text">

To finish this document, we only need to close the tags for both the FORM and HTML:


The code for this entire document is shown in listing 14.11. Figure 14.10 shows how this document looks inside our frame.

Figure 14.10: Notice the large message area waiting for a user to type something. The wrap attribute is set to virtual to force word-wrapping.

Listing 14.11  messcont.htm  Text Area in Lower Frame

<HTML><HEAD><TITLE>Message Editor by Ray Daly</TITLE></HEAD>
<BODY bgcolor ="aqua">
<FORM NAME="heavy"><P><B>Type your message in this box:</B><BR>
<TEXTAREA NAME="messarea" ROWS="10" COLS="70" WRAP="virtual">
<INPUT TYPE="submit" VALUE = "Submit Message" >
<INPUT TYPE="reset" VALUE = "Reset:  Erase all text">

You can add another button to this frame, as users might appreciate having a Preview button right next to the Submit button. This button allows users to preview their messages prior to submitting them. The Preview button is detailed in the section "The Preview" later in this chapter.

At this point, three of the four documents that make up the message editor are complete. The main code is in the control panel, which we will now develop.

The Controls in the Control Panel  The control panel will have three rows of controls. These controls prompt the user for text to be appended to the text in the text area with the appropriate HTML codes.

The first row will contain eight buttons all of approximately the same size. These buttons are for the physical styles: bold, italics, fixed, strike, blink, sup, and sub. (The buttons will display these words.) There will be an eighth button on this row called About.

The second row will contain nine controls. The first two buttons are of the same size as those in the first row. These are for the styles big and small. Then there will be much smaller buttons for font sizes 1 to 7. The last button on this row will be for Help.

The third row is a set of seven hyperlinks. The text for these are eight standard colors, except white. Each text will be displayed in its corresponding font color. The last control on the row will be a button for the preview feature.

Putting the Controls into a Table  The controls should appear properly spaced to make it easier for the user to find the button he wants. Aligning the buttons also makes it easier on the eyes. Figure 14.11 shows what we are trying to achieve. Figure 14.12 shows what it would look like without the table providing spacing and alignment.
Figure 14.11: This is how we want the control panel to appear. The alignment and spacing is more pleasing and the slightly different size of the buttons is less noticeable.
Figure 14.12: Without a table all of the controls are squished together, which makes it hard for the user to find the proper button.

To accomplish the desired layout of these controls, each will be centered within a cell of a table. The <TABLE> is being used only for layout purposes and has no borders. It will be effectively invisible to the user.

Given three rows of controls, the table will also have three rows. With both the top and bottom rows having eight controls, we know the minimum number of columns is also eight. Because the middle row has several smaller buttons and a total count of ten, we are going to double the number of columns to sixteen.

Centering buttons within cells of a table hides the fact that the buttons are different sizes.

The standard size buttons-those from the top and bottom rows-will be placed in cells that span two columns. The seven smaller buttons for font sizes in the second row will each be placed within single cells. The coding for this table is in listing 14.12.

There are comments inserted into the cells where coding will go for each control. Also, the entire table is between FORM tags because each button is a form element. The standard elements that define an HTML document are also there, including a background color of light gray. This code is shown in listing 14.12.

Listing 14.12  messcont.htm  Tabled Layout of Controls

<HTML><HEAD><TITLE>Message Editor by Ray Daly</TITLE>
</HEAD><BODY bgcolor ="white">
<TABLE WIDTH="100%" HEIGHT="100%" BORDER="0">
   <TR><TD COLSPAN=2><!-bold here->bold</TD>
       <TD COLSPAN=2><!-italics here->italics</TD>
       <TD COLSPAN=2><!-blink here->blink</TD>
       <TD COLSPAN=2><!-strike here->strike</TD>
       <TD COLSPAN=2><!-fixed here->fixed</TD>
       <TD COLSPAN=2><!-sub here->sub</TD>
       <TD COLSPAN=2><!-sup here->sup</TD>
       <TD COLSPAN=2><!-about here->about</TD>
   </TR><TR><TD COLSPAN=2><!-big here->big</TD>
       <TD COLSPAN=2><!-small here->small</TD>
       <TD><!-fontsize 1 here->1</TD>
       <TD><!-fontsize 2 here->2</TD>
       <TD><!-fontsize 3 here->3</TD>
       <TD><!-fontsize 4 here->4</TD>
       <TD><!-fontsize 5 here->5</TD>
       <TD><!-fontsize 6 here->6</TD>
       <TD><!-fontsize 7 here->7</TD>
       <TD><BR></TD><TD COLSPAN=2><BR></TD>          
       <TD COLSPAN=2><!-help here->help</TD>
   </TR><TR><TD COLSPAN=2><!-black fontcolor->black</TD>
       <TD COLSPAN=2><!-red fontcolor->red</TD>
       <TD COLSPAN=2><!-green fontcolor->green</TD>
       <TD COLSPAN=2><!-blue fontcolor->blue</TD>
       <TD COLSPAN=2><!-cyan fontcolor->cyan</TD>
       <TD COLSPAN=2><!-magenta fontcolor->magenta</TD>
       <TD COLSPAN=2><!-yellow fontcolor->yellow</TD>
       <TD COLSPAN=2><!-preview button->Preview</TD>

Putting Buttons into the Table  The coding for each of the buttons follows the same format. The HTML code creates a button displaying the name of the style (e.g., bold). Each contains an onClick event, which will call a function specifically to implement that feature. However, this coding will not be written until the next phase of developing this program. The following is the code for the Bold button:

<INPUT name="bold" type="button" value="  Bold  " 

This same coding is created for Italics, Fixed, Blink, Strike, Sub, Sup, Big, Small, 1, 2, 3, 4, 5, 6, and 7. Insert this coding into the correct cells of the table. The coding for all of these is shown in listing 14.13.

Listing 14.13  messcont.htm  Button Inputs Defined

<INPUT name="bold" type="button" value="  Bold  " onClick="stylemethod('bold')">
<INPUT NAME="italics" TYPE="button" VALUE="Italics" onClick="stylemethod('italics')">
<INPUT NAME="blink" TYPE="button" VALUE="  Blink  " onClick="stylemethod('blink')">
<INPUT NAME="strike" TYPE="button" VALUE=" Strike " onClick="stylemethod('strike')">
<INPUT NAME="fixed" TYPE="button" VALUE=" Fixed " onClick="stylemethod('fixed')">
<INPUT NAME="sub" TYPE="button" VALUE="  Sub  " onClick="stylemethod('sub')">
<INPUT NAME="sup" TYPE="button" VALUE="  Sup  " onClick="stylemethod('sup')">
<INPUT NAME="big" TYPE="button" VALUE="  Big  " onClick="stylemethod('big')">
<INPUT NAME="small" TYPE="button" VALUE="Small" onClick="stylemethod('small')">

About, Help, and Preview will have their own specialized functions so they do not call the same stylemethod. The code for these buttons is:

<INPUT NAME="about" TYPE="button" VALUE="  About  " onClick="aboutalert()"><
<INPUT NAME="help" TYPE="button" VALUE="   Help  " onClick="helppage()">
<INPUT NAME="preview" TYPE="button" VALUE="Preview" onClick="apreview(this.form)">

When you create a button, JavaScript makes the button just large enough to hold the text stored in the VALUE property. You can widen a button by adding extra spaces to the text of the VALUE property.
With a little experimenting, you can make most buttons appear to be the same width. However, browsers on other platforms and with other preferences may display different widths.

Hyperlinks as Controls  The third row of the control panel has seven hyperlinks that are used as controls. These are used instead of buttons to enable the user to actually see the different colors. This is essentially a simple color selector.

A color selector can be done in a variety of ways. You can have a SELECT list showing the string literals for all 150 colors. You can create a text box for users to input hexadecimal values, or you can create a SELECT drop-down list that has the names of the colors.
An exciting way would be to create a client-side image map of a color bar. The user can select a color and execute the appropriate JavaScript code by clicking anywhere on the color bar.

Originally I wrote the coding for these hyperlinks using the OnClick event. The problem was that I had to specify an HREF for either an anchor or a URL. All I wanted was to implement a JavaScript function without jumping to an anchor or loading a URL. So I set the HREF to a nonexistent anchor. This worked, however a future version of JavaScript might produce an error message. The following is an example of the code I originally used:

<A HREF=#bold  onClick="stylecolor('red')"> <FONT color="red">Red </ FONT></A>

It turns out that this is a perfect case for using the new javascript: protocol. Instead of specifying an anchor, a URL, or even a mailto:, you can specify JavaScript code. In our case, we want to specify executing a function for the color represented by the hyperlink. So now the code looks like this:

<A HREF="javascript: stylecolor('red')"> <FONT color="red">Red </ FONT></A>

Easter Egg is a term in video games for an undocumented, hidden feature. By using fontcolor methods, you can make a hyperlink invisible. Just make the fontcolor the same as the normal text color. The only clue would be in the status bar.
The javascript: protocol allows you to make hyperlinks behave like buttons. So if you don't like being limited to the predefined buttons, use a hyperlink, the javascript: protocol, and your own image as an icon.

<A HREF=#bold  onClick="stylemethod('red')">
<FONT color="red">Red </FONT></A>

Create this same coding for black, green, blue, yellow, cyan, and magenta. Obviously, if you don't like these colors, just pick another set. Insert this code into the correct cells of the table. The complete code for the tables with all of the hyperlinks and buttons is shown in listing 14.14.

Listing 14.14  messcont.htm  Tabled Layout of Buttons

<HTML><HEAD><TITLE>Message Editor by Ray Daly</TITLE>
</HEAD><BODY bgcolor ="lightgrey">
<TABLE WIDTH="100%" HEIGHT="100%" BORDER="0">
   <INPUT NAME="bold" TYPE="button" VALUE=" Bold " 
   <TD COLSPAN=2>       
   <INPUT NAME="italics" TYPE="button" VALUE="Italics" 
   <INPUT NAME="blink" TYPE="button" VALUE="  Blink  " 
   <INPUT NAME="strike" TYPE="button" VALUE=" Strike " 
   <INPUT NAME="fixed" TYPE="button" VALUE=" Fixed " 
   <INPUT NAME="sub" TYPE="button" VALUE="  Sub  " 
   <TD COLSPAN=2>      
   <INPUT NAME="sup" TYPE="button" VALUE="  Sup  " 
   <INPUT NAME="about" TYPE="button" VALUE="  About  " 
   <INPUT NAME="big" TYPE="button" VALUE="  Big  " 
   <TD COLSPAN=2>       
   <INPUT NAME="small" TYPE="button" VALUE="Small" 
   <TD><INPUT NAME="1" TYPE="button" VALUE="  1 " 
   <TD><INPUT NAME="2" TYPE="button" VALUE="  2 " 
onClick="stylemethod('Size 2')"></TD>
   <TD><INPUT NAME="3" TYPE="button" VALUE="  3 " 
onClick="stylemethod('Size 3')"></TD>
   <TD><INPUT NAME="4" TYPE="button" VALUE="  4 " 
onClick="stylemethod('Size 4')"></TD>
   <TD><INPUT NAME="5" TYPE="button" VALUE="  5 " 
onClick="stylemethod('Size 5')"></TD>
   <TD><INPUT NAME="6" TYPE="button" VALUE="  6 " 
onClick="stylemethod('Size 6')"></TD>
   <TD><INPUT NAME="7" TYPE="button" VALUE="  7 " 
onClick="stylemethod('Size 7')"></TD>
   <TD COLSPAN=2><BR></TD>          
   <INPUT NAME="help" TYPE="button" VALUE="   Help  " 
</TR><TR><TD COLSPAN=2 ALIGN="center">
<A HREF="javascript: stylecolor('black')">
             <FONT COLOR="black"><B>Black</B></FONT></A></TD>
       <TD COLSPAN=2 ALIGN="center">
       <A HREF="javascript: stylecolor('red')">
            <FONT COLOR="red"><B>Red</FONT></B></A></TD>
       <TD COLSPAN=2 ALIGN="center">
       <A HREF="javascript: stylecolor('green')">
              <FONT COLOR="green"><B>Green</B></FONT></A></TD>
       <TD COLSPAN=2 ALIGN="center">
       <A HREF="javascript: stylecolor('blue')">
              <FONT COLOR="blue"><B>Blue</B></FONT></A></TD>
       <TD COLSPAN=2 ALIGN="center">
       <A HREF="javascript: stylecolor('cyan')">
              <FONT COLOR="cyan">Cyan</FONT></B></A></TD>
       <TD COLSPAN=2 ALIGN="center">
       <A HREF="javascript: stylecolor('magenta')">
              <FONT COLOR="magenta"><B>Magenta</B></FONT></A></TD>
       <TD COLSPAN=2 ALIGN="center">
       <A HREF="javascript: stylecolor('yellow')">
              <FONT COLOR="yellow"><B>Yellow</B></FONT></A></TD>
       <TD COLSPAN=2>
       <INPUT NAME="preview" TYPE="button" VALUE="Preview" 

Double Check the Layout  You now have enough code to check your layout. Start your browser and load the code you have so far. You should see a layout just like that shown in figure 14.13.
Figure 14.13: The layout of the message editor is only a facade at this point, but it is better to get the layout done and then put code behind it.

Normally at this point in your program development, you would spend some time polishing the layout. You might rearrange the controls, change a description, or decide on a different color background. You may or may not want to do this now, depending on how you like the choices made so far. If you like what you see, let's proceed and make this thing do some work.

Program Structure or Coding the Events

Although the message editor has 26 different controls on the control panel, most perform nearly identical functions. Most controls prompt for a text string, apply a font method to the string, and then append it to the text in the text area. The Help and About buttons simply display text. And finally, we have the best feature of all: the Preview button.

Font Methods

For all of the font style buttons, there is one function. Each button calls this function and passes a single value: the name of the style. The function uses this value in the prompt box text and to decide which method to apply to the text. Although it creates a rather long function, it does keep down the number of functions.

The Function stylemethod( )  The first thing stylemethod() does is display a dialog box in which the user can enter the text. This is the text that will be highlighted in the given style. You will note that the prompt message reminds the user of the style selected. This goes after </TITLE> and before </HEAD>, and is shown in listing 14.15.

Listing 14.15  messcont.htm  Start Adding Functions

<SCRIPT LANGUAGE = "JavaScript">
<!-- hide code from other browsers
function stylemethod (style) {
     x = prompt ("Enter your text for the style:" + style, "")
      if ((x!=null) && (x!="")) {
          <!-- many if statements will go here -->
// no more hiding -->

The next several lines of code are a series of if statements. To the text string returned from the prompt dialog box, we must now apply the proper font method. This is the section of code for the condition in which the style was bold.

if (style=="bold") {
     x = x.bold()

Additional if statements must be created for each of the additional 15 font methods using buttons. This code is shown in listing 14.16.

Each of the above if statements produces a string with the appropriate HTML tags surrounding the string to be highlighted. This string is now simply appended to the existing text in the text area.

Listing 14.16  messcont.htm  If Statements of Style Function

         if (style == "bold") {
            x = x.bold()
        if (style == "italics") {
            x = x.italics()
        if (style == "blink") {
            x = x.blink()
        if (style == "strike") {
            x = x.strike()
        if (style == "fixed") {
            x = x.fixed()
        if (style == "sub") {
            x = x.sub()
        if (style == "sup") {
            x = x.sup()
        if (style == "big") {
            x = x.big()
        if (style == "small") {
            x = x.small()
        if (style == "Size 1") {
            x = x.fontsize(1)
        if (style == "Size 2") {
            x = x.fontsize(2)
        if (style == "Size 3") {
            x = x.fontsize(3)
        if (style == "Size 4") {
            x = x.fontsize(4)
        if (style == "Size 5") {
            x = x.fontsize(5)
        if (style == "Size 6") {
            x = x.fontsize(6)
         if (style == "Size 7") {
            x = x.fontsize(7)

The Function stylecolor( )  Though the method of applying color to strings is the same as other font methods, we are going to add a feature when using the fontcolor method. So we need a function just for colors, which we will call stylecolor( ). When you select a color control, you will change the color in the small frame in the upper-left corner. This provides the user with feedback and visually reminds the user which color he has selected. The code for this function is shown in listing 14.17.

Listing 14.17  messcont.htm  Function stylecolor( )

function stylecolor(style) {
  parent.messcolr.document.bgColor = style
  x = prompt ("Enter your text for the style: "+ style, "")
     if ((x!=null)&&(x!="")) {
          x = x.fontcolor(style)
parent.messarea.document.heavy.messtext.value = 
                      parent.messarea.document.heavy.messtext.value + x + ' ' 

Adding the String to the Textarea  We now have the text string with the proper method applied to it. The goal is to append this string to the text already in the textarea in the lower frame.

In a case without frames and with a single form, this task is simple. We would just add the string to the existing value of the textarea. For a string of x with a form named heavy and a textarea named messtext, the code would simply be as follows:

heavy.messtext.value=heavy.messtext.value + x + " "

A space is added at the end of each insertion for separation.

In our message editor example we have an application using frames. We are trying to add text from code in one frame (the control panel) to the textarea in another frame. We need to reach across the frames. To do this we will use the name of the frame, the form, and the textarea. In our case these names are messarea, heavy, and messtext. We also know that both frames are part of the same frameset. So our final line of the function looks like the following:

parent.messarea.document.heavy.messtext.value = 
               parent.messarea.document.heavy.messtext.value + x + ' 

From the control panel we are adding the text to messtext, which is in form heavy, which is part of the document in the frame named messarea. This frame is part of the same frameset as the control panel so they both have the same parent.

The About and Help Features

So far we have treated the About and Help buttons as part of the style function. This was great for testing the application, but we now want to make these buttons work.

The About button simply tells the user such information as where the program originated, the name of the author, and the version number. The coding is straight- forward:

function aboutalert () {
     alert ("Message Editor by Ray Daly from JavaScript Special

The Help function opens a new window with a help message, as seen in figure 14.14. This comes from another file, messhelp.htm (see listing 14.18). The code to open this window is as follows:

Figure 14.14: The Help screen for Message Editor is static. A more elaborate Help screen could contain the same controls as the control panel and provide help for each control.

function helppage () {
     helpwin=open ("messhelp.htm", "HelpWindow","toolbar=no,scrollbars=yes")

Listing 14.18  messhelp.htm  Help Screen for Message Editor

<HTML><HEAD><TITLE>messhelp.htm by Ray Daly </TITLE></HEAD><BODY>
<CENTER><H3>Help Screen for Message Editor</H3></CENTER>
<P>The purpose of this Message Editor is to allow you to create a message where you 
can use the various styles available to you on Web pages.   These include:</P>
<B>Bold</B> <I>Italics</I> <BLINK>Blink</BLINK> <STRIKE>Strike</STRIKE> Fixed 
<SUB>Sub</SUB> <SUP>Sup</SUP> <BR>
<BIG>Big</BIG> <SMALL>Small</SMALL> <FONT SIZE="1">Size 1</FONT> 
<FONT SIZE="2">Size 2</FONT> <FONT SIZE="3">Size 3</FONT> <FONT SIZE="4">Size 4</FONT> 
<FONT SIZE="5">Size 5</FONT> <FONT SIZE="6">Size 6</FONT> <FONT SIZE="7">Size 7</FONT> <BR>
<FONT COLOR="black">Black</FONT> <FONT COLOR="red">Red</FONT> 
<FONT COLOR="green">Green</FONT> <FONT COLOR="blue">Blue</FONT> 
<FONT COLOR="cyan">Cyan</FONT> <FONT COLOR="magenta">Magenta</FONT> 
<FONT COLOR="yellow">Yellow</FONT> 
<P>You create messages by typing text in the text box on the lower part of the screen. 
Besides typing normal text, you can also manually type in HTML tags.  The Message Editor 
makes it easier to insert style tags by providing buttons and controls on the top 
portion of the screen.</P>
<P>Each of the style buttons or controls work in the same fashion.  Click on a button 
and you are prompted to type in a line of text.  When you are finished typing, your text 
is automatically inserted into the text box with the proper HTML style tags.  Try it, 
you can always erase it.</B>
<P><B>Preview</B> your message by pressing the Preview button.  This will open up a new 
browser window where you can see exactly how your message will look with the HTML styles 
applied.  When you are satisfied with your work, submit it to your BBS.</P>

The Preview

You have waited to the very end of this chapter for the best feature of this program. You may be disappointed at how short this code is. The purpose of this code is to take the HTML document created in the text area and display it on its own page. The code is shown in listing 14.19.

Listing 14.19  messcont.htm  Preview Function

function apreview (form) {
      msg = open ("","DisplayWindow","toolbar=yes")
      starttags ="<HTML><HEAD><TITLE>Preview</TITLE></
      endtags = "</PRE></P></BODY></HTML>"
      y = starttags + parent.messarea.document.heavy.messtext.value +
      msg.document.write (y)

The function for preview is called apreview, not preview. This is because the button itself is already using the name preview (see fig. 14.15). Unlike some other languages, function and object names can conflict.

Figure 14.15: The message in the text box can be typed in or entered by pressing the control buttons. You can see how your message displays in a browser in figure 14.16.

The limitation built into this design is that only one style can be applied at a time. For example, using the controls, it does not allow bold italics or green big. Of course, you can manually enter the codes in the text area to create these physical styles. This limitation does force your users to keep their affects simple. Such simplicity can produce better design.

As the message editor was designed, it only allows a single paragraph message. To make it more useful, include a control to add the paragraph tags.