jQuery多步骤表单:取消选中字段时禁用下一个按钮

时间:2018-03-15 16:07:21

标签: javascript jquery html css forms

我有一个多步骤表单,在表单的每一步都有一个“下一步”和“后退”按钮。一旦满足每个部分的标准,我就使用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);
    }
});

有没有办法让这项工作?

3 个答案:

答案 0 :(得分:1)

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

所以你的代码中的比较: $('.panels input:checked').length >= 1

需要改为: $(this).parent().find('input:checked').length >= 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>

答案 1 :(得分:1)

当您选择输入以查看是否已选中时,您正在选择所有输入

if ($('.panels input:checked').length >= 1) {

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

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

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

答案 2 :(得分:0)

我认为使用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); } });级别的event delegation来处理互动非常有趣,这更灵活:

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

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>
    private void setProgramDataToView(Programme programme, TextView textView) {
        textView.setText(getEPGText(programme));
        textView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                Rect r = new Rect();
                boolean v = textView.getLocalVisibleRect(r);
                textView.setFocusable(v);
                textView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            }
        });

        ViewGroup.LayoutParams layoutParams = textView.getLayoutParams();
        layoutParams.width = timeLineHelper.getDurationProgram(programme);
        textView.setLayoutParams(layoutParams);
    }