Trivia
Problem to Solve
Write a webpage that lets users answer trivia questions.
Distribution Code
For this problem, you’ll extend the functionality of code provided to you by CS50’s staff.
Download the distribution code
Open VS Code.
Start by clicking inside your terminal window, then execute cd
by itself. You should find that its “prompt” resembles the below.
$
Click inside of that terminal window and then execute
wget https://cdn.cs50.net/2023/spring/psets/8/trivia.zip
followed by Enter in order to download a ZIP called trivia.zip
in your codespace. Take care not to overlook the space between wget
and the following URL, or any other character for that matter!
Now execute
unzip trivia.zip
to create a folder called trivia
. You no longer need the ZIP file, so you can execute
rm trivia.zip
and respond with “y” followed by Enter at the prompt to remove the ZIP file you downloaded.
Now type
cd trivia
followed by Enter to move yourself into (i.e., open) that directory. Your prompt should now resemble the below.
trivia/ $
If all was successful, you should execute
ls
and you should see an index.html
file and a styles.css
file.
If you run into any trouble, follow these same steps again and see if you can determine where you went wrong!
Implementation Details
Design a webpage using HTML, CSS, and JavaScript to let users answer trivia questions.
- In
index.html
, add beneath “Part 1” a multiple choice trivia question of your choosing with HTML.- You should use an
h3
heading for the text of your question. - You should have one
button
for each of the possible answer choices. There should be at least three answer choices, of which exactly one should be correct.
- You should use an
- Using JavaScript, add logic so that the buttons change colors when a user clicks on them.
- If a user clicks on a button with an incorrect answer, the button should turn red and text should appear beneath the question that says “Incorrect”.
- If a user clicks on a button with the correct answer, the button should turn green and text should appear beneath the question that says “Correct!”.
- In
index.html
, add beneath “Part 2” a text-based free response question of your choosing with HTML.- You should use an
h3
heading for the text of your question. - You should use an
input
field to let the user type a response. - You should use a
button
to let the user confirm their answer.
- You should use an
- Using JavaScript, add logic so that the text field changes color when a user confirms their answer.
- If the user types an incorrect answer and presses the confirmation button, the text field should turn red and text should appear beneath the question that says “Incorrect”.
- If the user types the correct answer and presses the confirmation button, the input field should turn green and text should appear beneath the question that says “Correct!”.
Optionally, you may also:
- Edit
styles.css
to change the CSS of your webpage! - Add additional trivia questions to your trivia quiz if you would like!
Hints
Run http-server
to render your webpage
Before adding questions to your Trivia site, it’s best to first take a look at how it renders! In your trivia
folder, run http-server
. Then, click on the link provided.
Inside the head
element, the page’s stylesheets and title are specified for you. You can see this site loads a font from fonts.googleapis.com and applies the CSS in styles.css
. Notice too that there’s a some space to write JavaScript in the script
element, but more on that later!
<head>
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@500&display=swap" rel="stylesheet">
<link href="styles.css" rel="stylesheet">
<title>Trivia!</title>
<script>
// TODO: Add code to check answers to questions
</script>
</head>
Look inside the body
element and you’ll see you have two places to write trivia questions:
<div class="section">
<h2>Part 1: Multiple Choice </h2>
<hr>
<!-- TODO: Add multiple choice question here -->
</div>
<div class="section">
<h2>Part 2: Free Response</h2>
<hr>
<!-- TODO: Add free response question here -->
</div>
Each of these sections is denoted by a div
with class section
(fitting!). A div
is an HTML element that can function as a divider between sections of your page. Though they aren’t rendered, they’re useful for applying styles to certain segments of a page. See the CSS associated with the section
class in styles.css
if you’re curious what CSS properties this div
applies to its children.
Use HTML's h3
, button
, and input
elements to add questions to your webpage
Consider the components you’ll need to make a question on your page. You’ll need the question text itself, followed by a way for the user to enter their answer, whether in the form of a button or an input box.
Consider writing your question’s text in a heading element. An h3
might work best, given that it’s one step smaller than an h2
—the heading size currently used for each section’s title.
<div class="section">
<h2>Part 1: Multiple Choice </h2>
<hr>
<h3>What is the approximate ratio of people to sheep in New Zealand?</h3>
</div>
<div class="section">
<h2>Part 2: Free Response</h2>
<hr>
<h3>In which country is it illegal to own only one guinea pig, as a lone guinea pig might get lonely?</h3>
</div>
Now, consider how to let a user input their answer. For a multiple choice question, you could add a sequence of button
s, as below.
<div class="section">
<h2>Part 1: Multiple Choice </h2>
<hr>
<h3>What is the approximate ratio of people to sheep in New Zealand?</h3>
<button>6 people per 1 sheep</button>
<button>3 people per 1 sheep</button>
<button>1 person per 1 sheep</button>
<button>1 person per 3 sheep</button>
<button>1 person per 6 sheep</button>
</div>
Or, for a free-response question, you could add an input
box with a button
to submit the answer.
<div class="section">
<h2>Part 2: Free Response</h2>
<hr>
<h3>In which country is it illegal to own only one guinea pig, as a lone guinea pig might get lonely?</h3>
<input type="text"></input>
<button>Check Answer</button>
</div>
Try refreshing your page to see these elements rendered. Be sure they look as you intend!
Use JavaScript's querySelector
, querySelectorAll
, and addEventListener
functions to add interactivity
Developers commonly use JavaScript to add interactivity to webpages. Often, they will select certain HTML elements from the page and apply an event listener to them. An event listener waits for some action to occur on a particular element and, when it does, runs the function specified by the developer.
Before you can use JavaScript to select elements from your page, you’ll first need to wait for the page to load. The process of waiting can itself be implemented as an event listener. In this case, you can add an event listener to the document
, which is the root element of your HTML. You can add an event listener to an object using a method called, well, addEventListener
! The event to listen for will be DOMContentLoaded
, which is the signal that all HTML elements have been loaded.
document.addEventListener('DOMContentLoaded', function() {
// Function to run when DOM content is loaded
});
Notice that the function to run is indeed blank for now. But consider what you might add!
Focus first, perhaps, on allowing the user to guess an answer to your multiple choice question. Write some pseudocode to remind you what to do:
document.addEventListener('DOMContentLoaded', function() {
/* When any correct answer is clicked, change button color to green and display "Correct!" */
/* When any incorrect answer is clicked, change button color to red and display "Incorrect" */
});
Consider how you could designate some buttons as “correct” and other buttons as “incorrect.” Applying a CSS class can be a good way to help you select all elements of a certain category.
<div class="section">
<h2>Part 1: Multiple Choice </h2>
<hr>
<h3>What is the approximate ratio of people to sheep in New Zealand?</h3>
<button class="incorrect">6 people per 1 sheep</button>
<button class="incorrect">3 people per 1 sheep</button>
<button class="incorrect">1 person per 1 sheep</button>
<button class="incorrect">1 person per 3 sheep</button>
<button class="correct">1 person per 6 sheep</button>
</div>
Now that you’ve applied a CSS selector (a class!) to each button, consider document.querySelectorAll
. document.querySelectorAll
is a function that returns a list of all elements on the document retrieved by the selector given as input.
document.addEventListener('DOMContentLoaded', function() {
/* When any correct answer is clicked, change button color to green and display "Correct!" */
// Select correct buttons
let corrects = document.querySelectorAll('.correct');
/* When any incorrect answer is clicked, change button color to red and display "Incorrect" */
});
Now, you can indeed iterate over a list in JavaScript, much as you would in C or Python. Moreover, you can apply an event listener to each item, a button, in that list—one that will itself run a function to update the style of the button.
document.addEventListener('DOMContentLoaded', function() {
/* When any correct answer is clicked, change button color to green and display "Correct!" */
// Select correct buttons
let corrects = document.querySelectorAll('.correct');
// Add event listeners to correct buttons
for (let i = 0; i < corrects.length; i++) {
corrects[i].addEventListener('click', function() {
// Set background color to green
corrects[i].style.backgroundColor = 'Green';
});
}
/* When any incorrect answer is clicked, change button color to red and display "Incorrect" */
});
Of course, you need to not only update the style of the button, but also display some textual feedback. Consider creating an empty p
tag where you could eventually display some text.
<div class="section">
<h2>Part 1: Multiple Choice </h2>
<hr>
<h3>What is the approximate ratio of people to sheep in New Zealand?</h3>
<button class="incorrect">6 people per 1 sheep</button>
<button class="incorrect">3 people per 1 sheep</button>
<button class="incorrect">1 person per 1 sheep</button>
<button class="incorrect">1 person per 3 sheep</button>
<button class="correct">1 person per 6 sheep</button>
<p id="feedback1"></p>
</div>
You might recall from lecture that the innerHTML
property can update the HTML between an element’s tags. You could, then, select this particular p
element and, from there, update that element’s innerHTML
. To select this element, you need only use querySelector
—a version of querySelectorAll
that returns only the first element on the page that matches the given selector.
document.addEventListener('DOMContentLoaded', function() {
/* When any correct answer is clicked, change button color to green and display "Correct!" */
// Select correct buttons
let corrects = document.querySelectorAll('.correct');
// Add event listeners to correct buttons
for (let i = 0; i < corrects.length; i++) {
corrects[i].addEventListener('click', function() {
// Set background color to green
corrects[i].style.backgroundColor = 'Green';
// Add "Correct!" feedback
document.querySelector('#feedback1').innerHTML = 'Correct!';
});
}
/* When any incorrect answer is clicked, change button color to red and display "Incorrect" */
});
And that’s it! Any buttons with the class correct
should turn green when clicked. Some feedback should also be displayed to the user. Now, do the same for the incorrect buttons, but adjust the event listener accordingly.
document.addEventListener('DOMContentLoaded', function() {
/* When any correct answer is clicked, change button color to green and display "Correct!" */
// Select correct buttons
let corrects = document.querySelectorAll('.correct');
// Add event listeners to correct buttons
for (let i = 0; i < corrects.length; i++) {
corrects[i].addEventListener('click', function() {
// Set background color to green
corrects[i].style.backgroundColor = 'Green';
// Add "Correct!" feedback
document.querySelector('#feedback1').innerHTML = 'Correct!';
});
}
/* When any incorrect answer is clicked, change button color to red and display "Incorrect" */
// Select incorrect buttons
let incorrects = document.querySelectorAll('.incorrect');
// Add event listeners to incorrect buttons
for (let i = 0; i < incorrects.length; i++) {
incorrects[i].addEventListener('click', function() {
// Set background color to red
incorrects[i].style.backgroundColor = 'Red';
// Add "Incorrect" feedback
document.querySelector('#feedback1').innerHTML = 'Incorrect';
});
}
});
Now for the final few steps! Turn to implementing your free response question. But first, you’ll likely want to add a few selectors to these elements, so you can select them via JavaScript.
<div class="section">
<h2>Part 2: Free Response</h2>
<hr>
<h3>In which country is it illegal to own only one guinea pig, as a lone guinea pig might get lonely?</h3>
<p id="feedback2"></p>
<input type="text"></input>
<button id="check">Check Answer</button>
</div>
Ideally, a user should be able to check their answer when they click on the button with the id of check
. Go ahead and create an event listener that button.
document.addEventListener('DOMContentLoaded', function() {
/* When any correct answer is clicked, change button color to green and display "Correct!" */
// Select correct buttons
let corrects = document.querySelectorAll('.correct');
// Add event listeners to correct buttons
for (let i = 0; i < corrects.length; i++) {
corrects[i].addEventListener('click', function() {
// Set background color to green
corrects[i].style.backgroundColor = 'Green';
// Add "Correct!" feedback
document.querySelector('#feedback1').innerHTML = 'Correct!';
});
}
/* When any incorrect answer is clicked, change button color to red and display "Incorrect" */
// Select incorrect buttons
let incorrects = document.querySelectorAll('.incorrect');
// Add event listeners to incorrect buttons
for (let i = 0; i < incorrects.length; i++) {
incorrects[i].addEventListener('click', function() {
// Set background color to red
incorrects[i].style.backgroundColor = 'Red';
// Add "Incorrect" feedback
document.querySelector('#feedback1').innerHTML = 'Incorrect';
});
}
/* Check free response submission */
// Add event listener to check button
document.querySelector('#check').addEventListener('click', function() {
// Check for correct answer
});
});
How to check for the correct answer? You’ll first need to select the input
element. Once you do, you can access the text inside it via its value
property.
document.addEventListener('DOMContentLoaded', function() {
/* When any correct answer is clicked, change button color to green and display "Correct!" */
// Select correct buttons
let corrects = document.querySelectorAll('.correct');
// Add event listeners to correct buttons
for (let i = 0; i < corrects.length; i++) {
corrects[i].addEventListener('click', function() {
// Set background color to green
corrects[i].style.backgroundColor = 'Green';
// Add "Correct!" feedback
document.querySelector('#feedback1').innerHTML = 'Correct!';
});
}
/* When any incorrect answer is clicked, change button color to red and display "Incorrect" */
// Select incorrect buttons
let incorrects = document.querySelectorAll('.incorrect');
// Add event listeners to incorrect buttons
for (let i = 0; i < incorrects.length; i++) {
incorrects[i].addEventListener('click', function() {
// Set background color to red
incorrects[i].style.backgroundColor = 'Red';
// Add "Incorrect" feedback
document.querySelector('#feedback1').innerHTML = 'Incorrect';
});
}
/* Check free response submission */
// Add event listener to check button
document.querySelector('#check').addEventListener('click', function() {
// Select input element
let input = document.querySelector('input');
// Test input element's value
if (input.value === 'Switzerland') {
input.style.backgroundColor = 'green';
document.querySelector('#feedback2').innerHTML = 'Correct!';
}
else {
input.style.backgroundColor = 'red';
document.querySelector('#feedback2').innerHTML = 'Incorrect';
}
});
});
And that’s all for your free response question! Try reloading the page to test your JavaScript.
Walkthrough
Not sure how to solve?
How to Test
No check50
for this problem, as implementations will vary based on your questions! But be sure to test both incorrect and correct responses for each of your questions to ensure that your webpage responds appropriately.
Run http-server
in your terminal while in your trivia
directory to start a web server that serves your webpage.
How to Submit
Per Step 4 below, after you submit, be sure to check your autograder results. If you see SUBMISSION ERROR: missing files (0.0/1.0)
, it means your file was either not named exactly as prescribed, you uploaded it to the wrong problem, or you did not include all files.
Correctness in submissions entails everything from reading the specification, writing code that is compliant with it, and submitting all files with the correct names. If you see this error, you should resubmit right away, making sure your submission is fully compliant with the specification. The staff will not adjust your filenames nor upload files for you after the fact!
- Download your
index.html
andstyles.css
files by control-clicking or right-clicking on the file in your codespace’s file browser and choosing Download. - Go to CS50’s Gradescope page.
- Click Problem Set 8: Trivia.
- Drag and drop your
index.html
andstyles.css
files to the area that says Drag & Drop. Be sure they have those exact filenames! If you upload a file with a different name, the autograder likely will fail when trying to run it, and ensuring you have uploaded files with the correct filenames is your responsibility! - Click Upload.
You should see a message that says “Problem Set 8: Trivia submitted successfully!”