UNIT 22 • STAGE 7 OF 7

Form Logic

JavaScript multi-step form: classList, addEventListener, required field validation

UNIT 7 / 7
STEP 1

How JavaScript Controls Multi-Step Forms

Right now in Stage 6, all three form steps are visible at the same time. That is fine for styling, but a real multi-step form should show only one step at a time. JavaScript makes this happen by adding and removing a CSS class.

The pattern works in two parts. First, you add a CSS rule that hides every .form-step by default, and a second rule that shows the ones with the class active:

CSS rule to add (inside your <style> block): .form-step { display: none; }
.form-step.active { display: block; }

Then JavaScript adds or removes the active class when buttons are clicked. When active is on a step, that step is visible. When it is removed, the step disappears.

classList — the tool that makes this work

element.classList.add('active') adds the class. element.classList.remove('active') removes it. element.classList.contains('active') lets you check if it is already there. You used classList.toggle in earlier units. This is the same API, just with explicit add and remove instead of toggling.

STEP 2

Add the CSS Rule

Find your existing .form-step CSS in the <style> block. It probably just sets some margin or padding. Add display: none to it, then add the .form-step.active rule right after:

👉 Find .form-step in your CSS and add display: none: .form-step { display: none; }
.form-step.active { display: block; }

After you add this, the preview will go blank in the form area. All three steps are now hidden because none of them have the active class yet. That is correct. The JavaScript in the next step will add it to step 1 on page load.

STEP 3

Add the JavaScript

Before the closing </body> tag, add a <script> block with this code:

👉 Add before </body>: <script>
  const steps = document.querySelectorAll('.form-step');
  const dots = document.querySelectorAll('.step-dot');
  let current = 0;

  function showStep(index) {
    steps.forEach(function(step, i) {
      step.classList.remove('active');
      dots[i].classList.remove('active', 'done');
      if (i < index) dots[i].classList.add('done');
    });
    steps[index].classList.add('active');
    dots[index].classList.add('active');
    current = index;
  }

  showStep(0);

  document.getElementById('next-1').addEventListener('click', function() {
    var name = document.getElementById('name').value.trim();
    var email = document.getElementById('email').value.trim();
    if (name === '' || email === '') {
      alert('Please enter your name and email before continuing.');
      return;
    }
    showStep(1);
  });

  document.getElementById('back-2').addEventListener('click', function() {
    showStep(0);
  });

  document.getElementById('submit-btn').addEventListener('click', function() {
    showStep(2);
  });
</script>
STEP 4

What Each Part Does

Here is what you just wrote, broken down:

  • querySelectorAll('.form-step') collects all three step divs into a list called steps. This is like getElementById but it finds multiple elements at once and returns them all.
  • showStep(index) is a function you defined. It loops through all the steps, removes active from every one, then adds active to just the one at position index. Index 0 is Step 1, index 1 is Step 2, index 2 is the confirmation.
  • showStep(0) is called immediately when the page loads, making Step 1 visible from the start.
  • The Next button listener checks that name and email are not empty before advancing. If either field is blank, alert() shows a message and return stops the function from continuing.
  • value.trim() removes any spaces the user accidentally typed before checking if the field is empty. Without trim(), a user who types only spaces would pass the check.
  • The dots update automatically inside showStep. Steps before the current one get the done class (dim teal). The current step gets active (bright teal).

Try it in the preview

Click Next without filling anything in. You should see an alert. Fill in a name and email, click Next, and Step 2 appears. Click Back and you return to Step 1. Click Submit and the confirmation message appears. The dots update as you move through the steps.

STEP 5

Unit 22 Complete

Powwow Event Planner is done

You built a full event website across seven stages: a poster-style hero with Oswald display type, event info cards using flexbox, a two-day schedule with a CSS Grid timeline, dance category cards with aspect-ratio, a two-column vendor grid, a styled multi-step form, and JavaScript that controls which step the user sees.

The JavaScript pattern you used here, hiding elements by default and revealing them by adding a class, is one of the most common patterns in web development. Tabs, accordions, modals, carousels, and tooltips all work the same way at their core.

The concepts covered in this unit:

  • CSS custom properties (:root variables) as a design system foundation
  • clamp() for fluid responsive typography
  • Flex layout with flex: 1 and min-width for wrapping cards
  • CSS Grid timeline with grid-template-columns: 80px 1fr and border-left
  • aspect-ratio for consistent card proportions
  • justify-content: flex-end to anchor content to the bottom
  • Label-value pairs with flex-shrink: 0; min-width
  • Form element styling: input, select, textarea, :focus
  • Multi-step form logic: querySelectorAll, classList.add/remove, value.trim(), addEventListener
Code Editor
🥁

You're Registered

Thank you for registering for the Mille Lacs Band Powwow 2026. A confirmation email has been sent to the address you provided. We look forward to seeing you at the powwow.

Live Preview