首页 文章

多个具有相同名称的复选框的必需属性? [1]

提问于
浏览
27

这个问题在这里已有答案:

我有一个具有相同名称属性的复选框列表,我需要验证其中至少有一个已被选中。

但是当我在所有这些属性上使用 html5 属性“required”时,浏览器(chrome&ff)不允许我提交表单,除非检查所有这些属性。

示例代码:

<label for="a-0">a-0</label>
<input type="checkbox" name="q-8" id="a-0" required />
<label for="a-1">a-1</label>
<input type="checkbox" name="q-8" id="a-1" required />
<label for="a-2">a-2</label>
<input type="checkbox" name="q-8" id="a-2" required />

当使用相同的无线电输入时,表单按预期工作(如果选择其中一个选项,表单验证)

根据Joe Hopfgartner(谁声称引用 html5 规范),假设的行为是:

对于复选框,只有在选中该表单中具有该名称的一个或多个复选框时,才能满足必需属性。

对于单选按钮,只有在检查该无线电组中的一个单选按钮时,才能满足所需属性。

我做错了什么,或者这是一个浏览器错误(在 chrome 和 ff 上)?

8 回答

  • 18

    对不起,现在我已经更好地阅读了您的期望,所以我正在更新答案。

    基于 W3C 的HTML5 规范,没有错。我创建了这个 JSFiddle 测试并且它的行为正确基于规格(对于那些基于规格的浏览器,如 Chrome 11 和 Firefox 4):

    <form>
        <input type="checkbox" name="q" id="a-0" required autofocus>
        <label for="a-0">a-1</label>
        <br>
    
        <input type="checkbox" name="q" id="a-1" required>
        <label for="a-1">a-2</label>
        <br>
    
        <input type="checkbox" name="q" id="a-2" required>
        <label for="a-2">a-3</label>
        <br>
    
        <input type="submit">
    </form>
    

    我同意它不是很有用(实际上很多人都在W3C 的邮件列表中抱怨过它)。

    但浏览器只是遵循标准的建议,这是正确的。标准有点误导,但在实践中我们无法做任何事情。 您可以随时使用 JavaScript 进行表单验证,但,就像一些优秀的 jQuery 验证插件。

    另一种方法是选择一个填充工具,它可以使(几乎)所有浏览器正确地解释表单验证。

  • 26

    你可以使用 jQuery 减少行数:

    $(function(){
    
        var requiredCheckboxes = $(':checkbox[required]');
    
        requiredCheckboxes.change(function(){
    
            if(requiredCheckboxes.is(':checked')) {
                requiredCheckboxes.removeAttr('required');
            }
    
            else {
                requiredCheckboxes.attr('required', 'required');
            }
        });
    
    });
    

    使用**$(':checkbox [13]')**您选择具有所需属性的所有复选框,然后,将.change 方法应用于此组复选框,您可以在此组的任何项目发生更改时执行所需的功能。在这种情况下,如果选中任何复选框,我将删除属于所选组的所有复选框的必需属性。

    我希望这有帮助。

    告别。

  • 6

    我有同样的问题,我的解决方案是将所需的属性应用于所有元素

    <input type="checkbox" name="checkin_days[]" required="required" value="0" /><span class="w">S</span>
    <input type="checkbox" name="checkin_days[]" required="required" value="1" /><span class="w">M</span>
    <input type="checkbox" name="checkin_days[]" required="required" value="2" /><span class="w">T</span>
    <input type="checkbox" name="checkin_days[]" required="required" value="3" /><span class="w">W</span>
    <input type="checkbox" name="checkin_days[]" required="required" value="4" /><span class="w">T</span>
    <input type="checkbox" name="checkin_days[]" required="required" value="5" /><span class="w">F</span>
    <input type="checkbox" name="checkin_days[]" required="required" value="6" /><span class="w">S</span>
    

    当用户检查其中一个元素时,我从所有元素中删除了所需的属性:

    var $checkedCheckboxes = $('#recurrent_checkin :checkbox[name="checkin_days[]"]:checked'),
        $checkboxes = $('#recurrent_checkin :checkbox[name="checkin_days[]"]');
    
    $checkboxes.click(function() {
    
    if($checkedCheckboxes.length) {
            $checkboxes.removeAttr('required');
        } else {
            $checkboxes.attr('required', 'required');
        }
    
     });
    
  • 4

    以下是 icova 答案的改进。它还按名称对输入进行分组。

    $(function(){
      var allRequiredCheckboxes = $(':checkbox[required]');
      var checkboxNames = [];
    
      for (var i = 0; i < allRequiredCheckboxes.length; ++i){
        var name = allRequiredCheckboxes[i].name;
        checkboxNames.push(name);
      }
    
      checkboxNames = checkboxNames.reduce(function(p, c) {
        if (p.indexOf(c) < 0) p.push(c);
        return p;
      }, []);
    
      for (var i in checkboxNames){
        !function(){
          var name = checkboxNames[i];
          var checkboxes = $('input[name="' + name + '"]');
          checkboxes.change(function(){
            if(checkboxes.is(':checked')) {
              checkboxes.removeAttr('required');
            } else {
              checkboxes.attr('required', 'required');
            }
          });
        }();
      }
    
    });
    
  • 4

    提供类似于@IvanCollantes 的答案的另一种方法。它的工作原理是按名称另外过滤所需的复选框。我也简化了代码。

    jQuery(document).ready(function($) {
      var requiredCheckboxes = $(':checkbox[required]');
      requiredCheckboxes.on('change', function(e) {
        var checkboxGroup = requiredCheckboxes.filter('[name="' + $(this).attr('name') + '"]');
        var isChecked = checkboxGroup.is(':checked');
        checkboxGroup.prop('required', !isChecked);
      });
    });
    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <form target="_blank">
      <p>
        At least one checkbox from each group is required...
      </p>
      <fieldset>
        <legend>Checkboxes Group test</legend>
        <label>
          <input type="checkbox" name="test[]" value="1" required="required">test-1
        </label>
        <label>
          <input type="checkbox" name="test[]" value="2" required="required">test-2
        </label>
        <label>
          <input type="checkbox" name="test[]" value="3" required="required">test-3
        </label>
      </fieldset>
      <br>
      <fieldset>
        <legend>Checkboxes Group test2</legend>
        <label>
          <input type="checkbox" name="test2[]" value="1" required="required">test2-1
        </label>
        <label>
          <input type="checkbox" name="test2[]" value="2" required="required">test2-2
        </label>
        <label>
          <input type="checkbox" name="test2[]" value="3" required="required">test2-3
        </label>
      </fieldset>
      <hr>
      <button type="submit" value="submit">Submit</button>
    </form>
    
  • 1

    一个小 jQuery 修复:

    $(function(){
        var chbxs = $(':checkbox[required]');
        var namedChbxs = {};
        chbxs.each(function(){
            var name = $(this).attr('name');
            namedChbxs[name] = (namedChbxs[name] || $()).add(this);
        });
        chbxs.change(function(){
            var name = $(this).attr('name');
            var cbx = namedChbxs[name];
            if(cbx.filter(':checked').length>0){
                cbx.removeAttr('required');
            }else{
                cbx.attr('required','required');
            }
        });
    });
    
  • 0

    基于 icova 的答案,这是代码,因此您可以使用自定义 HTML5 验证消息:

    $(function() {
        var requiredCheckboxes = $(':checkbox[required]');
        requiredCheckboxes.change(function() {
            if (requiredCheckboxes.is(':checked')) {requiredCheckboxes.removeAttr('required');}
            else {requiredCheckboxes.attr('required', 'required');}
        });
        $("input").each(function() {
            $(this).on('invalid', function(e) {
                e.target.setCustomValidity('');
                if (!e.target.validity.valid) {
                    e.target.setCustomValidity('Please, select at least one of these options');
                }
            }).on('input, click', function(e) {e.target.setCustomValidity('');});
        });
    });
    
  • 0
    var verifyPaymentType = function () {
       //coloque os checkbox dentro de uma div com a class checkbox
      var inputs =  window.jQuery('.checkbox').find('input');
      var first = inputs.first()[0];
    
      inputs.on('change', function () {
        this.setCustomValidity('');
      });
    
      first.setCustomValidity( window.jQuery('.checkbox').find('input:checked').length === 0 ? 'Choose one' : '');
    }
    
    window.jQuery('#submit').click(verifyPaymentType);
    
    }
    

相关问题