需要在多个复选框上使用相同的名称?(复制)

时间:2022-11-27 23:40:37

This question already has an answer here:

这个问题已经有了答案:

I have a list of checkboxes with the same name attribute, and I need to validate that at least one of them has been selected.

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

But when I use the html5 attribute "required" on all of them, the browser (chrome & ff) doesn't allow me to submit the form unless all of them are checked.

但是当我使用html5属性“required”时,浏览器(chrome & ff)不允许我提交表单,除非所有表单都被选中。

sample code:

示例代码:

<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 />

When using the same with radio inputs, the form works as expected (if one of the options is selected the form validates)

当对无线电输入使用相同的格式时,表单将按预期工作(如果选择了其中一个选项,表单将生效)

According to Joe Hopfgartner (who claims to quote the html5 specs), the supposed behaviour is:

根据Joe Hopfgartner(他声称引用了html5规范)的说法,假定的行为是:

For checkboxes, the required attribute shall only be satisfied when one or more of the checkboxes with that name in that form are checked.

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

For radio buttons, the required attribute shall only be satisfied when exactly one of the radio buttons in that radio group is checked.

对于单选按钮,只有当选中该单选组中的一个单选按钮时,才能满足所需要的属性。

am i doing something wrong, or is this a browser bug (on both chrome & ff) ??

我做错了什么,还是这是浏览器的错误(在chrome和ff上)?

8 个解决方案

#1


15  

Sorry, now I've read what you expected better, so I'm updating the answer.

对不起,现在我已经读了你想要的,所以我在更新答案。

Based on the HTML5 Specs from W3C, nothing is wrong. I created this JSFiddle test and it's behaving correctly based on the specs (for those browsers based on the specs, like Chrome 11 and Firefox 4):

基于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>

I agree that it isn't very usable (in fact many people have complained about it in the W3C's mailing lists).

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

But browsers are just following the standard's recommendations, which is correct. The standard is a little misleading, but we can't do anything about it in practice. You can always use JavaScript for form validation, though, like some great jQuery validation plugin.

但是浏览器只是遵循标准的建议,这是正确的。这个标准有点误导人,但实际上我们不能做任何事。不过,您可以使用JavaScript进行表单验证,就像一些很棒的jQuery验证插件一样。

Another approach would be choosing a polyfill that can make (almost) all browsers interpret form validation rightly.

另一种方法是选择一个可以使(几乎)所有浏览器正确解释表单验证的polyfill。

#2


24  

You can make it with jQuery a less lines:

你可以用jQuery少写几行:

$(function(){

    var requiredCheckboxes = $(':checkbox[required]');

    requiredCheckboxes.change(function(){

        if(requiredCheckboxes.is(':checked')) {
            requiredCheckboxes.removeAttr('required');
        }

        else {
            requiredCheckboxes.attr('required', 'required');
        }
    });

});

With $(':checkbox[required]') you select all checkboxes with the attribute required, then, with the .change method applied to this group of checkboxes, you can execute the function you want when any item of this group changes. In this case, if any of the checkboxes is checked, I remove the required attribute for all of the checkboxes that are part of the selected group.

使用$(':checkbox[required]'),您可以选择所需属性的所有复选框,然后,使用.change方法应用于这组复选框,您可以在该组的任何项更改时执行您想要的功能。在这种情况下,如果选中了任何一个复选框,我将移除作为所选组一部分的所有复选框的必需属性。

I hope this helps.

我希望这可以帮助。

Farewell.

告别。

#3


5  

i had the same problem, my solution was apply the required attribute to all elements

我遇到了同样的问题,我的解决方案是对所有元素应用required属性

<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>

when the user check one of the elements i remove the required attribute from all elements:

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

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


4  

Here is improvement for icova's answer. It also groups inputs by name.

以下是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');
        }
      });
    }();
  }

});

#5


2  

To provide another approach similar to the answer by @IvanCollantes. It works by additionally filtering the required checkboxes by name. I also simplified the code a bit.

提供与@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>

#6


1  

A little jQuery fix:

一个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');
        }
    });
});

#7


0  

Building on icova's answer, here's the code so you can use a custom HTML5 validation message:

基于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('');});
    });
});

#8


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);

}

#1


15  

Sorry, now I've read what you expected better, so I'm updating the answer.

对不起,现在我已经读了你想要的,所以我在更新答案。

Based on the HTML5 Specs from W3C, nothing is wrong. I created this JSFiddle test and it's behaving correctly based on the specs (for those browsers based on the specs, like Chrome 11 and Firefox 4):

基于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>

I agree that it isn't very usable (in fact many people have complained about it in the W3C's mailing lists).

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

But browsers are just following the standard's recommendations, which is correct. The standard is a little misleading, but we can't do anything about it in practice. You can always use JavaScript for form validation, though, like some great jQuery validation plugin.

但是浏览器只是遵循标准的建议,这是正确的。这个标准有点误导人,但实际上我们不能做任何事。不过,您可以使用JavaScript进行表单验证,就像一些很棒的jQuery验证插件一样。

Another approach would be choosing a polyfill that can make (almost) all browsers interpret form validation rightly.

另一种方法是选择一个可以使(几乎)所有浏览器正确解释表单验证的polyfill。

#2


24  

You can make it with jQuery a less lines:

你可以用jQuery少写几行:

$(function(){

    var requiredCheckboxes = $(':checkbox[required]');

    requiredCheckboxes.change(function(){

        if(requiredCheckboxes.is(':checked')) {
            requiredCheckboxes.removeAttr('required');
        }

        else {
            requiredCheckboxes.attr('required', 'required');
        }
    });

});

With $(':checkbox[required]') you select all checkboxes with the attribute required, then, with the .change method applied to this group of checkboxes, you can execute the function you want when any item of this group changes. In this case, if any of the checkboxes is checked, I remove the required attribute for all of the checkboxes that are part of the selected group.

使用$(':checkbox[required]'),您可以选择所需属性的所有复选框,然后,使用.change方法应用于这组复选框,您可以在该组的任何项更改时执行您想要的功能。在这种情况下,如果选中了任何一个复选框,我将移除作为所选组一部分的所有复选框的必需属性。

I hope this helps.

我希望这可以帮助。

Farewell.

告别。

#3


5  

i had the same problem, my solution was apply the required attribute to all elements

我遇到了同样的问题,我的解决方案是对所有元素应用required属性

<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>

when the user check one of the elements i remove the required attribute from all elements:

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

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


4  

Here is improvement for icova's answer. It also groups inputs by name.

以下是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');
        }
      });
    }();
  }

});

#5


2  

To provide another approach similar to the answer by @IvanCollantes. It works by additionally filtering the required checkboxes by name. I also simplified the code a bit.

提供与@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>

#6


1  

A little jQuery fix:

一个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');
        }
    });
});

#7


0  

Building on icova's answer, here's the code so you can use a custom HTML5 validation message:

基于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('');});
    });
});

#8


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);

}