jQuery Demo: Mad Libs Word Game

Posted April 3, 2007 at 7:36 PM by Ben Nadel

Tags: Javascript / DHTML

I am trying to come up with demos that will force me to learn the ins and outs of jQuery. For this demo, I have created a Mad Libs style game. If you did not use Mad Libs as a kid (what is wrong with you... j/k) it is a fill-in-the-blanks word game where not knowing the word context can lead to some whacky outcomes (and giggling fits). The whole idea behind jQuery: keep the output simple.

Here is the jQuery Mad Libs Demo.

Here is the HTML markup:

  • <div id="madlibs">
  •  
  • <p>
  • <span rel="madlib" type="noun" desc="A girl's name.">Sally</span> wend over to
  • <span rel="madlib" type="noun" desc="A boy's name.">Luke</span> and grabbed his
  • <span rel="madlib" type="noun" desc="A body part.">hand</span>. "Come on", she said, we have to
  • <span rel="madlib" type="verb" desc="A way to get from here to there.">run</span> to the
  • <span rel="madlib" type="noun" desc="A place.">lunch room</span> where we can eat lots of
  • <span rel="madlib" type="noun" desc="A food.">sandwhiches</span>! I
  • <span rel="madlib" type="adverb" desc="How you feel about something.">hate</span> those, he said, I would much rather
  • <span rel="madlib" type="verb" desc="Something you can do with your mouth.">eat</span> dog poop!
  • </p>
  •  
  • </div>

As you can see, I have created SPAN tags that relate to the Mad Lib game (rel="madlib"). Once the document loads, I use jQuery to dynamically loop through the document looking for these spans. Based on these spans, I create a FORM element and then create an input corresponding to each madlib span node.

Why do it this way? Because we don't care about the form - we care about the text. Doing it this way allows us to concentrate on getting some good Mad Libs text down on paper and not having to give the form a second thought.

Here is the jQuery code:

  • // This will fire when the document is ready.
  • $(
  • function(){
  •  
  • // Get a pointer to the mad libs container.
  • jMadLibsContainer = $( "#madlibs" );
  •  
  • // Get all of the madlib elements (defined by Span
  • // objects with the rel=madlib).
  • jMadLibs = $( "span[@rel='madlib']" );
  •  
  • // Create a form element and wire up the onsubmit
  • // to fire the show mad libs and then return false
  • // so that the form doesn't submit anywhere.
  • jMadLibsForm = $( "<form>" ).submit(
  • function(){
  • ShowMadLibs();
  • return( false );
  • }
  • );
  •  
  • // For each of the mad lib elements, we need to
  • // create a corresponding form element in our new form.
  • // Loop over each element and create the form fields.
  • jMadLibs.each(
  •  
  • // For each of the madlib nodes, we want to update
  • // the contents of the mad libs form.
  • function( intIndex ){
  • var jMadLibsNode = $( this );
  •  
  • jMadLibsForm.append(
  • "<p>" +
  • jMadLibsNode.attr( "type" ).toUpperCase() +
  • " : " +
  • jMadLibsNode.attr( "desc" ) +
  • "<br />" +
  • "<input type=\"text\" size=\"60\" />" +
  • "</p>"
  • );
  •  
  • }
  • );
  •  
  • // Add the submit button to the form.
  • jMadLibsForm.append(
  • "<p>" +
  • "<input type=\"submit\" value=\"Show Mad Libs!\" />" +
  • "</p>"
  • );
  •  
  •  
  • // Hide the mad lib container.
  • jMadLibsContainer.hide();
  •  
  • // Add the mad libs form after the mad libs container.
  • jMadLibsContainer.after(
  • jMadLibsForm
  • );
  • }
  • );
  •  
  •  
  • // This will be used to process the mad lib form once the
  • // user had entered all of the values.
  • function ShowMadLibs(){
  • var strErrors = "";
  •  
  • // Loop over the form elements to make sure that all
  • // the values have been entered.
  • jMadLibsForm.find( "input" ).each(
  • function( intIndex ){
  • var jPara = $( this.parentNode );
  • var jInput = jPara.find( "input" );
  •  
  • // Check to see if the form field is empty.
  • // If the input is empty, echo the field
  • // label and turn the field red.
  • if (jInput.val() == ""){
  •  
  • // Add the error text.
  • strErrors += (jPara.text() + "\n");
  •  
  • // Highlight the field.
  • jInput.css( "background-color", "#FFCCCC" );
  •  
  • } else {
  •  
  • // This field is fine, make sure that it
  • // is not hightlighted.
  • // Highlight the field.
  • jInput.css( "background-color", "#FFFFFF" );
  •  
  • }
  • }
  • );
  •  
  •  
  • // Check to see if we have any errors.
  • if (strErrors.length > 0){
  •  
  • // There were form validation errors. Alert them.
  • alert( strErrors );
  •  
  • } else {
  •  
  • // There were no form validation errors. Loop over
  • // each of the mad lib nodes and set the text.
  • jMadLibs.each(
  • function( intIndex ){
  • var jMadLibsNode = $( this );
  •  
  • // Set the text of the mad libs node to the
  • // form field valud of the input at the
  • // same index.
  • jMadLibsNode.text(
  • jMadLibsForm.find(
  • "p:nth-child(" + (intIndex + 1) + ") input"
  • ).val()
  • );
  • }
  • );
  •  
  • // Hide the form.
  • jMadLibsForm.hide();
  •  
  • // Show the mad libs.
  • jMadLibsContainer.show();
  •  
  • }
  • }
  •  
  •  
  •  
  • // This is a collection that will store references to all of
  • // our Mad Lib DOM elements.
  • var jMadLibs = null;
  •  
  • // This is a pointer to the mad libs container. We just need
  • // something in which we can group all the editable content.
  • var jMadLibsContainer = null;
  •  
  • // This is a pointer to the mad libs form (yet to be created).
  • var jMadLibsForm = null;

It's not the shortest piece of jQuery in the world, but if you think about how dynamic this is and easy it makes updating the text, suddenly it doesn't seem like over kill by any means. This jQuery stuff is so crazy-cool. If you have not looked into it yet, do so now!




Reader Comments

There are no comments posted for this web log entry.

Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
Jun 19, 2013 at 2:01 PM
Experimenting With The Amazon Simple Storage Service (S3) API Using ColdFusion
I have coincidentally been beating my head against the S3 API for the last week or so. One big "gotcha" I had to work around was file names and paths containing spaces. Remember to URL Enco ... read »
Jun 19, 2013 at 1:27 PM
Using Slice(), Substring(), And Substr() In Javascript
very good article. By the way IE supports negative values in substr or slice in verson 10. ... read »
Jun 19, 2013 at 11:33 AM
Filter vs. ngHide With ngRepeat In AngularJS
In your assessment, is it correct to say that given a list of say 500 items its more performant to use the `ngHide` method over the `filter` method? ... read »
Jun 19, 2013 at 10:18 AM
ColdFusion Path Usage And Manipulation Overview
Anyone happen to know if the file created by getTempFile will be automatically removed at any point? Nothing mentioned in the docs, and restarting CF doesn't remove them, so it seems it needs manu ... read »
Jun 19, 2013 at 9:41 AM
Working With Inherited Collections In AngularJS
I actually just ran into this same situation with a demo I was putting together. Your implementation of multi-lvl $scope's > Mine :) ... read »
Jun 19, 2013 at 8:17 AM
My Experience With AngularJS - The Super-heroic JavaScript MVW Framework
@Prateek, to match a word or text you should use .toContain('word') that's a jasmine reference. website is : http://pivotal.github.io/jasmine/ ... read »
Jun 19, 2013 at 8:10 AM
My Experience With AngularJS - The Super-heroic JavaScript MVW Framework
Hi Guys, Actually i am doing e2e test of angular js of my project but i am not getting one thing that is how to press enter key through the test when my form is filled as i am not using a button but ... read »
Jun 18, 2013 at 9:20 PM
Mapping AngularJS Routes Onto URL Parameters And Client-Side Events
I couldn't find examples of passing multiple arguments using the when() routing statement so figured out through trial and error that you can pass multiple arguments using the following format: .whe ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools