Forms are great for collecting information on users, like job applications or insightful surveys. However, we can also stretch our creative muscles and have a little fun with forms. For this project, we’ll use our knowledge of the HTML <form> and grab user input to put a spin on a classic story!
The logic for parsing and inserting of user inputs is already taken care of in main.js using JavaScript . We’ve also added some styling to the page in style.css. You can find these files by click on the folder icon located at the top of the code editor and selecting the files you’re interested in.
What you have to do is now make a <form> capable of collecting the correct information so that the newly crafted story makes sense!
We’ll be collecting information from our users using a <form> so, first, we have to add a <form> under the <hr> element inside the <body> of index.html.
Assign the <form> an action of "story.html" and a method of "GET".
We’ll be sending information from our form to story.html using a GET request. https://www.w3schools.com/tags/att_form_action.asp HTML input formmethod Attribute (w3schools.com)
In the <form>, create a submit button by adding an <input> with a type of "submit". Assign the value a value of "Form My Story!". Save your code to see the button rendered.
This might seem counterintuitive, but by creating this submit button and submitting the form as you add more code, you can see how the final result of the story evolves and debug in smaller chunks. Check the hint for more debugging tips! https://www.w3schools.com/tags/tag_input.asp
Now we can populate our <form> with <input> elements that allow users to type in their responses. We’ll also want to have associated <label>s with these <input> elements so users know what they’re filling in.
Add a <label> element and assign the for attribute a value of "animal-1". Have the <label> render the text Animal: on the webpage.
Write your code so that the submit button always shows up at the bottom of the <form>. As you add more code, the submit button should be kept at the bottom. https://www.w3schools.com/tags/tag_label.asp
Now we can create an <input> to associate our <label> element with.
Set the id of the <input> to "animal-1" and the type to "text". Assign the name to "animal-1". Remember, the name attribute is needed for information from this <input> to be sent with the form during submission.
Speaking of submission, since we want our users to put in some value, add the required attribute to the <input>. https://www.w3schools.com/tags/tag_input.asp
We’re going to be adding more <label>s and <input>s so we should add some spacing.
Below the <input> element, add a line break using <br>. https://www.w3schools.com/tags/tag_br.asp
With the first input field and working submit button, type some text into the field and submit it! Remember, in order for you to see the new code rendered on the browser, you’re going to need to save your code.
Our story has quite a few blanks, so we’re going to need a lot more <label>s and <input>s.
Add another <label> with a for attribute of "animal-2" that renders Another Animal: to the webpage.
Underneath the <label>, create a new <input> with the attributes:
id and name set to "animal-2".
type to "text".
required https://www.w3schools.com/tags/att_input_required.asp
Add another <br> for a line break.
There’s another animal in our story, so let’s add another <label> with a for attribute of "animal-3" that renders One More Animal: to the webpage.
Then, add a new <input> with the attributes:
id and name set to "animal-3".
type to "text".
required
Remember to add another <br> for a line break.
Let’s have our users provide an adjective.
Add another <label> with a for attribute of "adj-1" that renders the text Adjective (ends in -ed): to the webpage.
Then, add a new <input> with the attributes:
id and name set to "adj-1".
type to "text".
required
Add another line break.
Let’s get a verb.
Create a <label> with has a for attribute set to "verb-1" that renders the text Verb (ends in -ing):.
Follow the <label> with an <input> with the attributes:
id and name set to "verb-1".
type to "text".
required
Also, add a line break.
Great, we have some <input>s set up that accept text, but we can use some <input> with different types in our <form>.
Let’s add a field that will accept a number. First add <label> with a for attribute of "num-1"that renders the text Number: to the webpage.
After the <label> element, add an <input> that has:
id and name set to "num-1".
a type attribute of "number". https://www.w3schools.com/tags/att_input_type_number.asp
a required attribute.
Also, add a line break.
One of our blanks requires a “yes” or “no” answer— sounds like we can use some radio buttons for that.
Before we can add the radio buttons, add a <span> element that has the text Yes or No:.
For radio buttons, we want to add the <input> before the <label> to render the radio button on the left of the text.
Add an <input> element with the following attributes:
an id set to "yes".
a type with a value of "radio". https://www.w3schools.com/jsref/dom_obj_radio.asp
a name of "answer".
a value of "yes".
a required attribute.
Under the <input>, add a <label> with a for attribute assigned a value of "yes" that renders the text Yes on the webpage.
We should now add a radio button that represents the “no” choice.
Add another <input> element that has the following attributes:
an id set to "no".
a type with a value of "radio". https://www.w3schools.com/jsref/dom_obj_radio.asp
a name of "answer".
a value of "no".
Under the just added <input>, add another <label> with a for attribute assigned a value of "no" that renders the text No on the webpage.
This time, add a line break!
The story that we’re creating this <form> for involves some sort of speed, so let’s give our users a dropdown list of speed options.
Create a <label> and set the for attribute to "speed". The <label> should render the text: Relative speed (ends in -er):
Then add a <select> element with an id and name of "speed". Add the required attribute to make this field mandatory.
Insert a <br> after the closing <select> tag. The <select> element will be empty for now.
Inside the <select> add a few <option>s for users to choose from.
One example of an <option> you could include is:
<option value="faster">Faster</option>
Add as many or as few as you’d like!
Remember to assign a value and include text between the opening and closing <option> tags.
One of our story’s blank requires a quote. We could provide our users with a few options but also give them the choice of adding their own custom quote. To do this, we can use the <datalist> element.
To set up the <datalist> we need an accompanying <label> and <input>.
Under the last <br>, add a <label> with a for attribute of "quote". Have the <label> render the text Motivational Quote:.
After the <label>, add an <input> with the follow attributes:
an id and name assigned a value of "quote".
the type set to "text".
a required attribute.
a list attribute of "quote-choices".
Awesome, we should add the <datalist> now under the <input> element. Assign the <datalist> an id of "quote-choices".
Add a <br> after the closing <datalist> tag.
Let’s add a few <option>s with values within the <datalist> element. For example:
<option value="winner gets ice cream!"></option>
Every good story has a key takeaway, so let’s finish off this <form> by having our users provide this message!
Add a <label> that has a for attribute of "message". Have the <label> render Meaningful Message: on the web page.
Under the <label> add a <textarea> that has an id and name of "message". Make the <textarea> a required field. The <textarea> should have 8 rows and 40 columns. (Check the hint for a syntax reminder).
Then add a line break after the <textarea> element. https://www.w3schools.com/tags/tag_textarea.asp
Add pre-selected values for each input field.
Add placeholder text that contains examples for users.
Add some extra validations like min, minlength, or pattern to the elements that accept user input.
index.html
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css">
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
<title>Form a Story</title>
</head>
<body>
<section id="top">
<img src="https://content.codecademy.com/courses/learn-html-forms/formAStoryLogo.svg" alt="Form A Story Logo">
</section>
<section id="main">
<h1>Complete the Form -<br> Complete the Story!</h1>
<hr>
<!--Add your form below:-->
</section>
</body>
</html>
style.css
body {
background-color: rgb(255, 199, 64);
font-family: "Open Sans", Arial;
}
form {
line-height: 27px;
}
h2 {
font-size: 20px;
}
input[type="text"], input[type="number"] {
min-height: 15px;
border-radius: 5px;
border:1px solid #cccccc;
}
input[type="radio"] {
margin-left: 12px;
}
#main {
background-color: rgba(255,255,255,0.8);
text-align: center;
height: 80vh;
border-radius: 15px;
margin: 2% 10%;
overflow: auto;
}
#story {
padding: 0 3%;
}
#top {
background-color: rgb(255, 255, 255);
margin: 2% 10%;
border-radius: 15px;
}
#top img {
display: block;
width: 35%;
margin: 0 auto;
}
.italics {
font-style: italic;
}
.word {
font-weight: bold;
text-decoration: underline;
}
main.js
// Grab values from the submitted form in the URL
const words = new URLSearchParams(window.location.search);
// Cleans up and capitalizes the names of the animals
function cleanAndCap (str){
if(!str) return null
let temp = str.trim()
return temp[0].toUpperCase() + temp.substring(1)
}
// Assigning the variables with values used in the story
const firstAnimal= cleanAndCap(words.get('animal-1'));
const secondAnimal = cleanAndCap(words.get('animal-2'));
const answer = cleanAndCap(words.get('answer'));
const conjunction = answer === 'Yes' ? 'and' : 'but';
const speed = words.get('speed');
const adj1 = words.get('adj-1');
const thirdAnimal = cleanAndCap(words.get('animal-3'));
const quote = words.get('quote');
const verb1 = words.get('verb-1');
const num1 = words.get('num-1');
const message = words.get('message');
// The string containing HTML and text which will populate the story.html page
const story = `<p>A <span class="word" title="id: animal-1">${firstAnimal}</span> was making fun of the <span class="word" title="id: animal-2">${secondAnimal}</span> one day for being so slow.</p>
<p>"Do you ever get anywhere?" he asked with a mocking laugh.</p>
<p>"<span class="word" title="id: answer">${answer}</span>," replied the <span class="word" title="id: animal-2">${secondAnimal}</span>, "${conjunction} I get there <span class="word" title="id: speed">${speed}</span> than you think. I'll run you a race and prove it."</p>
<p>The <span class="word" title="id: animal-1">${firstAnimal}</span> was much <span class="word" title="id: adj-1">${adj1}</span> at the idea of running a race with the <span class="word" title="id: animal-2">${secondAnimal}</span>, but for the fun of the thing he agreed. So the <span class="word" title="id: animal-3">${thirdAnimal}</span>, who had consented to act as judge, marked the distance yelled, "<span class="word" title="id: quote">${quote}</span>".</p>
<p>The <span class="word" title="id: animal-1">${firstAnimal}</span> was soon far out of sight, and to make the <span class="word" title="id: animal-2">${secondAnimal}</span> feel very deeply how ridiculous it was for him to try a race with a <span class="word" title="id: animal-1">${firstAnimal}</span>, he went off the course to practice <span class="word" title="id: verb-1">${verb1}</span> for <span class="word" title="id: num-1">${num1}</span> hours until the <span class="word" title="id: animal-2">${secondAnimal}</span> should catch up.</p>
<p>The <span class="word" title="id: animal-2">${secondAnimal}</span> meanwhile kept going slowly but steadily, and, after a time, passed the place where the <span class="word" title="animal-1">${firstAnimal}</span> was <span class="word" title="id: verb-1">${verb1}</span>. The <span class="word" title="id: animal-1">${firstAnimal}</span> was so caught up in <span class="word" title="id: verb-1">${verb1}</span>; and when at last he did stop, the <span class="word" title="id: animal-2">${secondAnimal}</span> was near the goal. The <span class="word" title="id: animal-1">${firstAnimal}</span> now ran his swiftest, but he could not overtake the <span class="word" title="id: animal-2">${secondAnimal}</span> in time.</p>`;
// Grabbing the title element
const title = document.getElementById('title');
// Populating the title element with text
title.innerHTML = `The <span class="word" title="id: animal-1">${firstAnimal}</span> And The <span class="word" title="id: animal-2">${secondAnimal}</span>`;
// Grabbing the story element
const storyEl = document.getElementById('story');
// Populating the story element with the value of the story variable
storyEl.innerHTML = story;
// Grabbing the moral-message element
const moralMessage = document.getElementById('moral-message');
// Populating the moral-message element with text
moralMessage.innerHTML = `<span class="italics" title="id: message">"${message}"</span>`;
story.html
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Completed Story</title>
<script type="text/javascript" src="main.js" defer></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<section id="top">
<img src="https://content.codecademy.com/courses/learn-html-forms/formAStoryLogo.svg" alt="Form A Story Logo">
</section>
<section id="main">
<h1 id="title"></h1>
<article id="story"></article>
<h2 id="moral">Moral of the story:</h2>
<article id="moral-message"></article>
<hr>
<a href="index.html">Start Over!</a>
<span> || </span>
<a href="original.html">Original Story</a>
</section>
</body>
</html>
original.html
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Completed Story</title>
<script type="text/javascript" src="main.js" defer></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<section id="top">
<img src="https://content.codecademy.com/courses/learn-html-forms/formAStoryLogo.svg" alt="Form A Story Logo">
</section>
<section id="main">
<h1 id="orig-title">The Tortoise and the Hare</h1>
<article id="orig-story">
<p>A Hare was making fun of the Tortoise one day for being so slow.</p>
<p>"Do you ever get anywhere?" he asked with a mocking laugh.</p>
<p>"Yes," replied the Tortoise, "and I get there sooner than you think. I'll run you a race and prove it."</p>
<p>The Hare was much amused at the idea of running a race with the Tortoise, but for the fun of the thing he agreed. So the Fox, who had consented to act as judge, marked the distance and started the runners off.</p>
<p>The Hare was soon far out of sight, and to make the Tortoise feel very deeply how ridiculous it was for him to try a race with a Hare, he lay down beside the course to take a nap until the Tortoise should catch up.</p>
<p>The Tortoise meanwhile kept going slowly but steadily, and, after a time, passed the place where the Hare was sleeping. But the Hare slept on very peacefully; and when at last he did wake up, the Tortoise was near the goal. The Hare now ran his swiftest, but he could not overtake the Tortoise in time.</p>
</article>
<hr>
<a href="index.html">Start Over!</a>
</section>
</body>
</html>