Michael Doughty
Michael Doughty

Reputation: 45

Using jQuery to check all radio groups checked when names are unknown

Working on a form validation function which produces a list of empty fields and a list of incorrectly-filled fields. The script functions perfectly for text and text-areas. When I apply the following method to radio buttons:

$("input:radio[name]").each(function() {
    $(this).removeClass("error");     // Remove previously-applied error class
    if($(this).filter(":checked").length == 0) {       // Make sure they chose an option.
        emptys[j] = nameFix($(this).attr("name"));     // Add to array, apply error class
        $(this).addClass("error");                     // increment placeholder and exit
        j ++;                                          // the function
        return;
    } else {
        return;
    }
}); // end radio each

unanswered radio groups produce 2 indices in emptys and answered radio groups produce 1 index (I'm testing on a page where the user indicates whether tests were passed or failed).

The universally-accepted answers I've found so far all assume I will use specific attributes I've given the <input> tags in my JS. The site I'm building will have dozens of various forms which will require validation, so I'm trying to produce a universally-applicable script to check their validity.

EDIT: sample of HTML

<tr>
        <td class="borderRight">Methane Overpressure</td>
        <td>Target Pressure &#40;psi&#41;</td>
        <td>300</td>
        <td>&#177; 1.0</td>
        <td class="input"><input type="text" name="Target-Pressure" class="num" size="2" maxlength="5"></td>
        <td class="input"><input type="radio" name="Target-Pressure-Pass-or-Fail" value="1"> P</td>
        <td class="input">F <input type="radio" name="Target-Pressure-Pass-or-Fail" value="0"></td>
    </tr>
    <tr>
        <td class="borderRight">Magnet</td>
        <td>Magnetic Field Strength &#40;T&#41;</td>
        <td>4.5</td>
        <td>&#177; 0.5</td>
        <td class="input"><input type="text" name="Magnetic-Field-Strength" class="num" size="2" maxlength="4"></td>
        <td class="input"><input type="radio" name="Magnetic-Field-Strength-Pass-or-Fail" value="1"> P</td>
        <td class="input">F <input type="radio" name="Magnetic-Field-Strength-Pass-or-Fail" value="0"></td>
    </tr>
    <tr>
        <td rowspan="2" class="borderRight">Acceleration</td>
        <td>Radio Frequency &#40;MHz&#41;</td>
        <td>68</td>
        <td>&#177; 0.1</td>
        <td class="input"><input type="text" name="Radio-Frequency" class="num" size="2" maxlength="5"></td>
        <td class="input"><input type="radio" name="Radio-Frequency-Pass-or-Fail" value="1"> P</td>
        <td class="input">F <input type="radio" name="Radio-Frequency-Pass-or-Fail" value="0"></td>
    </tr>

Upvotes: 0

Views: 263

Answers (3)

Michael Doughty
Michael Doughty

Reputation: 45

This is the snippet which successfully analyzed the radios by group and allowed the script to run to completion.

    var rgroup = new Array();
$(":radio").each(function() {
    rgroup[this.name] = true;
});
for (group in rgroup) {
    if (!!$(":radio[name=" + group + "]:checked").length) {
        $(":radio[name=" + group + "]").removeClass("error");
    } else {
        $(":radio[name=" + group + "]").addClass("error");
        emptys[j] = nameFix(group);
        j ++;
    }
}

I don't know why I couldn't get David Thomas's answer to work, it was very well written. I have a suspicion it has to do with the $.unique pulling up every single radio button because, as charlieftl pointed out, I did give the different answers binary values (so that the server will have something to work with). Though my script did not even reach the point of building the error message (or even rejecting the submission). I imagine that I'll be able to extend this technique to checkboxes when I eventually build a form which uses them.

Thank you both for helping me through this, I am impressed with both the quality and speed of your aid. And now to clock out of work...

Upvotes: 0

David Thomas
David Thomas

Reputation: 253308

A simple approach (written prior to your appending your HTML in your question) is:

function checkForChecked() {
        // use $.unique() to get the unique values from an array (created within),
        // gets all inputs of type="radio" with a 'name' attribute,
        // creates a map of those elements' names, uses 'get()' to make that a
        // real array
        var radioGroups = $.unique($('input[type="radio"][name]').map(function () {
            return this.name;
        }).get());

        // iterates over the array of group names ('a' is the current array element)
        radioGroups.forEach(function (a) {
            // caching the radio-inputs of the current name:
            var sel = $('input[type="radio"][name="' + a + '"]');
            // gets the parent elements of those radios (here the 'label' elements),
            // if there are no radio inputs checked we call the 'addClass' method,
            // otherwise the 'removeClass' method, and add/remove the 'requiredStill'
            // class. This can be adjusted to do otherwise as you need.
            sel.parent()[sel.filter(':checked').length === 0 ? 'addClass' : 'removeClass']('requiredStill');
        });
    }

    $('input').on('change', checkForChecked);

function checkForChecked() {

    var radioGroups = $.unique($('input[type="radio"][name]').map(function () {
        return this.name;
    }).get());

    radioGroups.forEach(function (a) {
        var sel = $('input[type="radio"][name="' + a + '"]');

        sel.parent()[sel.filter(':checked').length === 0 ? 'addClass' : 'removeClass']('requiredStill');
    });
}

$('input').on('change', checkForChecked);
label {
    display: block;
}
.requiredStill {
    border: 1px solid #f00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label>
    <input type="radio" name="a" />a</label>
<label>
    <input type="radio" name="a" />a</label>
<label>
    <input type="radio" name="a" />a</label>
<label>
    <input type="radio" name="b" />b</label>
<label>
    <input type="radio" name="b" />b</label>
<label>
    <input type="radio" name="b" />b</label>
<label>
    <input type="radio" name="c" />c</label>
<label>
    <input type="radio" name="c" />c</label>
<label>
    <input type="radio" name="c" />c</label>

References:

Upvotes: 1

charlietfl
charlietfl

Reputation: 171679

Approach adding an error element for visual reference

 var radios = $mainElem.find(':radio');
    var radioNames={};
    radios.each(function(){
        radioNames[this.name] = true;
    });

    for( name in radioNames){
        var radioGroup=$mainElem.find('[name=' + name + ']');
        if( !radioGroup.filter(':checked').length ){
            radioGroup.parent().append('<span class="error">Ooooops</span>');
        }
    }

DEMO

Upvotes: 0

Related Questions