Adding New Entries

Section overview

In this lesson, we will bring our running tracker to life using JavaScript. You will learn how to capture user input from the form, handle form submission, store entries into an array, and dynamically update the display.

By the end of this lesson, you'll be able to add running entries that appear in the Last 7 days list, and understand how to manipulate the DOM to update the UI dynamically.

Adding a script tag

JavaScript code can be written directly in HTML using the <script> tag. Add this at the bottom of our HTML, just above the closing </body> tag:

    </section>
    <script src="script.js"></script> // add
  </body>
</html>
  • The <script> tag tells the browser to load and execute JavaScript code.
  • src="script.js" links to an external JavaScript file (we'll create this next).
  • We place it at the bottom so the HTML elements load first, making them available to control using JavaScript.

JavaScript code can also be placed between the <script> tags, or, in an external file as we will use.

Creating the JavaScript file

Create a new file called script.js in your project folder, alongside the two other files:

running-tracker/
├── index.html
├── styles.css
└── script.js

Setting up the entries array

We'll use an array to store all running entries. An array is common in many programming languages, and used to store multiple items using a single variable name. Add this at the top of your script.js:

let entries = [];
const entriesWrapper = document.querySelector('#entries');
  • let entries = [] creates an empty array to store running distances.
  • document.querySelector('#entries') selects the <ul> element with id entries and stores it in a constant called entriesWrapper.
  • We use const because the reference to the element won't change, even though we'll modify its contents.

querySelector() is used to find the first element matching the provided CSS selector, such as a class name (.className), or an ID as used above.

Creating the addNewEntry function

Now we move onto adding a new function to disply the running entried created by the user. Earlier we created the HTML section to display this:

 <section class="entriesWrapper">
    <h3>Last 7 days:</h3>
    <ul id="entries">
      <li>-</li>
      <li>-</li>
      <li>-</li>
      <li>-</li>
      <li>-</li>
      <li>-</li>
      <li>-</li>
    </ul>
  </section>

This function will create the <li> elements with the actual distance value entered by the user:

function addNewEntry(newEntry) {
  entriesWrapper.removeChild(entriesWrapper.firstElementChild);
  const listItem = document.createElement('li');
  const listValue = document.createTextNode(newEntry.toFixed(1));
  listItem.appendChild(listValue);
  entriesWrapper.appendChild(listItem);
}
  • function addNewEntry(newEntry) creates a function that accepts a number parameter.
  • entriesWrapper.removeChild(entriesWrapper.firstElementChild) removes the first <li> element (the oldest entry or placeholder).
  • document.createElement('li') creates a new list item element.
  • document.createTextNode(newEntry.toFixed(1)) creates a text node with the entry value formatted to 1 decimal place.
  • .toFixed(1) converts the number to a string with exactly 1 decimal place (e.g. 2.5 becomes "2.5").
  • listItem.appendChild(listValue) adds the text node to the list item.
  • entriesWrapper.appendChild(listItem) adds the new list item to the end of the list.

This creates a "rolling" list where new entries appear at the end and old ones are removed from the beginning, keeping exactly 7 items visible.

Handling form submission

When creating the HTML structure, we added an input element for the user to enter todays running distance:

 <form>
  <label for="entry">Number of miles today:</label>
  <br />
  <input type="number" id="entry" step="0.1" />
  <br />
  <button type="submit">Add</button>
</form>

Also, the button has a type=submit which will submit the form when clicked. Now let's create a function to handle when the user submits the form. Place this below the previous JavaScript code:

function handleSubmit(event) {
  event.preventDefault();
  const entry = Number(document.querySelector('#entry').value);
  console.log(entry);

  if (!entry) return;
  entries.push(entry);
  document.querySelector('form').reset();
  addNewEntry(entry);
}
  • function handleSubmit(event) creates a function that receives the form submission event.
  • event.preventDefault() stops the browser's default form submission behavior (which would reload the page).
  • document.querySelector('#entry') selects the input field by its ID.
  • .value gets the current value from the input entered by the user.
  • Number(...) converts the string to a number (e.g. "2.5" becomes 2.5).
  • console.log(entry) outputs the value to the browser console for debugging.
  • if (!entry) return checks if the entry is falsy (empty, 0, or NaN) and exits early if so.
  • entries.push(entry) adds the new entry to our array.
  • document.querySelector('form').reset() clears the form input after submission.
  • addNewEntry(entry) calls our function to update the display.

Adding the event listener

Finally, we need to connect the form to our handleSubmit function:

const form = document
  .querySelector('form')
  .addEventListener('submit', handleSubmit);
  • document.querySelector('form') selects the form element.
  • .addEventListener('submit', handleSubmit) listens for the form's submit event.
  • When the form is submitted (by clicking the button or pressing Enter), handleSubmit is called.

Complete JavaScript code

Here's the complete script.js file for this lesson:

let entries = [];
const entriesWrapper = document.querySelector('#entries');

function addNewEntry(newEntry) {
  entriesWrapper.removeChild(entriesWrapper.firstElementChild);
  const listItem = document.createElement('li');
  const listValue = document.createTextNode(newEntry.toFixed(1));
  listItem.appendChild(listValue);
  entriesWrapper.appendChild(listItem);
}

function handleSubmit(event) {
  event.preventDefault();
  const entry = Number(document.querySelector('#entry').value);
  console.log(entry);

  if (!entry) return;
  entries.push(entry);
  document.querySelector('form').reset();
  addNewEntry(entry);
}

const form = document
  .querySelector('form')
  .addEventListener('submit', handleSubmit);

Testing the functionality

  1. Open your index.html in a browser.
  2. Enter a number in the input field (e.g. 2.5).
  3. Click the "Add" button or press Enter.
  4. You should see the new entry appear in the "Last 7 days" list.
  5. The placeholder - should be removed and your entry should appear.
  6. Try adding multiple entries to see the rolling list in action.

Understanding the flow

Here's what happens when a user submits the form:

  1. User enters value: Types a number like 3.2 in the input field.
  2. Form submits: User clicks "Add" button or presses Enter.
  3. Event fires: Browser triggers the submit event on the form.
  4. Handler runs: handleSubmit function is called with the event object.
  5. Default prevented: preventDefault() stops page reload.
  6. Value extracted: JavaScript gets the input value and converts it to a number.
  7. Validation: Checks if entry is valid (not empty or zero).
  8. Storage: Adds an entry to the entries array.
  9. Form reset: Clears the input field.
  10. Display update: addNewEntry adds the new entry to the list.

Summary

In this lesson, you've learned how to:

  • Store data in arrays: Created an entries array to hold running distances.
  • Select DOM elements: Used querySelector to find HTML elements.
  • Handled form events: Prevented default form behavior and captured user input.
  • Create DOM elements: Dynamically created list items with createElement.
  • Update the display: Added new entries to the list and removed old ones.
  • Format numbers: Used toFixed() to display numbers with consistent decimal places.

In the next lesson, we continue by adding calculations to calculate totals and averages from the entries.