2011-05-04 119 views
23

我有一個複選框的列表屬性,我需要驗證其中至少有一個已被選中。具有相同名稱的多個複選框的必需屬性?

但是,當我在所有這些html5屬性「required」上使用時,瀏覽器(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 /> 

當使用相同的無線電輸入,形式按預期方式工作(如果其中一個選項被選擇的形式將驗證)

根據Joe Hopfgartner(誰聲稱引用html5規範),假定的行爲是:

對於複選框,只有當一個或多個具有該名稱的複選框在在形式被檢查。

對於單選按鈕,只有當該無線電組中的一個單選按鈕被選中時,才能滿足所需的屬性。

我做錯了什麼,或者這是一個瀏覽器錯誤(在這兩個鉻& ff)?

+3

可能更簡單(並向下兼容)使用JavaScript和jQuery來驗證您的複選框。 – Nathan 2011-05-04 14:01:31

+0

你沒有關閉你的標籤標籤 – 2011-05-04 14:04:07

+0

@tom gullen,你是對的,壞的複製粘貼!即時更正在問題tnx – 2011-05-04 14:22:11

回答

12

對不起,現在我已經讀了你期望的更好,所以我正在更新答案。

基於來自W3C的HTML5 Specs,沒有什麼是錯的。我創建this JSFiddle test,它的表現的基礎上正確的規格(基於規格的瀏覽器,如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's mailing lists中抱怨過)。

但瀏覽器只是遵循標準的建議,這是正確的。該標準有點誤導性,但我們在實踐中無法做任何事情。 您可以隨時使用JavaScript進行表單驗證,雖然就像一些很棒的jQuery驗證插件。

另一種方法是選擇一個polyfill,它可以使(幾乎)所有瀏覽器都正確地解釋表單驗證。

+0

Erick,HTML5中的哪些語句使您認爲即使它們在一個組中(即具有相同的名稱),所需的屬性也支配每個單獨的複選框?我無法發現它明確指出了某種方式或另一種方式。 – 2011-10-14 12:30:30

+0

Chrome 26和Firefox 20要求在鏈接的jsFiddle http://jsfiddle.net/ErickPetru/kXsj9/6/ – 2013-04-09 09:36:07

+1

@ John-Philip上檢查所有複選框,當然!完全像我在我的回答中所說的,並且像[規格](http://dev.w3.org/html5/markup/input.checkbox.html#input.checkbox.attrs.required)所說的那樣:「**元素* *是表單提交的必需部分「,'required'屬性適用於每個元素,但不適用於元素組。不是一件非常有用的東西,而是它在規格中的意思。 – 2013-04-09 17:16:44

4

我有同樣的問題,我的解決方案是必要的屬性適用於所有元素

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

}); 
+1

該名稱不應包含括號,但最重要的是,這是一個不好的解決方案,因爲您的語義與邏輯矛盾。以前的答案是更正確的方式,但如果你想要一個jQuery的polyfill版本試試這個SO問題:http://stackoverflow.com/questions/1535187/jquery-validate-form-with-multiple-checkboxes-at-least-one - 必須被檢查 – 2013-04-09 09:32:35

1

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

你可以使用jQuery少一行:

$(function(){ 

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

    requiredCheckboxes.change(function(){ 

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

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

}); 

隨着$( ':複選框[需要]')選擇與所需,則屬性所有複選框,與施加到該組的複選框的.change方法,則可以執行該組的任何項目更改時所需的功能。在這種情況下,如果選中任何複選框,我將刪除屬於所選組的所有複選框的所需的屬性。

我希望這會有所幫助。

告別。

+1

太棒了!我認爲可以在.change(...)旁邊添加.trigger('change')以確保規則在沒有輸入點擊的情況下有效。 – userlond 2016-01-27 07:20:39

3

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

}); 
+0

非常感謝。你救了我5個多小時。這種解決方案適用於所有使用多個複選框的用戶。 – 2016-06-19 14:48:14

+0

可以指導我如何更改錯誤消息?就好像我使用無效這會被打破。 – 2016-06-19 15:40:45

0

上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

無論如何,如果有多個複選框在同一頁面上存在,那麼這個工作是否有效? – 2016-06-23 17:43:52

0
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); 

} 
2

提供類似於@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>

+0

你有任何想法如何使用我們自己的消息覆蓋彈出的默認消息? – 2016-06-24 09:21:41

+0

@VivekSancheti請參閱http://stackoverflow.com/questions/5272433/html5-form-required-attribute-set-custom-validation-message – fyrye 2016-06-28 15:29:08

+0

這是行不通的。 http://stackoverflow.com/q/38069634/5278270我試過了,併發布了這個問題。 – 2016-06-29 10:35:57

相關問題