当使用支持HTML5的新浏览器时(例如FireFox 4); 表单字段有required='required'属性; 表单字段为空/空白; 然后点击提交按钮; 浏览器检测到“required”字段为空,不提交表单;相反,浏览器显示一个提示,要求用户在字段中输入文本。

现在,我有了一组复选框,而不是单一的文本字段,其中至少有一个应该由用户选中/选择。

如何在这组复选框上使用HTML5 required属性? (因为只有一个复选框需要被选中,我不能把所需的属性放在每个复选框上)

ps.我使用simple_form,如果这很重要。


更新

HTML 5的多重属性在这里有用吗?以前有人用它来做类似我的问题吗?

更新

HTML5规范似乎不支持这个特性:ISSUE-111:什么是输入?@type =复选框的@required mean ?

(发行状态:发行已被标记为已关闭。) 下面是解释。

更新2

这是一个老问题,但我想澄清的是,这个问题的最初意图是能够在不使用Javascript的情况下完成上述工作——即使用HTML5的方式来完成。回想起来,我应该更明显地说明“没有Javascript”。


当前回答

纯JS解决方案:

const group = document.querySelectorAll('[name="myCheckboxGroup"]');

function requireLeastOneChecked() {
    var atLeastOneChecked = false;
    for (i = 0; i < group.length; i++)
        if (group[i].checked)
            atLeastOneChecked = true;
    if (atLeastOneChecked)
        for (i = 0; i < group.length; i++)
            group[i].required = false;
    else
        for (i = 0; i < group.length; i++)
            group[i].required = true;
}
requireLeastOneChecked(); // onload

group.forEach(function ($el) {
    $el.addEventListener('click', function () { requireLeastOneChecked(); })
});

其他回答

Try:

self.request.get('sports_played', allow_multiple=True)

or

self.request.POST.getall('sports_played')

更具体地说:

当你从复选框数组中读取数据时,确保array具有:

len>0 

在这种情况下:

len(self.request.get('array', allow_multiple=True)) > 0

这是一个简单的技巧。这是jQuery代码,可以通过更改所需的属性来利用html5验证。下面是html代码(确保为组中的所有元素添加了required)。

<input type="checkbox" name="option[]" id="option-1" value="option1" required/> Option 1
<input type="checkbox" name="option[]" id="option-2" value="option2" required/> Option 2
<input type="checkbox" name="option[]" id="option-3" value="option3" required/> Option 3
<input type="checkbox" name="option[]" id="option-4" value="option4" required/> Option 4
<input type="checkbox" name="option[]" id="option-5" value="option5" required/> Option 5

下面是jQuery脚本,如果选择了任何一个,它将禁用进一步的验证检查。选择使用name元素。

$cbx_group = $("input:checkbox[name='option[]']");
$cbx_group = $("input:checkbox[id^='option-']"); // name is not always helpful ;)

$cbx_group.prop('required', true);
if($cbx_group.is(":checked")){
  $cbx_group.prop('required', false);
}

这里有个小问题:因为你正在使用html5验证,确保你在它得到验证之前执行这个,即在表单提交之前。

// but this might not work as expected
$('form').submit(function(){
  // code goes here
});

// So, better USE THIS INSTEAD:
$('button[type="submit"]').on('click', function() {
  // skipping validation part mentioned above
});

受到@thegauraw和@Brian Woodward的启发,我为JQuery用户收集了一些答案,其中包括一条自定义验证错误消息:

$cbx_group = $("input:checkbox[name^='group']");
$cbx_group.on("click", function () {
  if ($cbx_group.is(":checked")) {
    // checkboxes become unrequired as long as one is checked
    $cbx_group.prop("required", false).each(function () {
      this.setCustomValidity("");
    });
  } else {
    // require checkboxes and set custom validation error message
    $cbx_group.prop("required", true).each(function () {
      this.setCustomValidity("Please select at least one checkbox.");
    });
  }
});

注意,我的表单默认选中了一些复选框。

也许你们中的一些JavaScript/JQuery向导可以更严格地使用它?

这并不需要jQuery。这里是一个纯JS概念的证明,使用了一个事件监听器在复选框的父容器上(checkbox-group-required),复选框元素的.checked属性和array# some。

const validate = el => { const checkboxes = el.querySelectorAll('input[type="checkbox"]'); return [...checkboxes].some(e => e.checked); }; const formEl = document.querySelector("form"); const statusEl = formEl.querySelector(".status-message"); const checkboxGroupEl = formEl.querySelector(".checkbox-group-required"); checkboxGroupEl.addEventListener("click", e => { statusEl.textContent = validate(checkboxGroupEl) ? "valid" : "invalid"; }); formEl.addEventListener("submit", e => { e.preventDefault(); if (validate(checkboxGroupEl)) { statusEl.textContent = "Form submitted!"; // Send data from e.target to your backend } else { statusEl.textContent = "Error: select at least one checkbox"; } }); <form> <div class="checkbox-group-required"> <input type="checkbox"> <input type="checkbox"> <input type="checkbox"> <input type="checkbox"> </div> <input type="submit" /> <div class="status-message"></div> </form>

如果你有多个组要验证,在每个组上添加一个循环,可选地添加错误消息或CSS来指示哪个组验证失败:

const validate = el => { const checkboxes = el.querySelectorAll('input[type="checkbox"]'); return [...checkboxes].some(e => e.checked); }; const allValid = els => [...els].every(validate); const formEl = document.querySelector("form"); const statusEl = formEl.querySelector(".status-message"); const checkboxGroupEls = formEl.querySelectorAll(".checkbox-group-required"); checkboxGroupEls.forEach(el => el.addEventListener("click", e => { statusEl.textContent = allValid(checkboxGroupEls) ? "valid" : "invalid"; }) ); formEl.addEventListener("submit", e => { e.preventDefault(); if (allValid(checkboxGroupEls)) { statusEl.textContent = "Form submitted!"; } else { statusEl.textContent = "Error: select at least one checkbox from each group"; } }); <form> <div class="checkbox-group-required"> <label> Group 1: <input type="checkbox"> <input type="checkbox"> <input type="checkbox"> <input type="checkbox"> </label> </div> <div class="checkbox-group-required"> <label> Group 2: <input type="checkbox"> <input type="checkbox"> <input type="checkbox"> <input type="checkbox"> </label> </div> <input type="submit" /> <div class="status-message"></div> </form>

我也遇到过同样的问题,我的解决方案是这样的:

HTML:

<form id="processForm.php" action="post">
  <div class="input check_boxes required wish_payment_type">
    <div class="wish_payment_type">
    <span class="checkbox payment-radio">
      <label for="wish_payment_type_1">
        <input class="check_boxes required" id="wish_payment_type_1" name="wish[payment_type][]" type="checkbox" value="1">Foo
      </label>
    </span>
    <span class="checkbox payment-radio">
      <label for="wish_payment_type_2">
        <input class="check_boxes required" id="wish_payment_type_2" name="wish[payment_type][]" type="checkbox" value="2">Bar
      </label>
    </span>
    <span class="checkbox payment-radio">
      <label for="wish_payment_type_3">
        <input class="check_boxes required" id="wish_payment_type_3" name="wish[payment_type][]" type="checkbox" value="3">Buzz
      </label>
          
      <input id='submit' type="submit" value="Submit">
  </div>
</form>

JS:

var verifyPaymentType = function () {
  var checkboxes = $('.wish_payment_type .checkbox');
  var inputs = checkboxes.find('input');
  var first = inputs.first()[0];

  inputs.on('change', function () {
    this.setCustomValidity('');
  });

  first.setCustomValidity(checkboxes.find('input:checked').length === 0 ? 'Choose one' : '');
}

$('#submit').click(verifyPaymentType);

https://jsfiddle.net/oywLo5z4/