对一组复选框使用HTML5“required”属性?

时间:2011-06-02 18:11:56

标签: forms html5 validation checkbox

使用支持HTML5的新浏览器时(例如FireFox 4); 表单字段具有属性required='required';
表格字段为空/空白;
并单击提交按钮;
浏览器检测到“required”字段为空并且不提交表单;而是浏览器显示提示,要求用户在字段中键入文本。

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

如何在此组复选框上使用HTML5 required属性? (由于只需要检查其中一个复选框,我无法在每个复选框上添加required属性)

PS。如果重要,我正在使用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”更加明显。

14 个答案:

答案 0 :(得分:65)

不幸的是,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。 基于此,您可以实施验证检查。

答案 1 :(得分:13)

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

答案 2 :(得分:11)

我想没有标准的HTML5方法可以做到这一点,但是如果你不介意使用jQuery库,我已经能够使用webshims'“{{3来实现”复选框组“验证“验证功能:

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功能,但它也有一些很棒的可选扩展功能。

它甚至允许您编写自己的自定义有效性规则。例如,我需要创建一个不基于输入名称的复选框组,所以我写了docs for group-required ...

答案 3 :(得分:7)

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将确保至少选中一个复选框,然后取消整个复选框组。如果选中的一个复选框变为未选中状态,那么它将再次需要所有复选框!

答案 4 :(得分:3)

我遇到了同样的问题,我的解决方案是:

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/

答案 5 :(得分:2)

受到@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向导可以进一步收紧它们?

答案 6 :(得分:1)

嗨,只需使用复选框组旁边的文本框。当点击任何复选框时,将值放入该文本框。使该文本框成为必需和只读。

答案 7 :(得分:1)

我们也可以使用html5轻松完成此操作,只需要添加一些jquery代码

<强> Demo

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

答案 8 :(得分:1)

为此您不需要 jQuery。这是在复选框的父容器 (checkbox-group-required)、复选框元素的 .checked 属性和 Array#some 上使用事件侦听器的 vanilla JS 概念证明。

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>

答案 9 :(得分:0)

我在一组复选框中添加了一个不可见的收音机。 当至少一个选项被选中时,收音机也被设置为选中。 当所有选项都被取消时,收音机也被设置为取消。 因此,该表单使用单选提示“请检查至少一个选项”

  • 您无法使用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/

答案 10 :(得分:0)

我意识到这里有很多解决方案,但是我发现它们都无法满足我的所有要求:

  • 不需要自定义编码
  • 代码在页面加载时有效
  • 不需要自定义类(复选框或它们的父类)
  • 我需要多个复选框列表来共享相同的name以便通过其API提交Github问题,并且正在使用名称label[]在许多表单字段中分配标签(两个复选框列表和一些选择和文本框)-当然我可以做到这一点,而无需它们共享相同的名称,但是我决定尝试一下,并且有效。

对此的唯一要求是jQuery。您可以将其与@ewall的出色解决方案结合使用,以添加自定义验证错误消息。

/* required checkboxes */
(function ($) {
	$(function () {
		var $requiredCheckboxes = $("input[type='checkbox'][required]");

		/* init all checkbox lists */
		$requiredCheckboxes.each(function (i, el) {
			//this could easily be changed to suit different parent containers
			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);

			if ($checkboxList.find(cblNameAttr + ":checked").length > 0) {
				$checkboxes.prop("required", false);
			} else {
				$checkboxes.prop("required", true);
			}
		}

	});
})(jQuery);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<form method="post" action="post.php">
<div>
	Type of report:
</div>
<div>
	<input type="checkbox" id="chkTypeOfReportError" name="label[]" value="Error" required>
	<label for="chkTypeOfReportError">Error</label>

	<input type="checkbox" id="chkTypeOfReportQuestion" name="label[]" value="Question" required>
	<label for="chkTypeOfReportQuestion">Question</label>

	<input type="checkbox" id="chkTypeOfReportFeatureRequest" name="label[]" value="Feature Request" required>
	<label for="chkTypeOfReportFeatureRequest">Feature Request</label>
</div>

<div>
	Priority
</div>
<div>
	<input type="checkbox" id="chkTypeOfContributionBlog" name="label[]" value="Priority: High" required>
	<label for="chkPriorityHigh">High</label>


	<input type="checkbox" id="chkTypeOfContributionBlog" name="label[]" value="Priority: Medium" required>
	<label for="chkPriorityMedium">Medium</label>


	<input type="checkbox" id="chkTypeOfContributionLow" name="label[]" value="Priority: Low" required>
	<label for="chkPriorityMedium">Low</label>
</div>
<div>
	<input type="submit" />
</div>
</form>

答案 11 :(得分:0)

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

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

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

答案 12 :(得分:-1)

这是使用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");
    }
});

这就是全部...这是有效的,因为如果没有选中任何复选框,则关于复选框组(包括其名称)的任何内容都不会发布到服务器

答案 13 :(得分:-2)

尝试:

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