Требуемый атрибут в нескольких флажках с тем же именем?
У меня есть список флажков с тем же именем, и мне нужно проверить, что выбран хотя бы один из них.
Но когда я использую атрибут html5 "обязательно" для всех из них, браузер (хром и ff) не позволяет мне отправить форму, если все они не отмечены.
пример кода:
<label for="a-0">a-0</label>
<input type="checkbox" name="q-8" id="a-0" required />
<label for="a-1">a-1</label>
<input type="checkbox" name="q-8" id="a-1" required />
<label for="a-2">a-2</label>
<input type="checkbox" name="q-8" id="a-2" required />
При использовании этого же с радиовходами форма работает как ожидалось (если выбран один из параметров, форма проверяется)
Согласно Joe Hopfgartner (который утверждает, что цитирует спецификации html5), предполагаемое поведение:
Для флажков требуемый атрибут должен выполняться только тогда, когда отмечены один или несколько флажков с этим именем в этой форме.
Для радиокнопки требуемый атрибут должен выполняться только тогда, когда установлен один из переключателей в этой группе радио.
Я делаю что-то не так, или это ошибка браузера (на обоих хром и ff)??
Ответы
Ответ 1
Извините, теперь я прочитал то, что вы ожидали лучше, поэтому я обновляю ответ.
На основе характеристик HTML5 от W3C ничего не случилось. Я создал этот тест JSFiddle, и он корректно работает на основе спецификаций (для этих браузеров на основе спецификаций, таких как Chrome 11 и Firefox 4):
<form>
<input type="checkbox" name="q" id="a-0" required autofocus>
<label for="a-0">a-1</label>
<br>
<input type="checkbox" name="q" id="a-1" required>
<label for="a-1">a-2</label>
<br>
<input type="checkbox" name="q" id="a-2" required>
<label for="a-2">a-3</label>
<br>
<input type="submit">
</form>
Ответ 2
Вы можете сделать это с помощью jQuery меньше строк:
$(function(){
var requiredCheckboxes = $(':checkbox[required]');
requiredCheckboxes.change(function(){
if(requiredCheckboxes.is(':checked')) {
requiredCheckboxes.removeAttr('required');
}
else {
requiredCheckboxes.attr('required', 'required');
}
});
});
С помощью $(': checkbox [required]') вы выбираете все флажки с требуемым атрибутом, а затем с помощью метода .change, применяемого к этой группе флажков, вы можете выполнить функцию, которую вы хотите, если какой-либо элемент этой группы изменится. В этом случае, если установлен какой-либо из флажков, я удаляю требуемый атрибут для всех флажков, которые являются частью выбранной группы.
Надеюсь, это поможет.
Прощайте.
Ответ 3
У меня была та же проблема, мое решение применило требуемый атрибут ко всем элементам
<input type="checkbox" name="checkin_days[]" required="required" value="0" /><span class="w">S</span>
<input type="checkbox" name="checkin_days[]" required="required" value="1" /><span class="w">M</span>
<input type="checkbox" name="checkin_days[]" required="required" value="2" /><span class="w">T</span>
<input type="checkbox" name="checkin_days[]" required="required" value="3" /><span class="w">W</span>
<input type="checkbox" name="checkin_days[]" required="required" value="4" /><span class="w">T</span>
<input type="checkbox" name="checkin_days[]" required="required" value="5" /><span class="w">F</span>
<input type="checkbox" name="checkin_days[]" required="required" value="6" /><span class="w">S</span>
когда пользователь проверяет один из элементов, я удаляю требуемый атрибут из всех элементов:
var $checkedCheckboxes = $('#recurrent_checkin :checkbox[name="checkin_days[]"]:checked'),
$checkboxes = $('#recurrent_checkin :checkbox[name="checkin_days[]"]');
$checkboxes.click(function() {
if($checkedCheckboxes.length) {
$checkboxes.removeAttr('required');
} else {
$checkboxes.attr('required', 'required');
}
});
Ответ 4
Чтобы обеспечить другой подход, похожий на ответ @IvanCollantes.
Он работает путем дополнительной фильтрации необходимых флажков по имени. Я также немного упростил код и установил флажок по умолчанию checked
.
jQuery(function($) {
var requiredCheckboxes = $(':checkbox[required]');
requiredCheckboxes.on('change', function(e) {
var checkboxGroup = requiredCheckboxes.filter('[name="' + $(this).attr('name') + '"]');
var isChecked = checkboxGroup.is(':checked');
checkboxGroup.prop('required', !isChecked);
});
requiredCheckboxes.trigger('change');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form target="_blank">
<p>
At least one checkbox from each group is required...
</p>
<fieldset>
<legend>Checkboxes Group test</legend>
<label>
<input type="checkbox" name="test[]" value="1" checked="checked" required="required">test-1
</label>
<label>
<input type="checkbox" name="test[]" value="2" required="required">test-2
</label>
<label>
<input type="checkbox" name="test[]" value="3" required="required">test-3
</label>
</fieldset>
<br>
<fieldset>
<legend>Checkboxes Group test2</legend>
<label>
<input type="checkbox" name="test2[]" value="1" required="required">test2-1
</label>
<label>
<input type="checkbox" name="test2[]" value="2" required="required">test2-2
</label>
<label>
<input type="checkbox" name="test2[]" value="3" required="required">test2-3
</label>
</fieldset>
<hr>
<button type="submit" value="submit">Submit</button>
</form>
Ответ 5
Вот улучшение для ответа icova. Он также группирует входы по имени.
$(function(){
var allRequiredCheckboxes = $(':checkbox[required]');
var checkboxNames = [];
for (var i = 0; i < allRequiredCheckboxes.length; ++i){
var name = allRequiredCheckboxes[i].name;
checkboxNames.push(name);
}
checkboxNames = checkboxNames.reduce(function(p, c) {
if (p.indexOf(c) < 0) p.push(c);
return p;
}, []);
for (var i in checkboxNames){
!function(){
var name = checkboxNames[i];
var checkboxes = $('input[name="' + name + '"]');
checkboxes.change(function(){
if(checkboxes.is(':checked')) {
checkboxes.removeAttr('required');
} else {
checkboxes.attr('required', 'required');
}
});
}();
}
});
Ответ 6
Небольшое исправление jQuery:
$(function(){
var chbxs = $(':checkbox[required]');
var namedChbxs = {};
chbxs.each(function(){
var name = $(this).attr('name');
namedChbxs[name] = (namedChbxs[name] || $()).add(this);
});
chbxs.change(function(){
var name = $(this).attr('name');
var cbx = namedChbxs[name];
if(cbx.filter(':checked').length>0){
cbx.removeAttr('required');
}else{
cbx.attr('required','required');
}
});
});
Ответ 7
Основываясь на ответ icova, здесь код, чтобы вы могли использовать собственное сообщение проверки HTML5:
$(function() {
var requiredCheckboxes = $(':checkbox[required]');
requiredCheckboxes.change(function() {
if (requiredCheckboxes.is(':checked')) {requiredCheckboxes.removeAttr('required');}
else {requiredCheckboxes.attr('required', 'required');}
});
$("input").each(function() {
$(this).on('invalid', function(e) {
e.target.setCustomValidity('');
if (!e.target.validity.valid) {
e.target.setCustomValidity('Please, select at least one of these options');
}
}).on('input, click', function(e) {e.target.setCustomValidity('');});
});
});
Ответ 8
var verifyPaymentType = function () {
//coloque os checkbox dentro de uma div com a class checkbox
var inputs = window.jQuery('.checkbox').find('input');
var first = inputs.first()[0];
inputs.on('change', function () {
this.setCustomValidity('');
});
first.setCustomValidity( window.jQuery('.checkbox').find('input:checked').length === 0 ? 'Choose one' : '');
}
window.jQuery('#submit').click(verifyPaymentType);
}