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

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

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

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


更新

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

更新

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

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

更新2

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


当前回答

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

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/

其他回答

嗨,只是使用一个文本框附加组复选框。当单击任何复选框时,在该文本框中输入值。使该文本框必须和只读。

我在一组复选框中添加了一个隐形收音机。 当至少选中一个选项时,无线电也被设置为选中。 当所有选项都被取消时,收音机也被设置为取消。 因此,表单使用无线电提示“请至少选中一个选项”

你不能使用display: none,因为无线电不能聚焦。 我使单选字符的大小等于整个复选框的大小,这样在提示时就更明显了。

HTML

<form>
  <div class="checkboxs-wrapper">
    <input id="radio-for-checkboxes" type="radio" name="radio-for-required-checkboxes" required/>
    <input type="checkbox" name="option[]" value="option1"/>
    <input type="checkbox" name="option[]" value="option2"/>
    <input type="checkbox" name="option[]" value="option3"/>
  </div>
  <input type="submit" value="submit"/>
</form>

Javascript

var inputs = document.querySelectorAll('[name="option[]"]')
var radioForCheckboxes = document.getElementById('radio-for-checkboxes')
function checkCheckboxes () {
    var isAtLeastOneServiceSelected = false;
    for(var i = inputs.length-1; i >= 0; --i) {
        if (inputs[i].checked) isAtLeastOneCheckboxSelected = true;
    }
    radioForCheckboxes.checked = isAtLeastOneCheckboxSelected
}
for(var i = inputs.length-1; i >= 0; --i) {
    inputs[i].addEventListener('change', checkCheckboxes)
}

CSS

.checkboxs-wrapper {
  position: relative;
}
.checkboxs-wrapper input[name="radio-for-required-checkboxes"] {
    position: absolute;
    margin: 0;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    -webkit-appearance: none;
    pointer-events: none;
    border: none;
    background: none;
}

https://jsfiddle.net/codus/q6ngpjyc/9/

非常简单的方法来验证是否至少有一个复选框被选中:

function isAtLeastOneChecked(name) {
    let checkboxes = Array.from(document.getElementsByName(name));
    return checkboxes.some(e => e.checked);
}

然后,您可以实现想要显示错误的任何逻辑。

这并不需要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>

一个通用的解决方案,无需更改提交事件或知道复选框的名称

构建一个函数,将复选框标记为HTML5-Invalid 扩展Change-Event并在开始时检查有效性

jQuery.fn.getSiblingsCheckboxes = function () { let $this = $(this); let $parent = $this.closest('form, .your-checkbox-listwrapper'); return $parent.find('input[type="checkbox"][name="' + $this.attr('name')+'"]').filter('*[required], *[data-required]'); } jQuery.fn.checkRequiredInputs = function() { return this.each(function() { let $this = $(this); let $parent = $this.closest('form, .your-checkbox-list-wrapper'); let $allInputs = $this.getSiblingsCheckboxes(); if ($allInputs.filter(':checked').length > 0) { $allInputs.each(function() { // this.setCustomValidity(''); // not needed $(this).removeAttr('required'); $(this).closest('li').css('color', 'green'); // for debugging only }); } else { $allInputs.each(function() { // this.reportValidity(); // not needed $(this).attr('required', 'required'); $(this).closest('li').css('color', 'red'); // for debugging only }); } return true; }); }; $(document).ready(function() { $('input[type="checkbox"][required="required"], input[type="checkbox"][required]').not('*[data-required]').not('*[disabled]').each(function() { let $input = $(this); let $allInputs = $input.getSiblingsCheckboxes(); $input.attr('data-required', 'required'); $input.removeAttr('required'); $input.on('change', function(event) { $input.checkRequiredInputs(); }); }); $('input[type="checkbox"][data-required="required"]').checkRequiredInputs(); }); <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script> </head> <form> <ul> <li><input type="checkbox" id="checkbox1" name="countries" value="Argentina" required="required">Argentina</li> <li><input type="checkbox" id="checkbox2" name="countries" value="France" required="required">France</li> <li><input type="checkbox" id="checkbox3" name="countries" value="Germany" required="required">Germany</li> <li><input type="checkbox" id="checkbox4" name="countries" value="Japan" required="required">Japan</li> <li><input type="checkbox" id="checkbox5" name="countries" value="Australia" required="required">Australia</li> </ul> <input type="submit" value="Submit"> </form>