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

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

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

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


更新

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

更新

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

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

更新2

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


当前回答

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

你不能使用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/

其他回答

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

这是一个简单的技巧。这是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
});

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

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

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

纯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(); })
});

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

构建一个函数,将复选框标记为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>