Lab 4: Tables and Forms
Today, you are creating a simple grocery list! The user should be able to enter the name of the item, the quantity, and any notes they want. You will use JavaScript to dynamically add rows to an HTML table.

🎵 The Objectives Rap 🎙️
- Understand the basic styles for HTML tables
- Then create a simple form with all its fields and labels
- Process the form with JavaScript to create a grocery item
- Dynamically create new rows so you don’t have to write ‘em
Getting Started
Download lab04.zip and extract the two files to a lab04 folder, inside your cs343 folder (or somewhere else safe).
In VS Code, open the grocery.html and grocery-styles.css files for editing. Open a live preview of the HTML page so you can see your changes as you make them.
Part 1: Style the Table 🎨
-
Look at the HTML for the table:
- Look at the headers and the example rows (don’t delete them yet!)
- You might want to review the tags used for tables
-
In
grocery-styles.css, modify the CSS to style the table and its elements:- Everywhere that says “TODO”, write CSS to style accordingly!
-
The final result should look like:

-
Take a look at the style for the
form-container.- The
widthis currently set to600px. - If you have 3 columns that are 200px wide, shouldn’t the total width of the table be 600px?
-
Think: Why is the table wider than 600px?
Hint
Is the width of a column truly 200px? Anything else that might add to the width?
- The
-
Make the width of the
form-containermatch the actual width of the table.
Part 2: Be “Form”-al 🤵♀️
-
In the HTML, add elements to the form so that the user can input the item, quantity, and notes for a grocery item:
- You should have three
<input>elements, one for each value.- Make sure each
<input>is the appropriate type (list of all types)!
- Make sure each
- For the
nameattribute of each input, use the same name as the field (e.g."item","quantity","notes") - Give each input a unique
idattribute (e.g."item-input","quantity-input","notes-input") - Make the item and quantity required
- Also include
<label> elementsfor each of those inputs! - The
forattribute must match each corresponding input’sid!
- You should have three
-
Next, at the bottom of the form, add a submit button.
- This will trigger form submission, which will make our JavaScript function run.
-
Once done, open the preview for the page.
- Yes the form will look ugly, but that’s okay.
- If you have more time later and want to learn about styling forms, feel free to do so!
-
Try clicking the submit button without filling out the required fields. What happens?
-
Fill out the fields and click submit. Now what happens? Take a look at the URL!
What’s happening?
- By default, HTML forms will send a GET request to a specified target.
- Without setting a target, it will target the same page that it’s on, essentially reloading the page.
- Look at how your form fields end up in the URL’s “query parameters” (after the question mark):
?item=Eggs&quantity=12¬es=large
-
Part 3: Make Rows 🚣♂️
-
Now, go to the
<script>element at the bottom of the<body>.- Look at the line of code that adds an “event listener” to the form’s “submit” event.
-
THINK: What function do you think gets called when the form is submitted?
Answer
The function named
addItemToListgets called!formEl.addEventListener("submit", addItemToList);In JavaScript, we can treat functions as “first-class citizens”, meaning we can pass them around as values!
-
THINK: Where can you put JavaScript in an HTML page? Why did we put this script at the bottom?
Answer
We need to access the “grocery-form” element, so we have to write the script at a point after the element is created and available in the DOM!
We could also put this script in the
<head>, but then we would need to wait for the DOM to load before accessing elements!
-
Analyze the
addItemToList()function.-
First, uncomment the line with
event.preventDefault()and then preview the page.- Fill out the fields and click submit. Anything different happen?
-
THINK: What do you think
preventDefault()does in this context?Answer
By default, submitting a form will cause the page to reload (to send the GET request).
Calling
event.preventDefault()stops that from happening, so we can handle the form submission with JavaScript instead!
-
Also look at the other lines of code in the function.
- We get the table’s body element in a variable called
listBody - We call
makeRow(), which is supposed to return a new row element - Finally, we add that new row to the table body!
- We get the table’s body element in a variable called
-
-
Complete the
makeRow()function, which will return a new<tr>element containing the values from the form fields.- Follow the TODO comments in the code.
- You will need to add cells to the row for each of the three fields: item, quantity, and notes.
-
Two ways to do this:
- Use
document.createElement(),element.textContent, andelement.appendChild()to create the row and cells (more code, but safe) -
Use
element.innerHTMLto set the contents of the row (unsafe, but less code).Why not .innerHTML?
Imagine the following was entered as a note in the form:
<script>stealAllYourInfo()</script>If you set the
innerHTMLto this string, then that malicious script could get executed! This is a form of Cross-Site Scripting (XSS), which is a common web security vulnerability.(Note that there have been safeguards added to not execute scripts like this, but it’s still generally not a good idea to use
innerHTMLwith user input.)
- Use
-
Note that you need to get the value of each element:
- E.g. use
myInput.valueinstead of justmyInput - (If you output
myInput, you might get something like[object Object]in the table instead of the actual value!)
- E.g. use
-
If you haven’t already, comment out or delete the example rows in the table body.
-
Don’t forget to preview your page frequently and test if everything is working!
Submission
Submit both grocery.html and grocery-styles.css to the appropriate assignment on Gradescope/Canvas.