web-dev-qa-db-ja.com

同じ名前の複数のチェックボックスの必須属性?

チェックボックスのリスト同じ名前属性があり、少なくとも1つが選択されていることを検証する必要があります。

しかし、これらすべてでhtml5属性「必須」を使用すると、ブラウザ(chrome&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 />

ラジオ入力で同じものを使用する場合、フォームは期待どおりに機能します(オプションの1つが選択されている場合、フォームが検証します)

Joe Hopfgartner (html5仕様を引用すると主張している)によると、想定される動作は次のとおりです。

チェックボックスの場合、そのフォームでその名前のチェックボックスの1つ以上がチェックされている場合にのみ、必須属性が満たされます。

ラジオボタンの場合、必須属性は、そのラジオグループ内のラジオボタンの1つだけがチェックされている場合にのみ満たされます。

私は何か間違っているのですか、これはブラウザのバグですか(両方chrome&ff)??

30
anna.mi

申し訳ありませんが、今はあなたが期待しているものを読んでいるので、答えを更新しています。

W3Cの HTML5仕様 に基づくと、何も問題はありません。 この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>

私はそれがあまり有用ではないことに同意します(実際、多くの人々が W3Cのメーリングリスト でそれについて不満を言っています)。

しかし、ブラウザは標準の推奨事項に準拠しているだけであり、これは正しいです。この標準は少し誤解を招くかもしれませんが、実際にはそれについて何もできません。 優れたjQuery検証プラグインのように、フォームの検証には常にJavaScriptを使用できます

別のアプローチとしては、 polyfill を選択することで、(ほとんど)すべてのブラウザーがフォーム検証を正しく解釈できるようにします。

20

JQueryを使用して、より少ない行を作成できます。

$(function(){

    var requiredCheckboxes = $(':checkbox[required]');

    requiredCheckboxes.change(function(){

        if(requiredCheckboxes.is(':checked')) {
            requiredCheckboxes.removeAttr('required');
        }

        else {
            requiredCheckboxes.attr('required', 'required');
        }
    });

});

$( ':checkbox [required]')では、属性requiredを持つすべてのチェックボックスを選択します、次に、このグループのチェックボックスに。changeメソッドを適用して、functionこのグループは変更されます。この場合、チェックボックスのいずれかがチェックされている場合、選択したグループの一部であるすべてのチェックボックスのrequired属性を削除します。

これがお役に立てば幸いです。

別れ。

27
vantesllar

私は同じ問題を抱えていました、私の解決策は必要な属性をすべての要素に適用することでした

<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>

ユーザーが要素の1つをチェックすると、すべての要素から必要な属性が削除されます。

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

 });
6
Rommel Castro

@IvanCollantesによる答えに似た別のアプローチを提供する。必要なチェックボックスを名前で追加フィルタリングすることで機能します。また、コードを少し簡略化しました。

jQuery(document).ready(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);
  });
});
<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" 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
fyrye

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

});
4
Zhomart

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');
        }
    });
});
1
Yukulélé

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('');});
    });
});
0
OMA
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);

}
0
Marcos Alberton