Lesson Monday

So far, the only way we've been able to capture user input is by using confirm() and prompt(). Let's learn about forms so that we can build more interesting pages.

Have you ever played Mad Libs? You're prompted to fill out a list of nouns, verbs, adjectives, etc., and then copy them onto another piece of paper that contains a story, missing those crucial words that you are now providing. The idea is to pick bizarre words without knowing what the story is, and then when you fill them in, the results can be hilarious.

Let's make a page that mimics the Mad Libs format:

mad-libs.html
<!DOCTYPE html>
<html lang="en-US">
<head>
  <link href="css/bootstrap.css" rel="stylesheet" type="text/css">
  <link href="css/styles.css" rel="stylesheet" type="text/css">
  <script src="js/jquery-3.5.1.js"></script>
  <script src="js/scripts.js"></script>
  <title>A fantastical adventure</title>
</head>
<body>
  <div class="container">
    <h1>Fill in the blanks to write your story!</h1>
    <div>
      <form id="formOne">
        <div class="form-group">
          <label for="person1">A name</label>
          <input id="person1" class="form-control" type="text">
        </div>
        <div class="form-group">
          <label for="person2">Another name</label>
          <input id="person2" class="form-control" type="text">
        </div>
        <div class="form-group">
          <label for="animal">An animal</label>
          <input id="animal" class="form-control" type="text">
        </div>
        <div class="form-group">
          <label for="exclamation">An exclamation</label>
          <input id="exclamation" class="form-control" type="text">
        </div>
        <div class="form-group">
          <label for="verb">A past tense verb</label>
          <input id="verb" class="form-control" type="text">
        </div>
        <div class="form-group">
          <label for="noun">A noun</label>
          <input id="noun" class="form-control" type="text">
        </div>

        <button type="submit" class="btn">Show me the story!</button>
      </form>
    </div>

    <div id="story">
      <h1>A fantastical adventure</h1>
      <p>
        One day, <span class="person1"></span> and <span class="person2"></span> were walking through the woods, when suddenly a giant <span class="animal"></span> appeared. "<span class="exclamation"></span>", <span class="person1"></span> cried. The two of them <span class="verb"></span> as quickly possible, and when they were safe, <span class="person1"></span> and <span class="person2"></span> gave each other a giant <span class="noun"></span>.
      </p>
    </div>
  </div>
</body>
</html>

I've used some Bootstrap classes to make the form look nice. You can read more about them in the Bootstrap form documentation.

Let's make the story hidden to start:

styles.css
#story {
  display: none;
}

Our JavaScript needs to get the value from the form inputs, insert them into the <span>s where the information should go, and then un-hide the story itself. We know how to insert text into our pages, so let's get that working before we try to get the data from the form:

scripts.js
$(document).ready(function() {
  $("#formOne").submit(function() {
    $(".person1").append("blah blah");
    $(".person2").append("blah blah");
    $(".animal").append("blah blah");
    $(".exclamation").append("blah blah");
    $(".verb").append("blah blah");
    $(".noun").append("blah blah");

    $("#story").show();
  });
});

The submit() function attaches an event listener for when a form is submitted. It's different from the click() function because a form can be submitted by clicking the submit button, of course, but it can also be submitted by pressing Enter while a form field is selected.

But when we submit the form, the story briefly flashes and then disappears. This is because the submit() function has a default behavior. It's typical for a form submission to be sent to a server (which might hold a database) where the information on the form can be processed and stored. And that's exactly what the default behavior for submit() is - to try to submit the information to a server and then refresh the page with any information from the server.

However, we aren't submitting our form to a server. Instead, the default behavior is just refreshing the page. This also refreshes our application as well, erasing the information submitted in the form.

If you look in the URL bar, you can see that there's a ? at the end of the address now. This is your clue that the form has been submitted to nowhere and the page refreshed. We need to prevent the default action for the form:

scripts.js
$(document).ready(function() {
  $("#formOne").submit(function(event) {
    $(".person1").append("blah blah");
    $(".person2").append("blah blah");
    $(".animal").append("blah blah");
    $(".exclamation").append("blah blah");
    $(".verb").append("blah blah");
    $(".noun").append("blah blah");

    $("#story").show();

    event.preventDefault();
  });
});

Notice that we've added a parameter event to the callback function we passed to submit() method. (Developers often use e for short as well.) This event is from jQuery and is a built-in piece of functionality. We can then call event.preventDefault to prevent the submit() function's default behavior. There are other types of events that have defaults that we can prevent but submit() events are the most common.

At this point, there's no need to dig too deeply into what is happening. What's stored in event is actually pretty complex but you don't need to worry about it, especially this early in your coding journey. We just need to remember to pass event in as a parameter and then call event.preventDefault().

Now, we need to actually get the values from the form. If we open up the JavaScript console on the page and run:

  • $("input#person1").val();

We can see that this jQuery method returns the value from the input as a string. Since the append() method takes a string as an argument, we can update our code like this:

scripts.js
$(document).ready(function() {
  $("#formOne").submit(function(event) {
    const person1Input = $("input#person1").val();
    const person2Input = $("input#person2").val();
    const animalInput= $("input#animal").val();
    const exclamationInput = $("input#exclamation").val();
    const verbInput = $("input#verb").val();
    const nounInput = $("input#noun").val();

    $(".person1").append(person1Input);
    $(".person2").append(person2Input);
    $(".animal").append(animalInput);
    $(".exclamation").append(exclamationInput);
    $(".verb").append(verbInput);
    $(".noun").append(nounInput);

    $("#story").show();

    event.preventDefault();
  });
});

Now our page works. Hooray!

There's one last thing to fix, though. If you don't refresh the page and you change the value of one of the inputs, it just adds it after the first value, instead of replacing it. We need to replace the existing text rather than just appending to it:

scripts.js
$(document).ready(function() {
  $("#formOne").submit(function(event) {
    event.preventDefault();
    const person1Input = $("input#person1").val();
    const person2Input = $("input#person2").val();
    const animalInput= $("input#animal").val();
    const exclamationInput = $("input#exclamation").val();
    const verbInput = $("input#verb").val();
    const nounInput = $("input#noun").val();

    $(".person1").text(person1Input);
    $(".person2").text(person2Input);
    $(".animal").text(animalInput);
    $(".exclamation").text(exclamationInput);
    $(".verb").text(verbInput);
    $(".noun").text(nounInput);

    $("#story").show();
  });
});

Example


Capture input when a form is submitted:

HTML Form:

<form id="some-form">
  <label for="some-input">Your input:</label>
  <input id="some-input" type="text">

  <button type="submit" class="btn">Submit!</button>
</form>

JavaScript to capture form information when form is submitted:

$("form#some-form").submit(function(event) {
  const someInput = $("input#some-input").val();

  event.preventDefault();
});

Replace text in an HTML element using jQuery:

$(".some-class").text("New text");

Tips


  • If you submit your form and then there's a ? at the end of the URL in your address bar, you forgot to put event.preventDefault();, or you attached your event listener to the wrong form.

Lesson 1 of 10
Last updated April 7, 2021