Lab 8

This lab will (theoretically) be your first experience with actual Javascript code. In this lab, you will create an interactive website to generate "MAD LIB"-like stories. The story will be hidden completely from the user until they click the "Generate My Story!" button. At that time, the page will reveal the story. For now, our page will only support one story though we could easily expand it to include more.


If your code isn't working, first read through the "Stuck?" section at the bottom of this page. Then, perhaps ask a neighbor or me for assistance. For some tasks, I've put the answer in a sort of pop up hint that you can optionally access (don't view it unless you really have no idea how to proceed). For example, here is one now 1).


Note: I'll be using a pretty generic story "Once upon a time a [noun] [past tense verb] to [place]." Feel free to use your own, more creative story or to change your page to use different parts of speech (future tense verb, proper noun, etc.).

Setting Up

For now, go and take a look at the Lab 8 Sample Page. It's a basic page and is seemingly finished, but of course lacks the JavaScript necessary to achieve its purpose.


Save that page (right click the link, save as, or just open up the page and copy and paste the HTML into a new web page) and be sure to name it [yourinitials]_lab8.html (e.g., rym4_lab8.html). Open it up in your favorite HTML editor (Notepad, Dreamweaver, etc.) and your choice of web browser. Take a look at the HTML now and just see how everything is setup. In particular, you should notice that:

  1. The form elements (text boxes, and submit button) are placed in a table so that they're neatly aligned
    1. One column is used as the labels for what type of word should be entered
    2. The second column is used to hold the text box or button
  2. Each form element has its own ID ("word1", "word2", etc.)
  3. The generated story section paragraph (which says "(no story yet, please use the above form)") also has an ID of "story"


We'll use those IDs to access each element and read from (in the case of the text boxes) or write to (in the case of the finished story paragraph).

Responding to the Button Press

The basic pattern that the user will follow is:

  1. Type in each type of word
  2. Click the button (generating the story)
  3. Read the story


So, we'll add some code to respond to the button click and then we'll generate the story. If you take a look at the Simple JavaScript Demo Page that you've seen before, you'll see how we used the "onclick" attribute in order to respond to the button press. Since our respond to the button press may require lots of code (to read all the text boxes, make the story, and write the story out) we don't want to perform all of our actions inside that little onclick=" … " area. If you look on the example page, you'll see its already pretty messy with just 2 alert boxes. Imagine how messy it would be trying to do all that we're doing. Instead, we'll just have the button call a function (which we will soon write) and have that function do all the work.


To the HTML <input type="button" value="Generate My Story!" /> add a onclick event handler to call our function (let's pretend our function will be named makeStory). Remember, our function won't need to accept any parameters.2)


Of course, we still don't have a makeStory function yet so let's do that. In the <head> … </head> tags, we'll add the following HTML just like from the demo page:

  <script type="text/javascript">
  </script>

To make a function in JavaScript we simply type the word 'function' then the name of the function that we want, then we put a '(' and put a comma separated list of any function parameters we need, then we put a ')'. Finally, we hit enter and put a '{' then a '}'. So, a generic function might look something like this:

  function myFunction(param1, param2, param3)
  {
    // We'd put our function's code here
  }

After each line of code in the function, we end it with a ';' just like how we've been doing with CSS. Of course, we don't have any lines of code yet, so we don't have any ';'s.


We already said that our makeStory function won't need any parameters. So, inside the <script …> … </script> area let's now actually type and put our new makeStory function.

  function makeStory()
  {
    // We'd put our function's code here
  }

Then, just to be sure that it's working, inside the { and } (which define the code of our function) let's put a:

  alert("It worked!");


Save the page and load it up. When you click the button, our makeStory function should be called and we should see the pop up message. Don't go beyond this point if it isn't working right.

Reading the Text Boxes

Now we know that when our makeStory function is executed, the user has typed in all of the words. We also know how to add strings together (e.g., var bigString = "Hello" + " " + "World!"). So, if we could find out what the words were we could just generate a very long string and then print that out. For example, we WOULD LIKE to be able to do something like this (but currently, this will NOT work):

  function makeStory()
  {
    var word1 = getValue("word1"), word2 = getValue("word2"), word3 = getValue("word3");
    var story = "Once upon a time, " + word1 + " " + word2 + " to " + word3 + ".";
  }

However, there is no built in getValue function. But, we can make one! So, add another function into our script tags (be sure that you add it above or below the entirety of our makeStory function):

  function getValue(desiredName)
  {
    
  }

We are always able to access the "document" object, which contains everything about the current page that we're on. It also has lots of handy functions which we can use to manipulate the page. Feel free to look into it in more detail later, but for now we can use the document object's getElementById(…) function. Specifically, if we pass it a string which is the ID of an element, it will return that element. We can then access the various attributes of that element (value for <input>, src and alt for <img>, href for <a> etc.). Inside our getValue(desiredName) function put this code:

  return document.getElementById(desiredName).value;

So now, our completed getValue function looks like:

  function getValue(desiredName)
  {
    return document.getElementById(desiredName).value;
  }

That function will, given a desiredName, find that element on the page, and then return its value (its value of course, is a string). This is great for finding out the value of a <input> text box element, since the value attribute is what the user has typed into it.

Making the Story

Using our completed getValue function, we can now make the story. Write the necessary code inside makeStory to get the contents of each text box (by using the getValue function) and then store it into a variable. Then, make a finalStory variable and create it by doing lots of string addition 3). Finally, make a pop up message containing the story 4)


Don't go beyond this point if you can't get your custom story to pop up on the screen containing the words the user typed in.

Printing the Story to the Page

The pop up message is nice, but it would be better if the web page itself instantly changed to hold the story. That way, we wouldn't have any annoying pop ups and the user could more easily show off their story or copy/paste their story.


Get rid of the alert(finalStory) line (which should be the last line in your function before the ending '}') that we have, since we no longer want to pop up a message. Instead, replace it with:

 document.getElementById('story').innerHTML = finalStory;

It's important to look carefully at this line. It's similar to the code in our getValue function, but its hard coded to get a certain element whose ID is story (this is the paragraph element underneath the "Generated Story:" heading). It then sets the innerHTML property of that element to be whatever it is that was in our finalStory variable. Ask yourself, "Why can't we just do document.getElementById('story').value = finalStory;"?


If you run it now, when the user clicks the button the web page itself should change to reveal the story! If you're not impressed, you should be. If it doesn't work, don't go beyond this point.

Submission

Time permitting:

  1. Add new text boxes for additional words in the story.
  2. Change the story so it doesn't follow the standard "Once upon a time" format
  3. Add a reset button to clear the generated story to say "(no story yet, please use the above form)" and to reset the text box values
  4. Advanced: Add support for more than 1 story. For example, maybe add a text box where they type in which story they want ("1", "2", etc.) then have the makeStory function respond appropriately by using an if statement. You could also randomly pick which story to generate by using Math.rand() which returns a number [0, 1)).

Call me over if there's time so that I can see what you've done.

Whatever happens, submit your web page to the class submission FTP directory.

Stuck?

If your code isn't working properly, be sure to consider the following:

  1. Javascript is case sensitive. Be sure to use spell things correctly
  2. Quotes are important! var msg = "hi"; alert(msg); is VERY different from var msg = "hi"; alert("msg");
  3. Each line of code should end in a semicolon (e.g., ';')
    • The exception is to special lines which declare functions (e.g., function myFunction()) and lines which have curly braces (e.g., { and }).
1) SOLUTION AND SUCH WOULD BE HERE
2) <input type="button" value="Generate My Story!" onclick="makeStory()" />
3) var finalStory = "Once upon a time, " + word1 + " " + word2 + " to " + word3 + ".";
4) alert(finalStory);