Snippets Form

Bootstrap 5 Multi-Step Form with Progress Bar and Validation

A four-step project request form with selectable option cards, a progress bar, inline validation on required fields and a confirmation state.

Bootstrap 5 No jQuery Jun 2020 6.7K views

<section class="wdw-stage">
  <div class="container" style="max-width:820px">
    <div class="wdw-card overflow-hidden" id="msForm">
      <header class="d-flex flex-wrap justify-content-between align-items-center gap-3 p-4 border-bottom">
        <div><span class="wdw-eyebrow">Project request</span><h2 class="h5 fw-bold text-body-emphasis mb-0 mt-1">Tell us a little more about your project</h2></div>
        <a href="tel:1234567891" class="d-flex align-items-center gap-2 text-decoration-none fw-semibold text-body-emphasis"><span class="wdw-icon" style="width:2.5rem;height:2.5rem"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M22 16.9v3a2 2 0 0 1-2.2 2 19.8 19.8 0 0 1-8.6-3.1 19.5 19.5 0 0 1-6-6A19.8 19.8 0 0 1 2.1 4.2 2 2 0 0 1 4.1 2h3a2 2 0 0 1 2 1.7c.1 1 .4 1.9.7 2.8a2 2 0 0 1-.5 2.1L8.1 9.9a16 16 0 0 0 6 6l1.3-1.3a2 2 0 0 1 2.1-.4c.9.3 1.8.6 2.8.7a2 2 0 0 1 1.7 2z"/></svg></span>123 456 7891</a>
      </header>
      <div class="px-4 pt-4">
        <div class="d-flex justify-content-between small fw-semibold mb-2"><span class="wdw-muted" id="msStepLabel" aria-live="polite">Step 1 of 4</span><span class="text-primary" id="msPct">25% completed</span></div>
        <div class="progress" role="progressbar" aria-label="Form progress" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100" id="msProg" style="height:.5rem"><div class="progress-bar" id="msBar" style="width:25%"></div></div>
      </div>
      <form class="p-4 p-md-5" id="msSteps" novalidate>
        <div class="ms-step" data-step="1">
          <h3 class="h4 fw-bold text-body-emphasis mb-4" tabindex="-1">What should be done?</h3>
          <div class="row g-3" role="radiogroup" aria-label="Project type">
            <div class="col-12 col-sm-4"><input type="radio" class="btn-check" name="kind" id="kind-create" value="create" autocomplete="off" checked><label class="ms-choice w-100 h-100" for="kind-create"><span class="ms-tick" aria-hidden="true"></span><span class="wdw-icon ms-ic"><svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="4" width="18" height="12" rx="2"/><path d="M8 20h8M12 16v4M10 8l-2 2 2 2M14 8l2 2-2 2"/></svg></span><span class="fw-bold text-body-emphasis">Create website</span><span class="small wdw-muted">Start from scratch</span></label></div>
            <div class="col-12 col-sm-4"><input type="radio" class="btn-check" name="kind" id="kind-relaunch" value="relaunch" autocomplete="off"><label class="ms-choice w-100 h-100" for="kind-relaunch"><span class="ms-tick" aria-hidden="true"></span><span class="wdw-icon ms-ic"><svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 12a9 9 0 1 1-3-6.7"/><path d="M21 4v5h-5"/></svg></span><span class="fw-bold text-body-emphasis">Website relaunch</span><span class="small wdw-muted">Refresh an existing site</span></label></div>
            <div class="col-12 col-sm-4"><input type="radio" class="btn-check" name="kind" id="kind-unsure" value="unsure" autocomplete="off"><label class="ms-choice w-100 h-100" for="kind-unsure"><span class="ms-tick" aria-hidden="true"></span><span class="wdw-icon ms-ic"><svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="9"/><path d="M9.1 9a3 3 0 0 1 5.8 1c0 2-3 2.5-3 4.5M12 17.5h.01"/></svg></span><span class="fw-bold text-body-emphasis">I don't know yet</span><span class="small wdw-muted">Help me decide</span></label></div>
          </div>
        </div>
        <div class="ms-step d-none" data-step="2">
          <h3 class="h4 fw-bold text-body-emphasis mb-1" tabindex="-1">Personal details</h3><p class="wdw-muted mb-4 small">All fields are required.</p>
          <div class="row g-3">
<div class="col-12 col-sm-6"><div class="form-floating"><input type="text" class="form-control" id="fname" placeholder="First name" required autocomplete="given-name" aria-describedby="fname-fb"><label for="fname">First name</label><div class="invalid-feedback" id="fname-fb">Please enter first name.</div></div></div>
<div class="col-12 col-sm-6"><div class="form-floating"><input type="text" class="form-control" id="lname" placeholder="Last name" required autocomplete="family-name" aria-describedby="lname-fb"><label for="lname">Last name</label><div class="invalid-feedback" id="lname-fb">Please enter last name.</div></div></div>
<div class="col-12 col-sm-6"><div class="form-floating"><input type="email" class="form-control" id="email" placeholder="Email address" required autocomplete="email" aria-describedby="email-fb"><label for="email">Email address</label><div class="invalid-feedback" id="email-fb">Please enter email address.</div></div></div>
<div class="col-12 col-sm-6"><div class="form-floating"><input type="tel" class="form-control" id="mob" placeholder="Phone number" required autocomplete="tel" aria-describedby="mob-fb"><label for="mob">Phone number</label><div class="invalid-feedback" id="mob-fb">Please enter phone number.</div></div></div>
          </div>
        </div>
        <div class="ms-step d-none" data-step="3">
          <h3 class="h4 fw-bold text-body-emphasis mb-1" tabindex="-1">Website details</h3><p class="wdw-muted mb-4 small">Title and description are required.</p>
          <div class="row g-3">
<div class="col-12 col-sm-6"><div class="form-floating"><input type="text" class="form-control" id="cname" placeholder="Company name" aria-describedby="cname-fb"  ><label for="cname">Company name (optional)</label><div class="invalid-feedback" id="cname-fb">Please enter company name.</div></div></div>
<div class="col-12 col-sm-6"><div class="form-floating"><input type="text" class="form-control" id="zip" placeholder="Zip code" aria-describedby="zip-fb"  ><label for="zip">Zip code (optional)</label><div class="invalid-feedback" id="zip-fb">Please enter zip code.</div></div></div>
<div class="col-12 col-sm-6"><div class="form-floating"><input type="text" class="form-control" id="wtitle" placeholder="Website title" required aria-describedby="wtitle-fb" ><label for="wtitle">Website title</label><div class="invalid-feedback" id="wtitle-fb">Please enter website title.</div></div></div>
            <div class="col-12 col-sm-6"><div class="form-floating"><select class="form-select" id="wtype"><option>E-commerce</option><option>Entertainment</option><option>Personal</option><option>Business</option><option>Portfolio</option><option>Education</option></select><label for="wtype">Website type</label></div></div>
            <div class="col-12"><div class="form-floating"><textarea class="form-control" id="wdesc" aria-describedby="wdesc-fb" placeholder="Website description" style="height:110px;min-height:110px" required></textarea><label for="wdesc">Website description</label><div class="invalid-feedback" id="wdesc-fb">Please describe the website.</div></div></div>
          </div>
        </div>
        <div class="ms-step d-none text-center py-4" data-step="4">
          <div class="ms-done mx-auto mb-4"><svg width="36" height="36" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m5 12.5 4.5 4.5L19 7.5"/></svg></div>
          <h3 class="h4 fw-bold text-body-emphasis">Request submitted</h3>
          <p class="wdw-muted mx-auto mb-4" style="max-width:26rem">Thanks. You will receive an estimate by email and phone within one business day.</p>
          <button type="button" class="btn btn-outline-primary rounded-pill px-4" id="msReset">Start over</button>
        </div>
        <div class="d-flex justify-content-between gap-2 mt-5" id="msNav">
          <button type="button" class="btn btn-outline-secondary rounded-pill px-4 invisible" id="msBack">Back</button>
          <button type="button" class="btn btn-primary rounded-pill px-4" id="msNext">Next</button>
        </div>
      </form>
    </div>
  </div>
</section>

Built on Bootstrap 5.3.8 with plain JavaScript — no jQuery. Supports light and dark mode via data-bs-theme.