Chapter 2

Talking to the Page

In This Chapter

arrow Introducing the Document Object Model

arrow Responding to form events

arrow Connecting a button to a function

arrow Retrieving data from text fields

arrow Changing text in text fields

arrow Sending data to the page

arrow Working with other text-related form elements

JavaScript is fun and all, but it lives in web browsers for a reason: to let you change web pages. The best thing about JavaScript is how it helps   you control the page. You can use JavaScript to read useful information from the user and to change the page on the fly.

Understanding the Document Object Model

JavaScript programs usually live in the context of a web page. The contents of the page are available to the JavaScript programs through a mechanism called the Document Object Model (DOM).

The DOM is a special set of complex variables that encapsulates the entire contents of the web page. You can use JavaScript to read from the DOM and determine the status of an element. You can also modify a DOM variable and change the page from within JavaScript code.

Previewing the DOM

The easiest way to get a feel for the DOM is to load a page in Chrome and play around in the console. Follow these steps to get a feel for the DOM:

  1. Use the Chrome browser.

    Most browsers have something like the web developer console used in this example, but Chrome's is very easy to use and comes built-in, so you should begin with that one.

  2. Load any page you want.

    It's probably easiest to start with a page that's relatively simple, so you can get a sense of what's happening.

  3. Turn on the web developer toolbar.

    Use the F12 key, View ⇒ Developer ⇒ Developer Tools or Tools ⇒ Developer Tools from the menu. (It may vary based on your version of Chrome or your operating system.)

  4. Go to the Console tab.

    The Developer Tools window has many tabs, but the console tab is the one we need for now (and it will continue to be useful as you get more advanced).

  5. Type document.

    Don't forget the period at the end. When you type a period, Chrome's auto-complete describes all the various elements related to the document. document is a very fancy variable (called an object) that contains a ton of sub-variables. You can scroll through this list to see all the things related to document.

  6. Change the page's background color.

    Try typing this in the console:

      document.body.style.backgroundColor = “green”

    You can use this trick to (temporarily) change all kinds of features.

  7. Play around with the document tree a bit more.

    It's fine if you don't know exactly what's going on yet, but use this technique to get a general feel for the complexity of the page and all the interesting things you can do with it.

Figure 2-1 illustrates a simple web page being dynamically modified through the console tab.

9781118289389-fg1901.tif

Figure 2-1: Even a very simple page has a complex DOM.

tip.eps The Console tab is far more involved and powerful than I'm letting on here. Chapter 3 of this mini-book goes into all kinds of details about how to use this powerful tool to figure out what's going on in your page.

When you look over the DOM of a simple page, you can easily get overwhelmed. You'll see a lot of variables listed. Technically, these variables are all elements of a special object called window. The window object has a huge number of subobjects, all listed in the DOM view. Table 1 describes a few important window variables.

Table 2-1 Primary DOM Objects

Variable

Description

Notes

document

Represents HTML page

Most commonly scripted element

location

Describes current URL

Change location.href to move to a new page

history

A list of recently visited pages

Access this to view previous pages

status

The browser status bar

Change this to set a message in the status bar

Getting the blues, JavaScript-style

It all gets fun when you start to write JavaScript code to access the DOM. Take a look at blue.html in Figure 2-2.

9781118289389-fg1902.tif

Figure 2-2: This page is blue. But where's the CSS?

The page has white text on a blue background, but there's no CSS! Instead, it has a small script that changes the DOM directly, controlling the page colors through code.

  <!DOCTYPE html>
<html lang = "en-US">

  <head>
    <meta charset = "UTF-8">
    <title>blue.html</title>
  </head>
  <body>
    <h1>I've got the JavaScript Blues</h1>
    <script type = "text/javascript">
      // use javascript to set the colors
      document.body.style.color = "white";
      document.body.style.backgroundColor = "blue";
    </script>
  </body>
</html>
 

Writing JavaScript code to change colors

The page shown in Figure 2-3 is pretty simple, but it has a few unique features.

9781118289389-fg1903.tif

Figure 2-3: The page is white. It has two buttons on it. I've gotta click Blue.

  • It has no CSS. A form of CSS is dynamically created through the code.
  • The script is in the body. I can't place this particular script in the header because it refers to the body.

    technicalstuff.eps When the browser first sees the script, there must be a body for the text to change. If I put the script in the head, no body exists when the browser reads the code, so it gets confused. If I place the script in the body, there is a body, so the script can change it. (It's really okay if you don't get this discussion. This example is probably the only time you'll see this trick because I show a better way in the next example.)

  • Use a DOM reference to change the style colors. That long “trail of breadcrumbs” syntax (document.body.style.color) takes you all the way from the document through the body to the style and finally the color. It's tedious but thorough.
  • Set the foreground color to white. You can change the color property to any valid CSS color value (a color name or a hex value). It's just like CSS because you are affecting the CSS.
  • Set the background color to blue. Again, this adjustment is just like setting CSS.

Managing Button Events

Of course, there's no good reason to write code like blue.html. You will find that it's just as easy to build CSS as it is to write JavaScript. The advantage comes when you use the DOM dynamically to change the page's behavior after it has finished loading.

Figure 2-3 shows a page called backgroundColors.html.

The page is set up with the default white background color. It has two buttons on it, which should change the body's background color. Click the Blue button, and you see that it works, as verified in Figure 2-4.

9781118289389-fg1904.tif

Figure 2-4: It turned blue! Joy!

Some really exciting things just happened.

  • The page has a form. For more information on form elements, refer to Book I, Chapter 7.
  • The buttons do something. Plain-old HTML forms don't really do anything. You've got to write some kind of programming code to accomplish a task. This program does it. Twice. All for free.
  • Each button has a special attribute called onclick: The onclick attribute is an event handler. This is special because it allows you to apply some sort of action to the button press. The action (a single line of JavaScript code) assigned to onclick will happen each time the button is clicked.
  • Each button changes the background to a different color: The Blue button makes the background blue and the White one — well, you get it. I simply used the code from the console example to change the background colors.
  • The code is integrated directly into the buttons: You can attach one line of JavaScript code to a button's onclick event. I use that line to change the background colors.

Here's the code:

  <!DOCTYPE html>
<html lang = "en-US">
 
  <head>
    <meta charset = "UTF-8">
    <title>backgroundColors</title>
  </head>
  <body>
    <h1>Click a button to change the color</h1>
    <form action = "">
      <fieldset>
        <input type = "button"
               value = "blue"
               onclick = "document.body.style.backgroundColor = 'blue'"/>
        <input type = "button"
               value = "white"
               onclick = "document.body.style.backgroundColor = 'white'" />
      </fieldset>
    </form>
  </body>
</html>

Adding a function for more … functionality

The buttons work, but the program seems quite inefficient. First, buttons can only have one line of code attached to the onclick event handler. Secondly, the code is almost exactly the same in both buttons. There must be a more efficient way. Most of the time, JavaScript code is not done one line at a time. Instead, it is packaged into a special element called a function. Functions are simply a collection of code lines with a name. Functions can also be sent an optional parameter, and they can return output. You learn much more about functions in Chapter 4 of this minibook, but look at this basic version for now.

  <!DOCTYPE html>
<html lang = "en-US">

  <head>
    <meta charset = "UTF-8">
    <title>backgroundColors</title>
    <script type = "text/javascript">
      // from backgroundColors
      function makeBlue(){
        document.body.style.backgroundColor = "blue";
      } // end changeColor
 
      function makeWhite(){
        document.body.style.backgroundColor = "white";
      }
    </script>
  </head>
  <body>
    <h1>Click a button to change the color</h1>
    <form action = "">
      <fieldset>
        <input type = "button"
               value = "blue"
               onclick = "makeBlue()"/>
        <input type = "button"
               value = "white"
               onclick = "makeWhite()" />
      </fieldset>
    </form>
  </body>
</html>

This program looks and acts exactly like the program in Figures 2-3 and 2-4, so I don't provide a screenshot here. The important thing is how I've improved the code underneath the visible part of the page.

Something interesting is happening here. Take a look at how this program has changed from the first one.

  1. There's a function called makeBlue()in the script area.

    The function keyword allows you to collect one or more commands and give them a name. In this case, I'm giving that nasty document.body.style nonsense a much more sensible name — makeBlue().

  2. The parentheses are necessary.

    Whenever you define a function, you have to include parentheses, but sometimes (as in this simple example), they're empty. You see how to add something to the parentheses in the next example.

  3. One or more lines of code go inside the function.

    Mark a function with squiggle braces ({}). This example has only one line of code in the function, but you can have as many code lines as you want.

  4. The function name describes what the function does.

    Functions are used to simplify code, so it's really important that a function name describes what the function does.

  5. Another function makes the background white.

    One button makes the background blue, and the other makes it white, so I'll make a function to go with each button.

  6. Attach the functions to the buttons.

    Now the buttons each call a function rather than doing the work directly.

remember.eps You might wonder if all this business of making a function is worth the effort — after all, these programs seem exactly the same — but the new one is a bit more work. In this very simple example, the functions are a little more work but clarify the code a smidge. As your programs get more complex, there's no doubt that functions improve things, especially as you learn more about how functions work.

Making a more flexible function

The version of the code that uses functions doesn't seem a lot easier than adding the code directly, and it isn't. But functions are much more powerful than simply renaming a line of code. If you think about the two functions in that example, you quickly realize they're almost exactly the same. It would be awesome if you could write one simple function and have it change the background to any color you want. That's exactly what happens in the next example (backgroundColorFunction.html). Here's the code:

  <!DOCTYPE html>
<html lang = "en-US">
 
  <head>
    <meta charset = "UTF-8">
    <title>backgroundColors</title>
    <script type = "text/javascript">
      // from backgroundColors
      function changeColor(color){
        document.body.style.backgroundColor = color;
      } // end changeColor
    </script>
  </head>
  <body>
    <h1>Click a button to change the color</h1>
    <form action = "">
      <fieldset>
        <input type = "button"
               value = "blue"
               onclick = "changeColor('blue')"/>
        <input type = "button"
               value = "white"
               onclick = "changeColor('white')" />
      </fieldset>
  </form>
  </body>
</html>

Once again, this program will seem to the casual user to be exactly like the programs in Figures 2-3 and 2-4, so I'm not including a screen shot. This is an important part of computer programming. Often the most important changes are not visible to the user. If you've ever hired a programmer, you're no doubt aware of this issue.

  • The page has a single changeColor()function. The page has only one function called changeColor() defined in the header.
  • The changeColor()function includes a color parameter. This time, there's a value inside the parentheses:

      function changeColor(color){

    The term color inside the parentheses is called a parameter. A parameter is a value sent to a function. Inside the function, color is available as a variable. When you call a function, you can send a value to it, like this:

      changeColor('white'),

    This sends the text value ‘white’ to the function, where it becomes the value of the color variable.

    technicalstuff.eps You'll sometimes see the terms argument and parameter used interchangeably to reference the stuff passed to a function, but these terms are not exactly the same. Technically, the parameter is the variable name (color) and the argument is the value of that variable (‘white’).

    You can design a function with as many parameters as you wish, but you need to name each one. After a function is designed with parameters, you must supply an argument for each parameter when you call the function.

  • Both buttons pass information to changeColor: Both of the buttons call the changeColor() function, but they each pass a different color value. This is one of the most useful characteristics of functions. They allow you to repeat code that's similar but not identical. That makes it possible to build very powerful functions that can be reused easily.

Embedding quotes within quotes

Take a careful look at the onclick lines in the code in the preceding section. You may not have noticed one important issue:

onclick is an HTML parameter, and its value must be encased in quotes. The parameter happens to be a function call, which sends a string value. String values must also be in quotes. This setup can become confusing if you use double quotes everywhere because the browser has no way to know the quotes are nested. Look at this incorrect line of code:

  onclick = "changeColor("white")" />

HTML thinks the onclick parameter contains the value "changeColor(" and it will have no idea what white")" is.

Fortunately, JavaScript has an easy fix for this problem. If you want to embed a quote inside another quote, just switch to single quotes. The line is written with the parameter inside single quotes:

  onclick = "changeColor('white')" />

Writing the changeColor function

The changeColor() function is pretty easy to write.

  <script type = "text/javascript">
  // from backgroundColors
 
  function changeColor(color){
    document.body.style.backgroundColor = color;
  } // end changeColor
 //
</script>

It goes in the header area as normal. It's simply a function accepting one parameter called color. The body's backgroundColor property is set to color.

technicalstuff.eps I can write JavaScript in the header that refers to the body because the header code is all in a function. The function is read before the body is in place, but it isn't activated until the user clicks the button. By the time the user activates the code by clicking on the button, there is a body, and there's no problem.

Managing Text Input and Output

Perhaps the most intriguing application of the DOM is the ability to let the user communicate with the program through the web page, without all those annoying dialog boxes. Figure 2-5 shows a page with a web form containing two textboxes and a button.

9781118289389-fg1905.tif

Figure 2-5: I've typed a name into the top textbox.

When you click the button, something exciting happens, demonstrated by Figure 2-6.

9781118289389-fg1906.tif

Figure 2-6: I got a greeting! With no alert box!

Clearly, form-based input and output is preferable to the constant interruption of dialog boxes.

Introducing event-driven programming

Graphic user interfaces usually use a technique called event-driven programming. The idea is simple.

  1. Create a user interface.

    In web pages, the user interface is usually built of HTML and CSS.

  2. Identify events the program should respond to.

    If you have a button, users will click it. (If you want to guarantee they click it, put the text “Launch the Missiles” on the button. I don't know why, but it always works.) Buttons almost always have events. Some other elements do, too.

  3. Write a function to respond to each event.

    For each event you want to test, write a function that does whatever needs to happen.

  4. Get information from form elements.

    Now you're accessing the contents of form elements to get information from the user. You need a mechanism for getting information from a text field and other form elements.

  5. Use form elements for output.

    For this simple example, I also use form elements for output. The output goes in a second textbox, even though I don't intend the user to type any text there.

Creating the HTML form

The first step in building a program that can manage text input and output is to create the HTML framework. Here's the HTML code:

  <!DOCTYPE html>
<html lang = "en-US">

  <head>
    <meta charset = "UTF-8">
    <title>textBoxes.html</title>
    <script type = "text/javascript">
      // from textBoxes.html
      function sayHi(){
        var txtName = document.getElementById("txtName");
        var txtOutput = document.getElementById("txtOutput");
        var name = txtName.value;
        txtOutput.value = "Hi there, " + name + "!"
      } // end sayHi
    </script>
    <link rel = "stylesheet"
          type = "text/css"
          href = "textBoxes.css" />
  </head>
  <body>
    <h1>Text Box Input and Output</h1>
    <form action = "">
      <fieldset>
        <label>Type your name: </label>
        <input type = "text"
               id = "txtName" />
        <input type = "button"
               value = "click me"
               onclick = "sayHi()"/>
        <input type = "text"
               id = "txtOutput" />
      </fieldset>
    </form>
  </body>
</html>

As you look over the code, note a few important ideas:

  • The page uses external CSS. The CSS style is nice, but it's not important in the discussion here. It stays safely encapsulated in its own file. Of course, you're welcome to look it over or change it.
  • Most of the page is a form. All form elements must be inside a form.
  • A fieldset is used to contain form elements. input elements need to be inside some sort of block-level element, and a fieldset is a natural choice.
  • There's a text field named txtName. This text field contains the name. I begin with the phrase txt to remind myself that this field is a textbox.
  • The second element is a button. You don't need to give the button an ID (as it won't be referred to in code), but it does have an onclick() event.
  • The button's onclick event refers to a (yet undefined) function. In this example, it's named “sayHi()”.
  • A second textbox contains the greeting. This second textbox is called txtOutput because it's the text field meant for output.

After you set up the HTML page, the function becomes pretty easy to write because you've already identified all the major constructs. You know you need a function called sayHi(), and this function reads text from the txtName field and writes to the txtOutput field.

Using getElementById to get access to the page

HTML is one thing, and JavaScript is another. You need some way to turn an HTML form element into something JavaScript can read. The magical getElementById() method does exactly that. First, look at the first two lines of the sayHi() function (defined in the header as usual).

      function sayHi(){
        var txtName = document.getElementById("txtName");
        var txtOutput = document.getElementById("txtOutput");

You can extract every element created in your web page by digging through the DOM. In the old days, this approach is how we used to access form elements. It was ugly and tedious. Modern browsers have the wonderful getElementById() function instead. This beauty searches through the DOM and returns a reference to an object with the requested ID.

A reference is simply an indicator where the specified object is in memory. You can store a reference in a variable. Manipulating this variable manipulates the object it represents. If you want, you can think of it as making the textbox into a variable.

Note that I call the variable txtName, just like the original textbox. This variable refers to the text field from the form, not the value of that text field. After I have a reference to the text field object, I can use its methods and properties to extract data from it and send new values to it.

Manipulating the text fields

After you have access to the text fields, you can manipulate the values of these fields with the value property:

        var name = txtName.value;
      txtOutput.value = "Hi there, " + name + "!"

Text fields (and, in fact, all input fields) have a value property. You can read this value as an ordinary string variable. You can also write to this property, and the text field will be updated on the fly.

This code handles the data input and output:

  1. Create a variable for the name.

    This is an ordinary string variable.

  2. Copy the value of the textbox into the variable.

    Now that you have a variable representing the textbox, you can access its value property to get the value typed in by the user.

  3. Create a message for the user.

    Use ordinary string concatenation.

  4. Send the message to the output textbox.

    You can also write text to the value property, which changes the contents of the text field on the screen.

remember.eps Text fields always return string values (like prompts do). If you want to pull a numeric value from a text field, you may have to convert it with the parseInt() or parseFloat() functions.

Writing to the Document

Form elements are great for getting input from the user, but they're not ideal for output. Placing the output in an editable field really doesn't make much sense. Changing the web document is a much better approach.

The DOM supports exactly such a technique. Most HTML elements feature an innerHTML property. This property describes the HTML code inside the element. In most cases, it can be read from and written to.

technicalstuff.eps So what are the exceptions? Single-element tags (like <img> and <input>) don't contain any HTML, so obviously reading or changing their inner HTML doesn't make sense. Table elements can often be read from but not changed directly.

Figure 2-7 shows a program with a basic form.

9781118289389-fg1907.tif

Figure 2-7: Wait, there's no output text field!

This form doesn't have a form element for the output. Enter a name and click the button, and you see the results in Figure 2-8.

9781118289389-fg1908.tif

Figure 2-8: The page has changed itself.

Amazingly enough, this page can make changes to itself dynamically. It isn't simply changing the values of form fields, but changing the HTML.

Preparing the HTML framework

To see how the page changes itself dynamically, begin by looking at the HTML body for innerHTML.html:

  <body>
    <h1>Inner HTML Demo</h1>
    <form action = "">
      <fieldset>
        <label>Please type your name</label><p>
        <input type = "text"
               id = "txtName" />
        <button type = "button"
                onclick = "sayHi()">
          Click Me
        </button>
      </fieldset>
    </form>
 
    <div id = "divOutput">
      Watch this space.
    </div>
  </body>

The code body has a couple of interesting features:

  • The program has a form. The form is pretty standard. It has a text field for input and a button, but no output elements.
  • The button will call a sayHi()function. The page requires a function with this name. Presumably, it says hi somehow.
  • There's a div for output. A div element in the main body is designated for output.
  • The div has an ID. The id attribute is often used for CSS styling, but the DOM can also use it. Any HTML elements that will be dynamically scripted should have an id field.

Writing the JavaScript

The JavaScript code for modifying innerHTML isn't very hard:

    <script type = "text/javascript">
      //from innerHTML.html
 
      function sayHi(){
        txtName = document.getElementById("txtName");
        divOutput = document.getElementById("divOutput");
 
        name = txtName.value;
 
        divOutput.innerHTML = "<em>" + name +  "</em>";
        divOutput.innerHTML += " is a very nice name.";
      }
  </script>

The first step (as usual with web forms) is to extract data from the input elements. Note that I can create a variable representation of any DOM element, not just form elements. The divOutput variable is a JavaScript representation of the DOM div.

Finding your innerHTML

Like form elements, divs have other interesting properties you can modify. The innerHTML property allows you to change the HTML code displayed by the div. You can put any valid HTML code you want inside the innerHTML property, even HTML tags. Be sure that you still follow the HTML rules so that your code will be valid.

Working with Other Text Elements

When you know how to work with text fields, you've mastered about half of the form elements. Several other form elements work exactly like text fields, including these:

  • Password fields obscure the user's input with asterisks, but preserve the text.
  • Hidden fields allow you to store information in a page without revealing it to the user. (They're used a little bit in client-side coding, but almost never in JavaScript.)
  • Text areas are a special variation of textboxes designed to handle multiple lines of input.

Figure 2-9 is a page with all these elements available on the same form.

9781118289389-fg1909.tif

Figure 2-9: Passwords, hidden fields, and text areas all look the same to JavaScript.

When the user clicks the button, the contents of all the fields (even the password and hidden fields) appear on the bottom of the page, as shown in Figure 2-10.

9781118289389-fg1910.tif

Figure 2-10: Now you can see what was in everything.

Building the form

Here's the HTML (otherText.html) that generates the form shown in Figures 2-9 and 2-10:

  <body>
    <h1>Text Input Devices</h1>
    <form action = "">
      <fieldset>
        <label>Normal Text field</label>
        <input type = "text"
               id = "txtNormal" />
        <label>Password field</label>
        <input type = "password"
               id = "pwd" />
        <label>Hidden</label>
        <input type = "hidden"
               id = "hidden"
               value = "I can't tell you" />
        <textarea id = "txtArea"
                  rows = "10"
                  cols = "40">
This is a big text area.
It can hold a lot of text.           
        </textarea>
        <button type = "button"
                onclick = "processForm()">
          Click Me
        </button>
      </fieldset>
   </form>
 
  <div id = "output">
    
  </div>
  </body>

The code may be familiar to you if you read about form elements in Book I, Chapter 7. A few things are worth noting for this example:

  • An ordinary text field appears, just for comparison purposes. It has an id so that it can be identified in the JavaScript.
  • The next field is a password field. Passwords display asterisks, but store the actual text that was entered. This password has an id of pwd.
  • The hidden field is a bit strange. You can use hidden fields to store information on the page without displaying that information to the user. Unlike the other kinds of text fields, the user can't modify a hidden field. (She usually doesn't even know it's there.) This hidden field has an id of secret and a value (“I can't tell you”).
  • The text area has a different format. The input elements are all single-tag elements, but the textarea is designed to contain a large amount of text, so it has beginning and end tags. The text area's id is txtArea.
  • A button starts all the fun. As usual, most of the elements just sit there gathering data, but the button has an onclick event associated with it, which calls a function.
  • External CSS gussies it all up. The page has some minimal CSS to clean it up. The CSS isn't central to this discussion, so I don't reproduce it. Note that the page will potentially have a dl on it, so I have a CSS style for it, even though it doesn't appear by default.

warning.eps The password and hidden fields seem secure, but they aren't. Anybody who views the page source will be able to read the value of a hidden field, and passwords transmit their information in the clear. You really shouldn't be using web technology (especially this kind) to transport nuclear launch codes or the secret to your special sauce. (Hmmm, maybe the secret sauce recipe is the launch code — sounds like a bad spy movie.)

tip.eps When I create a text field, I often suspend my rules on indentation because the text field preserves everything inside it, including any indentation.

Writing the function

After you build the form, all you need is a function. Here's the good news: JavaScript treats all these elements in exactly the same way! The way you handle a password, hidden field, or text area is identical to the technique for a regular text field (described under “Managing Text Input and Output,” earlier in this chapter). Here's the code:

        // from otherText.html
      function processForm(){
        //grab input from form
        var txtNormal = document.getElementById("txtNormal");
        var pwd = document.getElementById("pwd");
        var hidden = document.getElementById("hidden");
        var txtArea = document.getElementById("txtArea");
        
        var normal = txtNormal.value;
        var password = pwd.value;
        var secret = hidden.value;
        var bigText = txtArea.value;
        
        //create output
        var result = ""
        result += "<dl> ";
        result += "  <dt>normal</dt> ";
        result += "  <dd>" + normal + "</dd> ";
        result += " ";
        result += "  <dt>password</dt> ";
        result += "  <dd>" + password + "</dd> ";
        result += " ";
        result += "  <dt>secret</dt> ";
        result += "  <dd>" + secret + "</dt> ";
        result += "    ";
        result += "  <dt>big text</dt> ";
        result += "  <dd>" + bigText + "</dt> ";
        result += "</dl> ";
        
        var output = document.getElementById("output");
        output.innerHTML = result;
        
      } // end function

The function is a bit longer than the others in this chapter, but it follows exactly the same pattern: It extracts data from the fields, constructs a string for output, and writes that output to the innerHTML attribute of a div in the page.

The code has nothing new, but it still has a few features you should consider:

  • Create a variable for each form element. Use the document.getElementById mechanism.
  • Create a string variable containing the contents of each element. Don't forget: The getElementById trick returns an object. You need to extract the value property to see what's inside the object.
  • Make a big string variable to manage the output. When output gets long and messy like this one, concatenate a big variable and then just output it in one swoop.
  • HTML is your friend. This output is a bit complex, but innerHTML is HTML, so you can use any HTML styles you want to format your code. The return string is actually a complete definition list. Whatever is inside the textbox is (in this case) reproduced as HTML text, so if I want carriage returns or formatting, I have to add them with code.
  • Newline characters ( ) clean up the output. If I were writing an ordinary definition list in HTML, I'd put each line on a new line. I try to make my programs write code just like I do, so I add newline characters everywhere I'd add a carriage return if I were writing the HTML by hand.

Understanding generated source

When you run the program in the preceding section, your JavaScript code actually changes the page it lives on. The code that doesn't come from your server (but is created by your program) is sometimes called generated source. The generated code technique is powerful, but it can have a significant problem. Try this experiment to see what I mean:

  1. Reload the page.

    You want to view it without the form contents showing so that you can view the source. Everything will be as expected; the source code shows exactly what you wrote.

  2. Click the Click Me button.

    Your function runs, and the page changes. You clearly added HTML to the output div because you can see the output right on the screen.

  3. View the source again.

    You'll be amazed. The output div is empty, even though you can clearly see that it has changed.

  4. Check generated code.

    Using the HTML validator extension or the W3 validator (described in Book I, Chapter 2) doesn't check for errors in your generated code. You have to check it yourself, but it's hard to see the code!

Figure 2-11 illustrates this problem.

9781118289389-fg1911.tif

Figure 2-11: The ordinary view source command isn't showing the contents of the div!

Here's what's going on: The view source command (on most browsers) doesn't actually view the source of the page as it currently stands. It goes back to the server and retrieves the page, but displays it as source rather than rendered output. As a result, the view source command isn't useful for telling you how the page has changed dynamically. Likewise, the page validators check the page as it occurs on the server without taking into account things that may have happened dynamically.

When you build regular web pages, this approach isn't a problem because regular web pages don't change. Dynamically generated pages can change on the fly, and the view source tool doesn't expect that. If you made a mistake in the dynamically-generated HTML, you can't simply view the source to see what you did wrong. Fortunately, Chrome gives you a pretty easy solution.

The Chrome developer tools (available with the F12 or Cmd+shift+I on Mac — have I mentioned how awesome this tool is?) can show you exactly what the browser is currently displaying.

Here's how you can use it:

  1. Run the page and put it through its paces.

    Click the buttons and do what the page does to modify itself.

  2. Inspect the page.

    Right-click anywhere on the page and choose inspect element from the popup menu. The developer tools will pop up and you'll be in a special outline view.

  3. Select the code to see the corresponding page element.

    Select a piece of code in the elements view and the corresponding part of the page is highlighted.

  4. Select an element to see its code.

    When you're in inspect mode, you can click on any visible element of the page and the corresponding code will be highlighted.

  5. The displayed code is what's currently being displayed.

    Unlike the view source results, the element inspector shows what's currently on the screen rather than what's on the server.

  6. You can even change the content here.

    You can double-click on content in the Elements tab and change it, and the page changes alongside it. (Hmm … does this mean you could change the headlines of an online newspaper and make it look totally real? That seems mischievous. I hope nobody ever does that.) Don't worry. None of the changes are permanent.

  7. The “trail of breadcrumbs” shows where you are.

    You can see exactly what tags are active by looking at the bottom of the developer screen.

  8. You can also see which CSS files are currently active.

    As described in Book II, you can also modify the CSS on this screen to see how the page will look if the CSS is changed. This is an ideal way to experiment with the page.

These tools keep you sane when you're trying to figure out why your generated code isn't acting right. (I wish I'd had them years ago….)

Figure 2-12 shows the Chrome developer tools with the dynamically generated contents showing.

9781118289389-fg1912.tif

Figure 2-12: Chrome shows the current status of dynamically-modified pages

What if you're not in Chrome?

If you're using another browser, the Firebug extension does most of the same things as the Chrome developer tools. Firebug performs best on Firefox, but there is a light version which works on any browser.

If none of these tools is available, there's another cool trick you can do. Type the following into the address bar:

  javascript:alert(document.body.innerHTML)

This very sneaky trick uses JavaScript to generate the source code of the page as it currently stands:

  1. Begin with the javascript: identifier.

    When you begin an address with javascript, the browser immediately renders the rest of the address as a JavaScript instruction rather than an address. Cool, huh? (Try javascript: alert(2+5) to turn your browser into a calculator. Whoa.)

  2. Use alert to produce quick output.

    You want to look at the source of whatever page is currently loaded, so use the alert mechanism to print the code in a pop-up and leave the original page in place.

  3. Print the current page's source code.

    The document.body.innerHTML trick returns all the HTML code inside the body tag. This doesn't show your header or doctype information, but it does display the page as it currently sits in memory, even if it has been changed dynamically through code. That's usually enough to figure out what's going wrong in a pinch.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset