Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to validate only parts of a form?

I have a multistep form with two fieldsets, containing two required inputs each. I want to validate only the first fieldset when the user wants to continue to the second one.

However, with my current approach, the entire form is validated, although I call checkValidity() only on the input elements of the first fieldset. As a result, when progressing to the second fieldset, users are greeted with invalidated input fields and warning tooltips.

What am I doing wrong? How can I validate the fieldsets separately? I’ve found approaches for jQuery and JSP, but not for plain ES6.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Here is my code.

let fieldsetElements;

function validateFieldset(step) {
  const inputElements = document.querySelectorAll(`fieldset.active input`);
  return !Array.from(inputElements).find((element) => !element.checkValidity());
}

function goToStep(step) {
  Array.from(fieldsetElements)
    .filter((element) => element.classList.contains("active"))
    .forEach((element) => element.classList.remove("active"));
  fieldsetElements[step - 1].classList.add("active");
}

function continueToStep(nextStep) {
  const currentStep = nextStep - 1;
  const fieldsetValid = validateFieldset(currentStep);
  if (fieldsetValid) {
    goToStep(nextStep);
  }
}

document.addEventListener("DOMContentLoaded", () => {
  fieldsetElements = document.getElementsByTagName("fieldset");
  goToStep(1);
});
fieldset {
  display: none;
}
fieldset.active {
  display: block;
}
<form>
  <fieldset>
    <legend>Your name</legend>
    <p>
      <label for="prename">Prename (required)</label><br />
      <input type="text" id="prename" name="prename" required />
    </p>
    <p>
      <label for="surname">Surname (required)</label><br />
      <input type="text" id="surname" name="surname" required />
    </p>
    <p>
      <button onclick="continueToStep(2)">Continue</button>
    </p>
  </fieldset>
  <fieldset>
    <legend>Your contact information</legend>
    <p>
      <label for="email">Email (required)</label><br />
      <input type="email" id="email" name="email" required />
    </p>
    <p>
      <label for="phone">Phone</label><br />
      <input type="tel" id="phone" name="phone" />
    </p>
    <button onclick="goToStep(1)">Go back</button>
    <button type="submit">Submit</button>
  </fieldset>
</form>

>Solution :

The issue is that without a type attribute all button tags trigger form validation. Add type="button" to your buttons and it should work as you expect.

let fieldsetElements;

function validateFieldset(step) {
  const inputElements = document.querySelectorAll(`fieldset.active input`);
  return !Array.from(inputElements).find((element) => !element.checkValidity());
}

function goToStep(step) {
  Array.from(fieldsetElements)
    .filter((element) => element.classList.contains("active"))
    .forEach((element) => element.classList.remove("active"));
  fieldsetElements[step - 1].classList.add("active");
}

function continueToStep(nextStep) {
  const currentStep = nextStep - 1;
  const fieldsetValid = validateFieldset(currentStep);
  if (fieldsetValid) {
    goToStep(nextStep);
  }
}

document.addEventListener("DOMContentLoaded", () => {
  fieldsetElements = document.getElementsByTagName("fieldset");
  goToStep(1);
});
fieldset {
  display: none;
}
fieldset.active {
  display: block;
}
<form>
  <fieldset>
    <legend>Your name</legend>
    <p>
      <label for="prename">Prename (required)</label><br />
      <input type="text" id="prename" name="prename" required />
    </p>
    <p>
      <label for="surname">Surname (required)</label><br />
      <input type="text" id="surname" name="surname" required />
    </p>
    <p>
      <button type="button" onclick="continueToStep(2)">Continue</button>
    </p>
  </fieldset>
  <fieldset>
    <legend>Your contact information</legend>
    <p>
      <label for="email">Email (required)</label><br />
      <input type="email" id="email" name="email" required />
    </p>
    <p>
      <label for="phone">Phone</label><br />
      <input type="tel" id="phone" name="phone" />
    </p>
    <button  type="button" onclick="goToStep(1)">Go back</button>
    <button type="submit">Submit</button>
  </fieldset>
</form>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading