Lab 7

Last Update: 2019-11-11

Author(s): Mark Olson


Due: First Lab Section meeting of the week of November 18th

Mad Libs in Javascript

Overview

In this lab exercise, you will create a simple "Mad Libs"-style game using Javascript. If you are not familiar with Mad Libs, the idea is that you ask a player to give you a collection of words (nouns, adjectives, verbs, adverbs) without knowledge of how they will be used. They are then plugged into a pre-determined narrative, often with hilarious or nonsensical results.

Example of a Mad Lib

The game play should proceed as follows:

  1. First, the user should be presented with an HTML form asking for a certain number of generic nouns, adjectives, verbs, adverbs as well as some specific elements: part of the body, favorite song title, article of clothing, type of food, etc. Be creative.

  2. Second, the user clicks the "Submit" button, which hides the form and displays the Mad Lib.

  3. Finally, hilarity ensues. Or not.

Requirements for a ✓

  1. Create a new folder in your labs folder called lab07 and a new index.html file in that folder.

  2. Do what is necessary to bring the page's aesthetic into alignment with your midterm website (link to your midterm.css; add the navigation / footers as necessary, etc.).

  3. On paper or in a separate text document, write an innocuous short story, indicating in parentheses where the Mad Libs words will go. For example,

    On a (adjective) November day, I woke up to the (adjective) smell of (liquid) percolating in the (room of a house) downstairs. I wrapped my (body part) in a warm (article of clothing) and sat down to (verb) my Javascript homework. I typed (adverb) as thoughts of Thanksgiving (verb - past tense) in my head.

    Our process, in essence, is to create an HTML form to collect the nouns, verbs, adverbs, adjectives, both general and specific, which we will then use javascript to insert into our narrative. [You'll of course need to come up with an original story of your own.]

  4. Return to your HTML document. Inside the <body> element, add the following, which will lay the groundwork for an HTML form for collecting nouns, verbs, adverbs, adjectives, both general and specific:

    <form id="formData">
        <fieldset>
            <legend>Javascript Mad Libs</legend>
    
        </fieldset>
    </form>
    
  5. Beneath the <legend> element, create labelled input fields for each of the words that your form will collect to insert into the narrative. Your Mad Lib should collect at least eight (8) words. For example:

     <form id="formData">
        <fieldset>
            <legend>Javascript Mad Libs</legend>
            <label>Adjective: </label><input type="text" name="adjective1"><br>
            <label>Article of Clothing: </label><input type="text" name="clothing"><br>
            <label>Liquid: </label><input type="text" name="liquid"><br>
            <label>Part of the Body: </label><input type="text" name="bodypart"><br>
            <!-- etc etc etc -->
        </fieldset>
    </form>
    
  6. Finally, before the closing </fieldset> tag, add a button for submitting the Mad Libs form. In a future step, we will add an event listener to that button to process the form fields' contents:

            <!-- etc etc etc -->
            <button id="submit">Submit</button> 
        </fieldset>
    </form>
    
  7. Next, add a <div> element with an id of "content" below the closing </form> element.

            <!-- etc etc etc -->
            <button id="submit">Submit</button> 
        </fieldset>
    </form>
    <div id = "content"></div>
    
  8. Now it's time to turn your attention to the javascript that will render this dynamic. All of your javascript should be written before the closing </body> tag and enclosed within a <script> tag:

    <script type="text/javascript">
        // javascript goes here
    </script>
    
  9. Let's first create a function that will, once fully implemented, grab all of the form input values and insert them into your MadLib narrative.

    A function is declared with the keyword function, followed by an arbitrary (but hopefully semantically informative) function name, followed by a pair of parenthesis (which optionally contain the function's arguments as variables). The function itself follows those parenthesis, enclosed in curly brackets. In this case, we'll create a function called "goMadLib" in betweeen the opening and closing <script> tags:

    <script type="text/javascript">
        // javascript goes here
        function goMadLib() {
        // function javascript goes here
        }
    </script>
    
  10. Now let's populate the function with javascript that selects each form input and assign its contents to its own variable. You could do this by assigning each <input> an ID and then make use of the getElementById method. But we already have assigned each <input> element a "name" atttribute, so rather than create redundant IDs, we can instead grab the entire form by its ID and then make use of the form elements collection from the DOM. [But if you prefer to stick with the getElementByID() method, that's fine too! There are several valid ways to accomplish most things in javascript.]

    First, declare a variable to hold the form object. Recall that the form was assigned an ID of "formData" (using proper camelcase):

    function goMadLib() { 
        let formData = document.getElementById("formData");
    }
    

    Now that we have the form object, we can access each form element and its value by using the the .namedItem() method on the form elements collection:

    function goMadLib() { 
        let formData = document.body.getElementById("formData");
    
        let adj1 = formData.elements.namedItem("adjective1").value;
        let clothing = formData.elements.namedItem("clothing").value;
        // continue with your remaining inputs
    }
    

    You'll of course modify the above with your own form input names and make sure you assign all form inputs to their own respective values

    Note

    The .item() method works the same as the .namedItem() method

    let variable = formData.elements.item("input_name").value;
    
  11. Now that each form input's value is stored in its own variable, we can use those variables and some string operations to generate our MadLib text:

    function goMadLib() { 
        let formData = document.getElementById("formData");
    
        let adj1 = formData.elements.namedItem("adjective1").value;
        let clothing = formData.elements.namedItem("clothing").value;
        // continue with your remaining inputs (not all listed above)
    
        let newContent = "On a " + adj1 + " November day, ";
    
        newContent += "I woke up to the " + adj2 + " smell of " + liquid + " percolating in the " + room + " downstairs.";
    
        newContent += "I wrapped my " + bodypart + " in a warm " + clothing + " and sat down to ...";
    }
    
  12. As a final step in our goMadLib() function, we'll use the innerHTML() method to insert the MadLib into the "content" DIV:

        newContent += "I wrapped my " + bodypart + " in a warm " + clothing + " and sat down to ...";
    
        // this sets the innerHTML of our content DIV to the concatenated 
        // string contained in the variable newContent 
        document.getElementById("content").innerHTML = newContent;
    }
    
  13. Finally, you can add an event listener to the "submit" button to call the goMadLib() function on the click event. Importantly, this needs to be outside of the goMadLib() function. So add the following after the closing curly bracket of your function:

        document.getElementById("content").innerHTML = newContent;
    }
    let submitBtn = document.getElementById("submit");
    submitBtn.addEventListener("click", goMadLib);
    

    SUPER IMPORTANT

    By default, clicking button within a <form> element will force a page reload, as if you are submitting your form data to a remote database. We need to override that behavior for this exercise, as we don't want the page to reload. Add the following onsubmit attribute to the <form> element in your HTML:

    <form id="formData" onsubmit="event.preventDefault();">
    

If you encounter errors, use the Javascript Console in Chrome's Developer tools to troubleshoot.

Reach Goals

Some suggestions to extend your work in this lab:

  • Instead of storing each verb, adjective, noun in its own variable, store them in an array using the array push() method and then use array indexes to display them in the Mad Lib.

  • Create a "reset" button that clears out all data, clears the story, and returns the input form to its empty state.

  • Use Javascript for basic form validation, ensuring that no fields are left blank. Hint: this can be added to form inputs using the "onblur" event through the addEventListener() method.