简体   繁体   中英

Javascript validate checkboxes with array values

Plot I have some dynamic js validations that first scan for all fields in a step (HTMLElement). Basically I populate checkbox_groups with all the names and then check if at least one is checked. This works good except a certain situation.

Problem I have some dynamic checkboxes that have names like: person[1] , person[2] , person[3] . Because the id is specified my error <p> appears under each checkbox instead of only the last checkboxes as intended. Basically all I want is to find a way to modify this script so in this scenario the error message to appear only after the last checkbox.

Code

/**
 * Validate step checkboxes
 *
 * @param {HTMLElement} element
 *
 * @returns {Object}
 */
function validate_step_checkboxes(step) {
    var checkbox_groups = [];
    var errors = [];
    var error = false;

    $.each(step.find('input[type="checkbox"][data-required="1"]'), function () {
        var myname = this.name;
        if ($.inArray(myname, checkbox_groups) < 0) {
            checkbox_groups.push(myname);
        }
    });

    console.log('groups');
    console.log(checkbox_groups);

    // Check if there is a checkbox selected for each checkbox group
    for (i = 0; i < checkbox_groups.length; i++) {
        if (step.find('input[type="checkbox"][data-required="1"]:checked').length <= 0) {
            $('input[type="checkbox"][data-required="1"][name="' + checkbox_groups[i] + '"]').last().closest('.checkbox-label').after('<p class="input-error">Please select one option.</p>');
            errors[checkbox_groups[i]] = 'Field required';
            error = true;
        }
    }
    return !error;
}

HTML

<table class="primary-table hidden-xs">
    <thead>
        <tr>
            <th>Name</th>
            <th>X/th>
            <th>x</th>
            <th>x</th>
            <th>&emsp;</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <label class="checkbox-label">Test PErson
                <input name="person[1]" type="checkbox" data-required="1">
                <span class="checkmark"></span>
                </label>
            </td>
            <td>-</td>
            <td>Test</td>
            <td>Test</td>
            <td><a href="h#">Edit</a></td>
        </tr>
        <tr>
            <td>
                <label class="checkbox-label">Test PErson
                <input name="person[2]" type="checkbox" data-required="1">
                <span class="checkmark"></span>
                </label>
            </td>
            <td>-</td>
            <td>Test</td>
            <td>Test</td>
            <td><a href="h#">Edit</a></td>
        </tr>
        <tr>
            <td>
                <label class="checkbox-label">Test PErson
                <input name="person[3]" type="checkbox" data-required="1">
                <span class="checkmark"></span>
                </label>
            </td>
            <td>-</td>
            <td>Test</td>
            <td>Test</td>
            <td><a href="h#">Edit</a></td>
        </tr>
        <tr>
            <td>
                <label class="checkbox-label">Test PErson
                <input name="person[4]" type="checkbox" data-required="1">
                <span class="checkmark"></span>
                </label>
            </td>
            <td>-</td>
            <td>Test</td>
            <td>Test</td>
            <td><a href="h#">Edit</a></td>
        </tr>
    </tbody>
</table>

As described in the comments, the HTML defines each individual checkbox as part of a unique set (eg person[1] ). But the Javascript expects those to be groups of checkboxes ...

There is nothing wrong with using a checkbox name like person , you can still have 10 checkboxes with that name and check as many or as few as you like. To make things easier on the backend it is common to use a name like person[] , so you get an array of values. In this case since you're selecting multiple persons maybe people[] is an appropriate name.

If you really need unique name s for each checkbox for some reason, the only way I can think of to get the JS to treat them as part of a single group is to strip off the [1] part to find the common "base" name. This does not seem like a good idea though, fragile and hacky. I've included a working example below, but I wouldn't recommend using this.

Maybe a better option would be to treat the block of HTML as the semantic group? So the input name isn't relevant, you're just looking for something checked inside that <div> (or maybe <table> in your case)? But again this doesn't feel like a good option, we're circumventing the built in properties that are supposed to do exactly this - the name specifies how inputs are grouped.

 /** * Validate step checkboxes * * @param {HTMLElement} element * * @returns {Object} */ function validate_step_checkboxes(step) { var checkbox_groups = []; var errors = []; var error = false; $.each(step.find('input[type="checkbox"][data-required="1"]'), function () { var myname = this.name; // Check if this name includes [1], etc if (myname.match(/\[\d\]/)) { // It does, let's get the "base name" without [1] myname = myname.replace(/\[\d\]/, ''); console.log('stripped', myname); } if ($.inArray(myname, checkbox_groups) < 0) { checkbox_groups.push(myname); } }); console.log('groups'); console.dir(checkbox_groups); // Check if there is a checkbox selected for each checkbox group for (i = 0; i < checkbox_groups.length; i++) { if (step.find('input[type="checkbox"][data-required="1"]:checked').length <= 0) { $('input[type="checkbox"][data-required="1"][name^="' + checkbox_groups[i] + '"]').last().closest('.checkbox-label').after('<p class="input-error">Please select one option.</p>'); errors[checkbox_groups[i]] = 'Field required'; error = true; } } console.log('errors:'); console.dir(errors); return !error; } $(document).ready(function() { let $step1 = $('.primary-table'); let valid = validate_step_checkboxes($step1); console.log('valid:', valid); });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <table class="primary-table hidden-xs"> <thead> <tr> <th>Name</th> <th>X/<th> <th>x</th> <th>x</th> <th>&emsp;</th> </tr> </thead> <tbody> <tr> <td> <label class="checkbox-label">Test PErson <input name="person[1]" type="checkbox" data-required="1"> <span class="checkmark"></span> </label> </td> <td>-</td> <td>Test</td> <td>Test</td> <td><a href="h#">Edit</a></td> </tr> <tr> <td> <label class="checkbox-label">Test PErson <input name="person[2]" type="checkbox" data-required="1"> <span class="checkmark"></span> </label> </td> <td>-</td> <td>Test</td> <td>Test</td> <td><a href="h#">Edit</a></td> </tr> <tr> <td> <label class="checkbox-label">Test PErson <input name="person[3]" type="checkbox" data-required="1"> <span class="checkmark"></span> </label> </td> <td>-</td> <td>Test</td> <td>Test</td> <td><a href="h#">Edit</a></td> </tr> <tr> <td> <label class="checkbox-label">Test PErson <input name="person[4]" type="checkbox" data-required="1"> <span class="checkmark"></span> </label> </td> <td>-</td> <td>Test</td> <td>Test</td> <td><a href="h#">Edit</a></td> </tr> </tbody> </table>

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