如何验证表单的部分内容?

huangapple go评论54阅读模式
英文:

How to validate only parts of a form?

问题

我有一个多步表单,其中包含两个字段集,每个字段集中包含两个必填输入字段。我想在用户想要继续到第二个字段集时仅验证第一个字段集。

然而,根据我的当前方法,整个表单都会被验证,尽管我只在第一个字段集的输入元素上调用了checkValidity()。结果是,当进入第二个字段集时,用户会看到无效的输入字段和警告工具提示。

我做错了什么?如何可以分别验证这两个字段集?我找到了关于jQuery和JSP的方法,但没有找到纯ES6的方法。

以下是我的代码。

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>
英文:

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.

Here is my code.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

let fieldsetElements;

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

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

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

document.addEventListener(&quot;DOMContentLoaded&quot;, () =&gt; {
  fieldsetElements = document.getElementsByTagName(&quot;fieldset&quot;);
  goToStep(1);
});

<!-- language: lang-css -->

fieldset {
  display: none;
}
fieldset.active {
  display: block;
}

<!-- language: lang-html -->

&lt;form&gt;
  &lt;fieldset&gt;
    &lt;legend&gt;Your name&lt;/legend&gt;
    &lt;p&gt;
      &lt;label for=&quot;prename&quot;&gt;Prename (required)&lt;/label&gt;&lt;br /&gt;
      &lt;input type=&quot;text&quot; id=&quot;prename&quot; name=&quot;prename&quot; required /&gt;
    &lt;/p&gt;
    &lt;p&gt;
      &lt;label for=&quot;surname&quot;&gt;Surname (required)&lt;/label&gt;&lt;br /&gt;
      &lt;input type=&quot;text&quot; id=&quot;surname&quot; name=&quot;surname&quot; required /&gt;
    &lt;/p&gt;
    &lt;p&gt;
      &lt;button onclick=&quot;continueToStep(2)&quot;&gt;Continue&lt;/button&gt;
    &lt;/p&gt;
  &lt;/fieldset&gt;
  &lt;fieldset&gt;
    &lt;legend&gt;Your contact information&lt;/legend&gt;
    &lt;p&gt;
      &lt;label for=&quot;email&quot;&gt;Email (required)&lt;/label&gt;&lt;br /&gt;
      &lt;input type=&quot;email&quot; id=&quot;email&quot; name=&quot;email&quot; required /&gt;
    &lt;/p&gt;
    &lt;p&gt;
      &lt;label for=&quot;phone&quot;&gt;Phone&lt;/label&gt;&lt;br /&gt;
      &lt;input type=&quot;tel&quot; id=&quot;phone&quot; name=&quot;phone&quot; /&gt;
    &lt;/p&gt;
    &lt;button onclick=&quot;goToStep(1)&quot;&gt;Go back&lt;/button&gt;
    &lt;button type=&quot;submit&quot;&gt;Submit&lt;/button&gt;
  &lt;/fieldset&gt;
&lt;/form&gt;

<!-- end snippet -->

答案1

得分: 1

问题在于没有type属性,所有的button标签都会触发表单验证。请将type="button"添加到你的按钮上,它就会按你的期望工作。

<button type="button" onclick="continueToStep(2)">Continue</button>
<button type="button" onclick="goToStep(1)">Go back</button>
<button type="submit">Submit</button>

请注意,我只翻译了代码部分,没有包含其他内容。

英文:

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

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

let fieldsetElements;

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

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

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

document.addEventListener(&quot;DOMContentLoaded&quot;, () =&gt; {
  fieldsetElements = document.getElementsByTagName(&quot;fieldset&quot;);
  goToStep(1);
});

<!-- language: lang-css -->

fieldset {
  display: none;
}
fieldset.active {
  display: block;
}

<!-- language: lang-html -->

&lt;form&gt;
  &lt;fieldset&gt;
    &lt;legend&gt;Your name&lt;/legend&gt;
    &lt;p&gt;
      &lt;label for=&quot;prename&quot;&gt;Prename (required)&lt;/label&gt;&lt;br /&gt;
      &lt;input type=&quot;text&quot; id=&quot;prename&quot; name=&quot;prename&quot; required /&gt;
    &lt;/p&gt;
    &lt;p&gt;
      &lt;label for=&quot;surname&quot;&gt;Surname (required)&lt;/label&gt;&lt;br /&gt;
      &lt;input type=&quot;text&quot; id=&quot;surname&quot; name=&quot;surname&quot; required /&gt;
    &lt;/p&gt;
    &lt;p&gt;
      &lt;button type=&quot;button&quot; onclick=&quot;continueToStep(2)&quot;&gt;Continue&lt;/button&gt;
    &lt;/p&gt;
  &lt;/fieldset&gt;
  &lt;fieldset&gt;
    &lt;legend&gt;Your contact information&lt;/legend&gt;
    &lt;p&gt;
      &lt;label for=&quot;email&quot;&gt;Email (required)&lt;/label&gt;&lt;br /&gt;
      &lt;input type=&quot;email&quot; id=&quot;email&quot; name=&quot;email&quot; required /&gt;
    &lt;/p&gt;
    &lt;p&gt;
      &lt;label for=&quot;phone&quot;&gt;Phone&lt;/label&gt;&lt;br /&gt;
      &lt;input type=&quot;tel&quot; id=&quot;phone&quot; name=&quot;phone&quot; /&gt;
    &lt;/p&gt;
    &lt;button  type=&quot;button&quot; onclick=&quot;goToStep(1)&quot;&gt;Go back&lt;/button&gt;
    &lt;button type=&quot;submit&quot;&gt;Submit&lt;/button&gt;
  &lt;/fieldset&gt;
&lt;/form&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年3月7日 01:12:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/75653830.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定