2

Using the jQuery Validate plugin, I've got a custom method that ensures at least one out of three checkboxes has been checked (as per this question).

This works fine, except that once the one of the checkboxes has been checked, the error container doesn't disappear (even though the error messages do disappear and the form will submit successfully). The error container remains stuck on 'display: block' rather than reverting back to 'display: none'.

Here's a JSFiddle which demonstrates this (it's a simplified version of my form). If one out of three checkboxes is checked, the error container remains in place even though there's no error messages. If all three checkboxes are checked, the error message container disappears. So I'd appreciate any ideas on how to make the error container disappear after just one of the checkboxes has been checked, as per the custom method, thanks.

Here's my HTML:

<form class="my_form" method="post" action="#">

  <div class="error-container">
    <ul>
    </ul>
  </div><!--error-container-->

    <p><label>My checkbox 1</label>
    <input class="my_checkbox_group" id="my_checkbox_1"
    name="my_checkbox_1[]" type="checkbox" value="Yes" /></p>
    <p><label>My checkbox 2</label>
    <input class="my_checkbox_group" id="my_checkbox_2"
    name="my_checkbox_2[]" type="checkbox" value="Yes" /></p>
    <p><label>My checkbox 3</label>
    <input class="my_checkbox_group" id="my_checkbox_3"
        name="my_checkbox_3[]" type="checkbox" value="Yes" /></p>
    <input type="submit" value="Submit" />
</form>

Here's my CSS:

input.error { background: #fdf3f3; border: 1px solid #ff3333; color: #ff3333; }
.error-container    { background: #fdf3f3; border: 1px solid #ff3333; clear: both; display: none; overflow: auto; padding: 10px; }
.error-container ul { margin-bottom: 0; }
.error-container label { float: none; font-weight: normal!important; width: auto; }

Here's my JS:

$(document).ready(function () {

    $.validator.addMethod("checkboxrule", function (value, element) {
        return ($('#my_checkbox_1').is(':checked') || $('#my_checkbox_2').is(':checked') || $('#my_checkbox_3').is(':checked'))
    }, "Select at least one of these three");

    $('.my_form').validate({ // initialize the plugin
        errorContainer: ".error-container",
        errorLabelContainer: ".error-container ul",
        wrapper: "li",
        focusInvalid: false,
        ignore: "",
        groups: {
            somename: "my_checkbox_1[] my_checkbox_2[] my_checkbox_3[]"
        },
        rules: {
            'my_checkbox_1[]': {
                checkboxrule: true
            },
            'my_checkbox_2[]': {
                checkboxrule: true
            },
            'my_checkbox_3[]': {
                checkboxrule: true
            }
        },
        submitHandler: function (form) { // for demo
            alert('valid form submitted'); // for demo
            return false; // for demo
        }
    });

});
Community
  • 1
  • 1
Stephen
  • 553
  • 3
  • 12
  • 23

1 Answers1

3

Add the following success callback function to your .validate() options.

success: function() {
    $('.error-container').hide();
},

DEMO: http://jsfiddle.net/M2gp4/


BTW: If you want to validate your hidden fields, the proper format for the ignore option is not ignore: "".

It should be ignore: [].

See this answer: https://stackoverflow.com/a/8565769/594235


EDIT:

As you originally wrote your code, the error container works as expected, but only when all three checkboxes are checked.

Taking it further, this problem can be better seen when the groups option is removed. In this new jsFiddle, you can see three messages and what happens when you click all three checkboxes. The box remains even on a valid form until you click submit. The plugin is not doing a validation test on this "group" until all checkboxes in the group are clicked. It's very much like it's treating all three checkboxes as a single input element.

A possible solution is to use the .valid() method to force a validation test every time you click on any one of the checkboxes.

$('.my_checkbox_group').on('click', function(){
    $('.my_form').valid();
});

DEMO: http://jsfiddle.net/M2gp4/3/

Community
  • 1
  • 1
Sparky
  • 98,165
  • 25
  • 199
  • 285
  • Thanks for this, and for the pointer about the ignore option. The JSFiddle works fine, but I couldn't get this working when plugging it into my form. If I try submit the form without touching any fields, I get all the validation error messages appearing as expected. If I enter something in a field or check a checkbox, all the validation messages disappear (instead of just the message for the field I just filled in). Here's a JSFiddle to demonstrate this: http://jsfiddle.net/M2gp4/1/ Any ideas on this at all? – Stephen Mar 13 '13 at 01:57
  • 1
    @Stephen, I've reviewed the documentation and your original code matched the examples given. As per the description, it should have worked properly without adding the `success` callback. I'd keep working on your problem if the jsFiddle server wasn't acting like complete garbage tonight. Perhaps there's something about this over at Github. – Sparky Mar 13 '13 at 02:20