简体   繁体   中英

How to validate required checkboxlists when each property's value of them is dymanic using JavaScript?

Below is my form with two groups of checkboxlist.

<form id="my-form">

    <input type="checkbox" class="unknown-name-1" name="unknown-name-1[]" value="Bike"> I have a bike<br>
    <input type="checkbox" class="unknown-name-1" name="unknow-name-1[]" value="Car"> I have a car<br>
    <input type="checkbox" class="unknown-name-1" name="unknow-name-1[]" value="_other" data-target-text-input="text-input-other-option-unknow-name-1"> Others 
    <input type="text" id="text-input-other-option-unknow-name-1" class="unknown-name-1" name="unknown-name-1[]">


    <input type="checkbox" class="unknown-name-2" name="unknow-name-2[]" value="House"> I have a house<br>
    <input type="checkbox" class="unknown-name-2" name="unknow-name-2[]" value="Apartement"> I have an apartement<br>
    <input type="checkbox" class="unknown-name-2" name="unknow-name-2[]" value="Vila"> I have a vila<br>
    <input type="checkbox" class="unknown-name-2" name="unknow-name-2[]" value="_other" data-target-text-input="text-input-other-option-unknow-name-2"> Others 
    <input type="text" id="text-input-other-option-unknow-name-2" class="unknown-name-2" name="unknow-name-2[]">

</form>

All the class or ID or name of each checkbox is dynamic which means I don't know what the value of each attribute will be on the moment that the view is rendered, neither the numbers of groups of the checkboxlist, but two groups above will be used as an example of code snippet.

Validation rules:

Each checkboxlist is required at least one option to be checked. The last option is _other , if this option is checked, its input field is required.

I have spent hours to write the dynamic validator with JavaScript but I still cannot get it done. I hope some of you can help me! How can I write a dynamic validator with JavaScript , not in jQuery , that can check these conditions? Note: There can be one, two, three or more groups of checkboxlist, the value of all attributes of each checkbox is unknown beforehands. If necessary, more attributes can be added to the checkbox but the value of them needs be dynamic.

You need to attach an handler to submit event and retrieve all checkbox for current form, and to checks if one checkbox is checked use the "checked" property (easy, isn't it ? :)).

Simple solution :

var form = document.getElementById('my-form');

function validate(e) {
    // "this" is the current form which has been submitted
    // so we get all checkboxes for this form
    var checkboxes = this.querySelectorAll('[type="checkbox"]'); 
    var isValid = false;

    for (var c = 0; c < checkboxes.length; c++) {
        if (checkboxes[c].checked) {
            isValid = true; break;
        }
    }

    if (!isValid) {
        alert('One choice at least required.');
        e.preventDefault();
    }
}

form.addEventListener('submit', validate);

Full example : http://jsfiddle.net/Reeska/a228Lko0/

Advanced solution :

You can apply this method to an advanced usage, first we need to mark which block or field need to be validate, to do that, we need to use css classes and data-attributes :

<form id="my-form">
   <div class="validate" data-validator="checkbox-required" data-name="Group 1">
      <input type="checkbox" class="unknown-name-1" name="unknown-name-1[]" value="Bike"> I have a bike<br>
      <input type="checkbox" class="unknown-name-1" name="unknow-name-1[]" value="Car"> I have a car<br>
      <input type="checkbox" class="unknown-name-1" name="unknow-name-1[]" value="_other" data-target-text-input="text-input-other-option-unknow-name-1"> Others 
      <input type="text" id="text-input-other-option-unknow-name-1" class="unknown-name-1" name="unknown-name-1[]">
   </div>
   <hr />
   <div class="validate" data-validator="checkbox-required" data-name="Group 2">
    ...
   </div>
   <input type="submit" val="submit" />
</form>

For each items with validate class, I indicate which validation type I want with data-attributes data-validator , and in JS I will create one function by validation type :

var validators = {
    'checkbox-required' : function() {
        var checkboxes = this.querySelectorAll('[type="checkbox"]'); 
        var isValid = false;

        for (var c = 0; c < checkboxes.length; c++) {
            if (checkboxes[c].checked) {
                isValid = true; break;
            }
        }     

        return {
            valid: isValid,
            msg: (!isValid ? 'One choice at least required.' : '')
        }
    }
};

Finally, for each validate item I apply its validator function on submit :

form.addEventListener('submit', function(e) {
    var items = this.querySelectorAll('.validate');
    var errors = [];

    for (var it = 0; it < items.length; it++) {
        var data = items[it].dataset;
        var validator = data['validator'];

        if (!validator || !validators[validator]) {
            console.log('Unknown validator : ' + validator);
            continue;
        }

        var test = validators[validator].call(items[it]);

        if (!test.valid) {
            errors.push((data.name ? data.name + ": " : '') + test.msg);  
        }
    }

    if (errors.length > 0) {
        // if error is detected, cancel submit
        e.preventDefault();  

        alert(errors.join("\n"));
    }
});

That's it, and you can add other validators type.

Full advanced example : http://jsfiddle.net/Reeska/a228Lko0/5/

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