【问题标题】:jQuery multi-step form: disable next button when fields uncheckedjQuery多步表单:未选中字段时禁用下一步按钮
【发布时间】:2018-03-15 16:07:20
【问题描述】:

我有一个多步骤表单,在表单的每个步骤上都有一个“下一步”和“返回”按钮。一旦满足每个部分的条件,我将使用 jQuery 启用“下一步”按钮。例如:至少一个复选框被选中或一个单选按钮被选中。

我遇到了一个问题,在完成多个部分后,我返回上一个部分并取消选中所有复选框,并且“下一步”按钮保持启用状态。

这里有一个 Codepen,是我正在使用的粗略版本 - 请注意,所有部分都可见,以显示按钮在您开始检查/取消检查后如何保持启用状态:https://codepen.io/abbasarezoo/pen/jZgQOV

我当前的代码:

<form>
    <fieldset class="panels">
        <h2>1: Select multiple answers</h2>
        <label for="checkbox-1">Checkbox 1</label>
        <input type="checkbox" id="checkbox-1" name="checkbox" />
        <label for="checkbox-2">Checkbox 2</label>
        <input type="checkbox" id="checkbox-2" name="checkbox" />
        <label for="checkbox-3">Checkbox 3</label>
        <input type="checkbox" id="checkbox-3" name="checkbox" />
        <br />
        <button type="button" class="next-q" disabled>Next</button>
    </fieldset>
    <fieldset class="panels">
        <h2>2: Select multiple answers</h2>
        <label for="checkbox-4">Checkbox 1</label>
        <input type="checkbox" id="checkbox-4" name="checkbox" />
        <label for="checkbox-5">Checkbox 2</label>
        <input type="checkbox" id="checkbox-5" name="checkbox" />
        <label for="checkbox-6">Checkbox 3</label>
        <input type="checkbox" id="checkbox-6" name="checkbox" />
        <br />
        <button type="button" class="next-q" disabled>Next</button>
    </fieldset>
    <fieldset class="panels">
        <h2>3: Select one answer</h2>
        <label for="radio-1">Radio 1</label>
        <input type="radio" id="radio-1" name="radio" />
        <label for="radio-2">Radio 2</label>
        <input type="radio" id="radio-2" name="radio" />
        <label for="radio-2">Radio 3</label>
        <input type="radio" id="radio-3" name="radio" />
        <br />
        <button type="button" class="next-q" disabled>Next</button>
        <button type="button" class="previous-q">Previous</button>
    </fieldset>
    <fieldset class="rows">
        <h2>4: Select one answer per row</h2>
        <div class="radio-row">
            <h3>Row 1</h3>
            <label for="radio-4">Radio 1</label>
            <input type="radio" id="radio-4" name="radio-row-1" />
            <label for="radio-5">Radio 2</label>
            <input type="radio" id="radio-5" name="radio-row-1" />
            <label for="radio-6">Radio 3</label>
            <input type="radio" id="radio-6" name="radio-row-1" />
        </div>
        <div class="radio-row">
            <h3>Row 2</h3>
            <label for="radio-7">Radio 1</label>
            <input type="radio" id="radio-7" name="radio-row-2" />
            <label for="radio-8">Radio 2</label>
            <input type="radio" id="radio-8" name="radio-row-2" />
            <label for="radio-9">Radio 3</label>
            <input type="radio" id="radio-9" name="radio-row-2" />
        </div>
        <button type="button" class="next-q" disabled>Next</button>
        <button type="button" class="previous-q">Previous</button>
    </fieldset>
</form>

JS:

var $panelsInput = $('.panels input'),
        $rowsInput = $('.rows input');

$panelsInput.click(function () {
  if ($('.panels input:checked').length >= 1) {
    $(this).closest('.panels').find('.next-q').prop('disabled', false);
  }
  else {
    $(this).closest('.panels').find('.next-q').prop('disabled', true);
  }
});

$rowsInput.click(function () {
    var radioLength = $('.radio-row').length;
    if ($('.rows input:checked').length == radioLength) {
        $('.rows .next-q').prop('disabled', false);
    }
    else {
        $('.rows .next-q').prop('disabled', true);
    }
});

有什么办法可以做到吗?

【问题讨论】:

    标签: javascript jquery html css forms


    【解决方案1】:

    当您选择输入以查看是否被选中时,您选择了所有输入

    if ($('.panels input:checked').length &gt;= 1) {

    您只需从用户单击的面板中选择输入

    if ($(this).closest('.panels').find('input:checked').length &gt;= 1) {

    https://codepen.io/spacedog4/pen/YaWqdo?editors=1010

    【讨论】:

      【解决方案2】:

      请查看$panelsInput.click(function (){}); 中的以下评论,您需要获取当前面板(用户点击)的checked 计数,而不是全部。

      因此,您的代码中的比较: $('.panels input:checked').length &gt;= 1

      需要更改为: $(this).parent().find('input:checked').length &gt;= 1

      var $panelsInput = $('.panels input'),
          $rowsInput = $('.rows input');
      
      $panelsInput.click(function () {
        //get current input, find out its parent, then get the count of checked
        if ($(this).parent().find('input:checked').length >= 1) {
          $(this).closest('.panels').find('.next-q').prop('disabled', false);
        }
        else {
          $(this).closest('.panels').find('.next-q').prop('disabled', true);
        }
      });
      
      $rowsInput.click(function () {
          var radioLength = $('.radio-row').length;
          if ($('.rows input:checked').length == radioLength) {
              $('.rows .next-q').prop('disabled', false);
          }
          else {
              $('.rows .next-q').prop('disabled', true);
          }
      });
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <form>
        <fieldset class="panels">
          <h2>1: Select multiple answers</h2>
          <label for="checkbox-1">Checkbox 1</label>
          <input type="checkbox" id="checkbox-1" name="checkbox" />
          <label for="checkbox-2">Checkbox 2</label>
          <input type="checkbox" id="checkbox-2" name="checkbox" />
          <label for="checkbox-3">Checkbox 3</label>
          <input type="checkbox" id="checkbox-3" name="checkbox" />
          <br />
          <button type="button" class="next-q" disabled>Next</button>
        </fieldset>
        <fieldset class="panels">
          <h2>2: Select multiple answers</h2>
          <label for="checkbox-4">Checkbox 1</label>
          <input type="checkbox" id="checkbox-4" name="checkbox" />
          <label for="checkbox-5">Checkbox 2</label>
          <input type="checkbox" id="checkbox-5" name="checkbox" />
          <label for="checkbox-6">Checkbox 3</label>
          <input type="checkbox" id="checkbox-6" name="checkbox" />
          <br />
          <button type="button" class="next-q" disabled>Next</button>
        </fieldset>
        <fieldset class="panels">
          <h2>3: Select one answer</h2>
          <label for="radio-1">Radio 1</label>
          <input type="radio" id="radio-1" name="radio" />
          <label for="radio-2">Radio 2</label>
          <input type="radio" id="radio-2" name="radio" />
          <label for="radio-2">Radio 3</label>
          <input type="radio" id="radio-3" name="radio" />
          <br />
          <button type="button" class="next-q" disabled>Next</button>
          <button type="button" class="previous-q">Previous</button>
        </fieldset>
        <fieldset class="rows">
          <h2>4: Select one answer per row</h2>
          <div class="radio-row">
            <h3>Row 1</h3>
            <label for="radio-4">Radio 1</label>
            <input type="radio" id="radio-4" name="radio-row-1" />
            <label for="radio-5">Radio 2</label>
            <input type="radio" id="radio-5" name="radio-row-1" />
            <label for="radio-6">Radio 3</label>
            <input type="radio" id="radio-6" name="radio-row-1" />
          </div>
          <div class="radio-row">
            <h3>Row 2</h3>
            <label for="radio-7">Radio 1</label>
            <input type="radio" id="radio-7" name="radio-row-2" />
            <label for="radio-8">Radio 2</label>
            <input type="radio" id="radio-8" name="radio-row-2" />
            <label for="radio-9">Radio 3</label>
            <input type="radio" id="radio-9" name="radio-row-2" />
          </div>
          <button type="button" class="next-q" disabled>Next</button>
          <button type="button" class="previous-q">Previous</button>
        </fieldset>
      </form>

      【讨论】:

      • 不错!工作一种享受。
      【解决方案3】:

      我认为在更灵活的form 级别使用event delegation 处理交互很有趣:

      • 内存中只加载了一个处理程序。 (顺便说一下,只有一个作用域负责 prev/next 行为背后的逻辑)。
      • 您可以向表单动态添加面板(具有相同的标记结构),并且按钮将立即起作用,而无需另一个侦听器注册步骤。

      var $panelsInput = $('.panels input')
          , $rowsInput = $('.rows input')
          ;
      
      $('form').on('click', function (e) {
         let $t = $(this)
             , $target = $(e.target)
             , $fieldset = $target.closest('fieldset')
             , $rows = $fieldset.find('.radio-row')
             ;
             
         // When a button is clicked
         if ($target.is('button')) {
           // Next button
           if ($target.is('.next-q')) {
               $fieldset.addClass('hide').next().addClass('show');
           // Prev button
           } else {
              // Untick boxes
              $fieldset.find('input').prop('checked', false).end()
              // Disable appropriate button
              .find('.next-q').prop('disabled', true).end()
              .prev().removeClass('hide').nextAll().removeClass('show');
              
           }
           
         // When a checkbox is clicked
         } else if ($target.is('input')) {
              let $containers = ($rows.length ? $rows : $fieldset)
                  , containersHavingAtickedBox = $containers.filter(function() {
                    return !!$(this).find('input:checked').length
                  })
                  , shouldEnable = $containers.length === containersHavingAtickedBox.length
                  ;
              $fieldset.find('.next-q').prop('disabled', !shouldEnable);
         }
      });
      fieldset ~ fieldset, .hide{display:none}
      fieldset.show:not(.hide){display: block}
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <form>
          <fieldset class="panels">
              <h2>1: Select multiple answers</h2>
              <label for="checkbox-1">Checkbox 1</label>
              <input type="checkbox" id="checkbox-1" name="checkbox" />
              <label for="checkbox-2">Checkbox 2</label>
              <input type="checkbox" id="checkbox-2" name="checkbox" />
              <label for="checkbox-3">Checkbox 3</label>
              <input type="checkbox" id="checkbox-3" name="checkbox" />
              <br />
              <button type="button" class="next-q" disabled>Next</button>
          </fieldset>
          <fieldset class="panels">
              <h2>2: Select multiple answers</h2>
              <label for="checkbox-4">Checkbox 1</label>
              <input type="checkbox" id="checkbox-4" name="checkbox" />
              <label for="checkbox-5">Checkbox 2</label>
              <input type="checkbox" id="checkbox-5" name="checkbox" />
              <label for="checkbox-6">Checkbox 3</label>
              <input type="checkbox" id="checkbox-6" name="checkbox" />
              <br />
              <button type="button" class="next-q" disabled>Next</button>
          </fieldset>
          <fieldset class="panels">
              <h2>3: Select one answer</h2>
              <label for="radio-1">Radio 1</label>
              <input type="radio" id="radio-1" name="radio" />
              <label for="radio-2">Radio 2</label>
              <input type="radio" id="radio-2" name="radio" />
              <label for="radio-2">Radio 3</label>
              <input type="radio" id="radio-3" name="radio" />
              <br />
              <button type="button" class="next-q" disabled>Next</button>
              <button type="button" class="previous-q">Previous</button>
          </fieldset>
          <fieldset class="rows">
              <h2>4: Select one answer per row</h2>
              <div class="radio-row">
                  <h3>Row 1</h3>
                  <label for="radio-4">Radio 1</label>
                  <input type="radio" id="radio-4" name="radio-row-1" />
                  <label for="radio-5">Radio 2</label>
                  <input type="radio" id="radio-5" name="radio-row-1" />
                  <label for="radio-6">Radio 3</label>
                  <input type="radio" id="radio-6" name="radio-row-1" />
              </div>
              <div class="radio-row">
                  <h3>Row 2</h3>
                  <label for="radio-7">Radio 1</label>
                  <input type="radio" id="radio-7" name="radio-row-2" />
                  <label for="radio-8">Radio 2</label>
                  <input type="radio" id="radio-8" name="radio-row-2" />
                  <label for="radio-9">Radio 3</label>
                  <input type="radio" id="radio-9" name="radio-row-2" />
              </div>
              <button type="button" class="next-q" disabled>Next</button>
              <button type="button" class="previous-q">Previous</button>
          </fieldset>
      </form>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-01-18
        • 2012-05-21
        • 1970-01-01
        • 1970-01-01
        • 2019-11-12
        • 1970-01-01
        • 2019-02-03
        相关资源
        最近更新 更多