使用支持 HTML5 的较新浏览器时(例如 FireFox 4);
并且表单字段具有属性 required='required'
;
并且表单字段为空/空白;
并且单击提交按钮;
浏览器检测到“必填”字段为空,因此不提交表单;
相反,浏览器显示提示,要求用户在字段中输入文本。
现在,我有一组复选框,而不是单个文本字段,其中至少一个应该由用户检查/选择。
如何在这组复选框上使用 HTML5 required
属性? (由于只需要选中一个复选框,我不能将 required
属性放在每个复选框上)
附言。如果这很重要,我正在使用 simple_form。
更新
HTML 5 multiple
attribute 在这里有用吗?有没有人用它来做类似于我的问题的事情?
更新
HTML5 规范不支持此功能似乎: ISSUE-111: What does input.@required mean for @type = checkbox?
(问题状态:问题已被标记为已关闭且无偏见。)还有 here is the explanation。
更新 2
这是一个老问题,但想澄清这个问题的初衷是能够在不使用 Javascript 的情况下完成上述操作 - 即使用 HTML5 方式来完成。回想起来,我应该让“没有 Javascript”更明显。
不幸的是,HTML5 没有提供开箱即用的方法来做到这一点。
但是,使用 jQuery,您可以轻松控制复选框组是否具有至少一个选中元素。
考虑以下 DOM 片段:
<div class="checkbox-group required">
<input type="checkbox" name="checkbox_name[]">
<input type="checkbox" name="checkbox_name[]">
<input type="checkbox" name="checkbox_name[]">
<input type="checkbox" name="checkbox_name[]">
</div>
你可以使用这个表达式:
$('div.checkbox-group.required :checkbox:checked').length > 0
如果至少检查了一个元素,则返回 true
。基于此,您可以实施验证检查。
这是一个简单的技巧。这是 jQuery 代码,如果选中任何一个,则可以通过更改 required
属性来利用 html5 验证。以下是您的 html 代码(确保为组中的所有元素添加必需的。)
<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 脚本,如果选择了任何一个,它将禁用进一步的验证检查。使用名称元素选择。
$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
});
HTML5 不直接支持要求在一个复选框组中只选中一个/至少一个复选框。这是我使用 Javascript 的解决方案:
HTML
<input class='acb' type='checkbox' name='acheckbox[]' value='1' onclick='deRequire("acb")' required> One
<input class='acb' type='checkbox' name='acheckbox[]' value='2' onclick='deRequire("acb")' required> Two
JAVASCRIPT
function deRequireCb(elClass) {
el = document.getElementsByClassName(elClass);
var atLeastOneChecked = false; //at least one cb is checked
for (i = 0; i < el.length; i++) {
if (el[i].checked === true) {
atLeastOneChecked = true;
}
}
if (atLeastOneChecked === true) {
for (i = 0; i < el.length; i++) {
el[i].required = false;
}
} else {
for (i = 0; i < el.length; i++) {
el[i].required = true;
}
}
}
javascript 将确保至少选中一个复选框,然后取消需要整个复选框组。如果选中的一个复选框变为未选中,那么它将再次需要所有复选框!
i
和 el
之类的变量污染了窗口,在运算符周围没有使用适当的间距,使用过时的成语并且在条件中具有诸如 === true
之类的分散注意力的冗长。
我想没有标准的 HTML5 方法可以做到这一点,但如果你不介意使用 jQuery 库,我已经能够使用 webshims' "group-required" 验证功能实现“复选框组”验证:
如果复选框具有“group-required”类,则必须选中表单/文档中至少一个具有相同名称的复选框。
这是一个如何使用它的示例:
<input name="checkbox-group" type="checkbox" class="group-required" id="checkbox-group-id" />
<input name="checkbox-group" type="checkbox" />
<input name="checkbox-group" type="checkbox" />
<input name="checkbox-group" type="checkbox" />
<input name="checkbox-group" type="checkbox" />
我主要使用 webshims 来填充 HTML5 功能,但它也有一些很棒的可选扩展,比如这个。
它甚至允许您编写自己的自定义有效性规则。例如,我需要创建一个不基于输入名称的复选框组,所以我写了 my own validity rule for that...
我们也可以用 html5 轻松做到这一点,只需要添加一些 jquery 代码
HTML
<form>
<div class="form-group options">
<input type="checkbox" name="type[]" value="A" required /> A
<input type="checkbox" name="type[]" value="B" required /> B
<input type="checkbox" name="type[]" value="C" required /> C
<input type="submit">
</div>
</form>
jQuery
$(function(){
var requiredCheckboxes = $('.options :checkbox[required]');
requiredCheckboxes.change(function(){
if(requiredCheckboxes.is(':checked')) {
requiredCheckboxes.removeAttr('required');
} else {
requiredCheckboxes.attr('required', 'required');
}
});
});
受到@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 向导可以进一步加强这一点?
我在一组复选框中添加了一个不可见的收音机。当至少一个选项被选中时,收音机也被设置为选中。当所有选项都被取消时,收音机也被设置为取消。因此,表单使用单选提示“请检查至少一个选项”
您不能使用 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/
radio
的opacity
设置为0,提交时将opacity
设置为1,这样我们就可以控制是否出现红色轮廓。
visibility: hidden
或 display: none
只是为了避免使可用性有点脏,它不起作用。因为屏幕阅读器和其他辅助工具可能会找到隐藏的单选按钮。
我有同样的问题,我的解决方案是这样的:
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/
inputs.on('change', function () { this.setCustomValidity(''); });
没用 jsfiddle.net/d8r2146j
$('#submit').click(verifyPaymentType);
这很明显是错误的,而且很多后辈都会这样做,这对我来说取消了整个答案的资格。请始终收听表单的提交事件。
为此,您不需要 jQuery。这是一个 vanilla JS 概念证明,它使用复选框的父容器 (checkbox-group-required
)、复选框元素的 .checked
属性和 Array#some
上的事件侦听器。
const validate = el => { const checkboxes = el.querySelectorAll('input[type="checkbox"]');返回 [...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 submit!"; // 将数据从 e.target 发送到您的后端 } else { statusEl.textContent = "错误:至少选择一个复选框"; } });
如果您有多个要验证的组,请在每个组上添加一个循环,可选择添加错误消息或 CSS 以指示哪个组未通过验证:
const validate = el => { const checkboxes = el.querySelectorAll('input[type="checkbox"]');返回 [...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 = "表单提交!"; } else { statusEl.textContent = "错误:至少选择一个每个组的复选框"; } });
allValid(checkboxGroupEls)
为真,如何继续提交?我有一个 action: action="includes/action.php"
in form
e.preventDefault()
。
我意识到这里有很多解决方案,但我发现它们都没有满足我的所有要求:
无需自定义编码
代码适用于页面加载
不需要自定义类(复选框或其父级)
我需要几个复选框列表来共享相同的名称,以便通过他们的 API 提交 Github 问题,并且使用名称 label[] 在许多表单字段(两个复选框列表和一些选择和文本框)之间分配标签 - 我本可以实现这没有他们共享相同的名字,但我决定尝试一下,它奏效了。
这个唯一的要求是jQuery。您可以将此与@ewall 的出色解决方案结合使用,以添加自定义验证错误消息。
/* 必需的复选框 */ jQuery(function ($) { var $requiredCheckboxes = $("input[type='checkbox'][required]"); /* 初始化所有复选框列表 */ $requiredCheckboxes.each(function (i , el) { //this 可以很容易地改变以适应不同的父容器 var $checkboxList = $(this).closest("div, span, p, ul, td"); if (!$checkboxList.hasClass("requiredCheckboxList ")) $checkboxList.addClass("requiredCheckboxList"); }); var $requiredCheckboxLists = $(".requiredCheckboxList"); $requiredCheckboxLists.each(function (i, el) { var $checkboxList = $(this); $ checkboxList.on("change", "input[type='checkbox']", function (e) { updateCheckboxesRequired($(this).parents(".requiredCheckboxList")); }); updateCheckboxesRequired($checkboxList); } ); function updateCheckboxesRequired($checkboxList) { var $chk = $checkboxList.find("input[type='checkbox']").eq(0), cblName = $chk.attr("name"), cblNameAttr = " [name='" + cblName + "']", $checkboxes = $checkboxList.find("input[type='checkbox']" + cblNameAttr); 如果($checkboxList.find(cblNameAttr + ":checked").length > 0) { $checkboxes.prop("required", false); } else { $checkboxes.prop("必需", true); } } });
嗨,只需在复选框组之外使用一个文本框。单击任何复选框时,将值放入该文本框。使该文本框为必需且只读。
验证是否至少选中一个复选框的非常简单的方法:
function isAtLeastOneChecked(name) {
let checkboxes = Array.from(document.getElementsByName(name));
return checkboxes.some(e => e.checked);
}
然后你可以实现任何你想显示错误的逻辑。
这是另一个使用 Jquery 的简单技巧! HTML
<form id="hobbieform">
<div>
<input type="checkbox" name="hobbies[]">Coding
<input type="checkbox" name="hobbies[]">Gaming
<input type="checkbox" name="hobbies[]">Driving
</div>
</form>
jQuery
$('#hobbieform').on("submit", function (e) {
var arr = $(this).serialize().toString();
if(arr.indexOf("hobbies") < 0){
e.preventDefault();
alert("You must select at least one hobbie");
}
});
仅此而已..这是可行的,因为如果未选中任何复选框,则不会将有关复选框组(包括其名称)的任何内容发布到服务器
尝试:
self.request.get('sports_played', allow_multiple=True)
或者
self.request.POST.getall('sports_played')
进一步来说:
当您从复选框数组中读取数据时,请确保数组具有:
len>0
在这种情况下:
len(self.request.get('array', allow_multiple=True)) > 0
setCustomValidity
stackoverflow.com/a/30222924 的最佳实现