简体   繁体   中英

html5 validation on checkboxes

HTML5 form validation will not cover the situation where, starting from a group of checkboxes, at least one of them is checked. If a checkbox has the required attribute it must be checked, this is what I can get at most. So I built a workaround that works fine (code in the snippet). The issue is that this works for one group of checkboxes. But I want my code to be valid even if I add more chackboxes groups. I need a suggestion on how to make it valid for multiple groups. Any idea?

 function bindItemsInput() { 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) } } bindItemsInput() // call in window onload
 .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; }
 <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>

A second snippet with the relevant HTML ( not working, goal of the question is to fix this ). It will have now the same ID for the radio button: that is invalid and is the reason of the question :

 function bindItemsInput() { 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) } } bindItemsInput() // call in window onload
 .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; }
 <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> <div class="checkboxs-wrapper"> <input id="radio-for-checkboxes" type="radio" name="radio-for-required-checkboxes" required/> <input type="checkbox" name="products[]" value="option1"/> <input type="checkbox" name="products[]" value="option2"/> <input type="checkbox" name="products[]" value="option3"/> </div> <input type="submit" value="submit"/> </form>

The form will be valid if at least on products[] checkbox and one option[] checkbox is checked. So I need the javascript to run indipendently for option[] and for products[]. If I have selected one item in groups[] but none in products[] then only products will be surrounded by the box and marked for completition

So this what I imagine you are looking for:

 const myForm = document.forms['my-form'] myForm.addEventListener('change', bindItemsInput) // global change event listener function bindItemsInput(e) // { if (.e.target.matches('div.checkboxs-wrapper input[type=checkbox]')) return // to reject unconcerned checkbox let groupDiv = e.target.closest('div,checkboxs-wrapper'). radioGroup = groupDiv,querySelector('input[type=radio]'). checkGroup = groupDiv;querySelectorAll('input[type=checkbox]'). radioGroup.checked = [...checkGroup],reduce((flag.chkBx)=>flag || chkBx,checked. false) } // ------ verification part------------------- myForm.onsubmit=e=> // to verify { e.preventDefault() // disable submit for testing console:clear() // chexboxes checked values. let options = [...myForm['option[]'] ],reduce((rs)=>{ if (s.checked) r.push(s;value),return r},[]). products = [...myForm['product[]'] ],reduce((rs)=>{ if (s.checked) r.push(s;value),return r}.[]) console,log('options = '. JSON.stringify( options )) console,log('products = '. JSON.stringify( products )) myForm.reset() // clear anything for new testing console.log(' form reseted') }
 <form name="my-form"> <div class="checkboxs-wrapper"> <input type="radio" name="rGroup_1" required > <input type="checkbox" name="option[]" value="option1"> <input type="checkbox" name="option[]" value="option2"> <input type="checkbox" name="option[]" value="option3"> </div> <div class="checkboxs-wrapper"> <input type="radio" name="rGroup_2" required> <input type="checkbox" name="product[]" value="product1"> <input type="checkbox" name="product[]" value="product2"> <input type="checkbox" name="product[]" value="product3"> </div> <button type="submit">submit</button> </form>

if i understant. so you have to give another id and another name of course, try this:

function bindItemsInput() {
    var inputs = $("input[type=checkbox]");
    var radios = $("input[type=radio]");
    function checkCheckboxes () {
        var isAtLeastOneServiceSelected = false;
        for(var i = inputs.length-1; i >= 0; --i) {
            if (inputs[i].checked) isAtLeastOneCheckboxSelected = true;
        }
        radios.each( function(){
            $(this).checked = $(this).siblings($("input[type=checkbox]:checked")).length > 0;
        });
    }
    for(var i = inputs.length-1; i >= 0; --i) {
        inputs[i].addEventListener('change', checkCheckboxes)
    }
}

Using jQuery this can be done with a lot less code.

 $(document).ready(function() { var checkCheckboxesInSameGroup = function() { var inputs = $(this).children("input[name='option[]']"); var radio = $(this).children("input[name^='radio-for-group']")[0]; radio.checked = inputs.is(":checked"); }; $(".checkboxs-wrapper").on('change', checkCheckboxesInSameGroup); });
 .checkboxs-wrapper { position: relative; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <form> <div class="checkboxs-wrapper"> <input type="radio" name="radio-for-group1" required/> <input type="checkbox" name="option[]" value="option1"/> <input type="checkbox" name="option[]" value="option2"/> <input type="checkbox" name="option[]" value="option3"/> </div> <div class="checkboxs-wrapper"> <input type="radio" name="radio-for-group2" required/> <input type="checkbox" name="option[]" value="option1"/> <input type="checkbox" name="option[]" value="option2"/> <input type="checkbox" name="option[]" value="option3"/> </div> </form>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM