【问题标题】:Problem when unchecking checkbox buttons in a form取消选中表单中的复选框按钮时出现问题
【发布时间】:2020-04-14 15:41:55
【问题描述】:

在我的演示表单中,您可以在下面运行,在按钮选择时按顺序启用字段集。因此,检查第一个字段集中的按钮会启用第二个,依此类推。

如果未选中第一个字段集中的所有复选框,则应重置表单,然后再次禁用第二个到第四个字段集。

但是,当第一个字段集中的一个复选框被取消选中时,第一个字段集中的所有其他复选框按钮也被取消选中,这当然不是应该的工作方式。

我做错了什么?


document.addEventListener("DOMContentLoaded", _ => {
  const form = document.forms[0]

  // First, disable all fieldsets except the first

  function disableFieldsets() {
    const disabledFieldsets = form.querySelectorAll(
      "section:not(:first-of-type) fieldset"
    )

    for (let i = 0; i < disabledFieldsets.length; i++) {
      disabledFieldsets[i].disabled = true
    }
  }

  disableFieldsets()

  // Sequentially enable fieldsets on selection

  const sections = form.querySelectorAll("section")

  let reset = false
  
  sections.forEach(section => {
    section.addEventListener("change", function() {
      let nextFieldset = this.nextElementSibling.querySelector("fieldset")
      if (nextFieldset && !reset) {
        nextFieldset.disabled = false
      } else if (reset) {
        reset = false
      }
    })
  })

  // Reset form and disable fieldsets after all inputs in the first fieldset are deselected

  const firstFieldsetButtons = form.querySelectorAll("[name=First]")
  let isChecked = false

  firstFieldsetButtons.forEach(firstFieldsetButton => {
    firstFieldsetButton.addEventListener("click", function(e) {
      if (this.checked) {
        isChecked = true
      } else {
        form.reset()
        disableFieldsets()
      }
    })
  })
})
<main>
<form method="post" action="">    
  <section>
  <fieldset>
    <legend>First Fieldset</legend>
    <label><input type=checkbox name=First value=A>A</label>
    <label><input type=checkbox name=First value=B>B</label>
    <label><input type=checkbox name=First value=C>C</label>
  </fieldset>
  </section>
  
  <section>
  <fieldset>
    <legend>Second Fieldset</legend>
    <label><input type=radio name=Second value=1.1>1.1</label>
    <label><input type=radio name=Second value=1.2>1.2</label>
    <label><input type=radio name=Second value=1.3>1.3</label>
  </fieldset>
  </section>
  
  <section>
  <fieldset>
    <legend>Third Fieldset</legend>
    <label><input type=radio name=Third value=2.1>2.1</label>
    <label><input type=radio name=Third value=2.2>2.2</label>
    <label><input type=radio name=Third value=2.3>2.3</label>
  </fieldset>
  </section>
  
  <section>
  <fieldset>
    <legend>Fourth Fieldset</legend>
    <label><input type=radio name=Fourth value=3.1>3.1</label>
    <label><input type=radio name=Fourth value=3.2>3.2</label>
    <label><input type=radio name=Fourth value=3.3>3.3</label>
  </fieldset>
  </section>
  
  <input type=submit value=Submit>
</form>
</main>

【问题讨论】:

  • 当任何第一个字段集复选框未选中时,您正在通过执行form.reset() 重置表单。

标签: javascript html forms ecmascript-6


【解决方案1】:

再做一个这样的条件: if(this.closest('fieldset').querySelectorAll('input:checked').length &gt; 0) { return;}

sn-p:

document.addEventListener("DOMContentLoaded", _ => {
  const form = document.forms[0]

  // First, disable all fieldsets except the first

  function disableFieldsets() {
    const disabledFieldsets = form.querySelectorAll(
      "section:not(:first-of-type) fieldset"
    )

    for (let i = 0; i < disabledFieldsets.length; i++) {
      disabledFieldsets[i].disabled = true
    }
  }

  disableFieldsets()

  // Sequentially enable fieldsets on selection

  const sections = form.querySelectorAll("section")

  let reset = false
  
  sections.forEach(section => {
    section.addEventListener("change", function() {
      let nextFieldset = this.nextElementSibling.querySelector("fieldset")
      if (nextFieldset && !reset) {
        nextFieldset.disabled = false
      } else if (reset) {
        reset = false
      }
    })
  })

  // Reset form and disable fieldsets after all inputs in the first fieldset are deselected

  const firstFieldsetButtons = form.querySelectorAll("[name=First]")
  let isChecked = false

  firstFieldsetButtons.forEach(firstFieldsetButton => {
    firstFieldsetButton.addEventListener("click", function(e) { 
      if(this.closest('fieldset').querySelectorAll('input:checked').length > 0) { return;} 
      if (this.checked) {
        isChecked = true
      }
     
      else {
        form.reset()
        disableFieldsets()
      }
    })
  })
})
<main>
<form method="post" action="">    
  <section>
  <fieldset>
    <legend>First Fieldset</legend>
    <label><input type=checkbox name=First value=A>A</label>
    <label><input type=checkbox name=First value=B>B</label>
    <label><input type=checkbox name=First value=C>C</label>
  </fieldset>
  </section>
  
  <section>
  <fieldset>
    <legend>Second Fieldset</legend>
    <label><input type=radio name=Second value=1.1>1.1</label>
    <label><input type=radio name=Second value=1.2>1.2</label>
    <label><input type=radio name=Second value=1.3>1.3</label>
  </fieldset>
  </section>
  
  <section>
  <fieldset>
    <legend>Third Fieldset</legend>
    <label><input type=radio name=Third value=2.1>2.1</label>
    <label><input type=radio name=Third value=2.2>2.2</label>
    <label><input type=radio name=Third value=2.3>2.3</label>
  </fieldset>
  </section>
  
  <section>
  <fieldset>
    <legend>Fourth Fieldset</legend>
    <label><input type=radio name=Fourth value=3.1>3.1</label>
    <label><input type=radio name=Fourth value=3.2>3.2</label>
    <label><input type=radio name=Fourth value=3.3>3.3</label>
  </fieldset>
  </section>
  
  <input type=submit value=Submit>
</form>
</main>

【讨论】:

  • 嘿,我刚刚尝试了您的建议,并且在取消选中最后一个选中的复选框后表单不会重置。你能帮忙吗?
  • 哦。没问题,给我一点时间
  • 我一定不明白你的意思......当取消选中所有第一个字段集输入时,第一部分不会重置或禁用其他字段,第二部分将在取消选中它们后重置表单。 ..那么你希望表格什么时候重置?因为您可以触发该特定事件,仅此而已....
  • 哦!再给我一秒钟
  • @Tzar 希望我终于得到你的要求...检查我的编辑
猜你喜欢
  • 1970-01-01
  • 2014-08-07
  • 2017-09-28
  • 2020-04-05
  • 2016-10-18
  • 1970-01-01
  • 2014-05-14
  • 2013-11-18
  • 2018-06-29
相关资源
最近更新 更多