44

I'm trying to validate a form using the validate plugin for jquery. I want to require that the user check at least one checkbox in a group in order for the form to be submitted. Here's my jquery code:

$().ready(function() {
$("#subscribeForm").validate({
   rules:   { list: {required: "#list0:checked"} },
   messages:  { list:  "Please select at least one newsletter"}                                                        
 });
 });

and here's the html form:

<form action="" method="GET" id="subscribeForm">
<fieldset id="cbgroup">
    <div><input name="list" id="list0" type="checkbox"  value="newsletter0" >zero</div>
    <div><input name="list" id="list1" type="checkbox"  value="newsletter1" >one</div>
    <div><input name="list" id="list2" type="checkbox"  value="newsletter2" >two</div>
</fieldset>
<input name="submit" type="submit"  value="submit">

The problem is that the form submits even if nothing is checked. How can I resolve this?

1
  • shouldn't your name elements be an array in the form of name="list[]" anyway?
    – JM4
    Dec 5, 2012 at 22:39

11 Answers 11

52
  $('#subscribeForm').validate( {
      rules: {
          list: {
              required: true,
              minlength: 1
          }
       }
   });

I think this will make sure at least one is checked.

2
  • 1
    I don't know why, but when I add this rule, other rules don't work as expected. Such as, I have "rule1" for textbox and "rule2" for list checkbox. If "rule2" is satisfied, the form submit no matter what "rule1" is. On the other hand, if "rule2" is not satisfied, it reports the error of "rule2". If both are not satisfied, both errors are reported. Dec 31, 2010 at 8:07
  • 1
    I think 'required' is sufficient (not sure whether minlength is also necessary). You might want to put it in the js, but just adding the required attribute to the inputs themselves will also accomplish the task. Oct 24, 2014 at 22:53
33

This script below should put you on the right track perhaps?

You can keep this html the same (though I changed the method to POST):

<form method="POST" id="subscribeForm">
    <fieldset id="cbgroup">
        <div><input name="list" id="list0" type="checkbox"  value="newsletter0" >zero</div>
        <div><input name="list" id="list1" type="checkbox"  value="newsletter1" >one</div>
        <div><input name="list" id="list2" type="checkbox"  value="newsletter2" >two</div>
    </fieldset>
    <input name="submit" type="submit"  value="submit">
</form>

and this javascript validates

function onSubmit() 
{ 
    var fields = $("input[name='list']").serializeArray(); 
    if (fields.length === 0) 
    { 
        alert('nothing selected'); 
        // cancel submit
        return false;
    } 
    else 
    { 
        alert(fields.length + " items selected"); 
    }
}

// register event on form, not submit button
$('#subscribeForm').submit(onSubmit)

and you can find a working example of it here

UPDATE (Oct 2012)
Additionally it should be noted that the checkboxes must have a "name" property, or else they will not be added to the array. Only having "id" will not work.

UPDATE (May 2013)
Moved the submit registration to javascript and registered the submit onto the form (as it should have been originally)

UPDATE (June 2016)
Changes == to ===

5
  • 6
    Why use onsubmit (on the button instead of the form, no less!) instead of $('form').submit(function() {...})? Oct 8, 2009 at 2:58
  • 1
    Er, should be $('#subscribeForm').submit(...) Oct 8, 2009 at 2:59
  • 1
    This works, but as I should have made more clear in my original question, I'm trying to use the validate plugin because the actual form is more complex and I'm trying to validate a bunch of other stuff. The other fields are validating just fine; it's just the checkbox group that's problematic. So, really, my question is whether I can get the validate plugin to do something like this.
    – jalperin
    Oct 8, 2009 at 10:43
  • 7
    Ah, I think I've got it working by substituting "input[name='list']" in the "required: " rules parameter. So, my jquery "rule" now looks like this: rules: { list: {required: "input[name='list']", minlength: 1} },
    – jalperin
    Oct 8, 2009 at 11:04
  • Should change fields.length == 0 to fields.length === 0.
    – TGarrett
    Jun 15, 2016 at 20:49
14

How about this:

$(document).ready(function() {
    $('#subscribeForm').submit(function() {
        var $fields = $(this).find('input[name="list"]:checked');
        if (!$fields.length) {
            alert('You must check at least one box!');
            return false; // The form will *not* submit
        }
    });
});
3
  • 1
    this is a very smooth and fast way, I like it!
    – Luci
    Mar 15, 2011 at 9:20
  • 4
    But makes no use of the jQuery Validate plugin as requested by the OP.
    – Eric J.
    May 25, 2012 at 6:12
  • I can't see the revision history for the question, but I don't think that the original version mentioned the Validate plugin. I could be wrong though...
    – JJ Geewax
    May 25, 2012 at 15:16
9

The above addMethod by Lod Lawson is not completely correct. It's $.validator and not $.validate and the validator method name cb_selectone requires quotes. Here is a corrected version that I tested:

$.validator.addMethod('cb_selectone', function(value,element){
    if(element.length>0){
        for(var i=0;i<element.length;i++){
            if($(element[i]).val('checked')) return true;
        }
        return false;
    }
    return false;
}, 'Please select at least one option');
6

Here is the a quick solution for multiple checkbox validation using jquery validation plugin:

jQuery.validator.addMethod('atLeastOneChecked', function(value, element) {
  return ($('.cbgroup input:checked').length > 0);
});

$('#subscribeForm').validate({
  rules: {
    list0: { atLeastOneChecked: true }
  },
  messages: {
    list0: { 'Please check at least one option' }
  }
});

$('.cbgroup input').click(function() {
  $('#list0').valid();
});
2
if (
  document.forms["form"]["mon"].checked==false &&
  document.forms["form"]["tues"].checked==false &&
  document.forms["form"]["wed"].checked==false &&
  document.forms["form"]["thrs"].checked==false &&
  document.forms["form"]["fri"].checked==false
) {
  alert("Select at least One Day into Five Days");
  return false; 
}
1
  • 1
    This is super nasty but I actually like the simplicity and zero-dependencies. Jun 3, 2019 at 21:49
1

Good example without custom validate methods, but with metadata plugin and some extra html.

Demo from Jquery.Validate plugin author

0

How about this

$.validate.addMethod(cb_selectone,
                   function(value,element){
                           if(element.length>0){
                               for(var i=0;i<element.length;i++){
                                if($(element[i]).val('checked')) return true;
                               }
                           return false;
                           }
                            return false;
                  },
                  'Please select a least one')

Now you ca do

$.validate({rules:{checklist:"cb_selectone"}});

You can even go further a specify the minimum number to select with a third param in the callback function.I have not tested it yet so tell me if it works.

0

I had to do the same thing and this is what I wrote.I made it more flexible in my case as I had multiple group of check boxes to check.

// param: reqNum number of checkboxes to select
$.fn.checkboxValidate = function(reqNum){
    var fields = this.serializeArray();
    return (fields.length < reqNum) ? 'invalid' : 'valid';
}

then you can pass this function to check multiple group of checkboxes with multiple rules.

// helper function to create error
function err(msg){
    alert("Please select a " + msg + " preference.");
}

$('#reg').submit(function(e){
    //needs at lease 2 checkboxes to be selected
    if($("input.region, input.music").checkboxValidate(2) == 'invalid'){
        err("Region and Music");
    } 
});
0

I had a slighlty different scenario. My checkboxes were created in dynamic and they were not of same group. But atleast any one of them had to be checked. My approach (never say this is perfect), I created a genric validator for all of them:

jQuery.validator.addMethod("validatorName", function(value, element) {
    if (($('input:checkbox[name=chkBox1]:checked').val() == "Val1") ||
        ($('input:checkbox[name=chkBox2]:checked').val() == "Val2") ||
        ($('input:checkbox[name=chkBox3]:checked').val() == "Val3")) 
    {   
        return true;
    }
    else
    {
        return false;
    }       
}, "Please Select any one value");

Now I had to associate each of the chkbox to this one single validator.

Again I had to trigger the validation when any of the checkboxes were clicked triggering the validator.

$('#piRequest input:checkbox[name=chkBox1]').click(function(e){
    $("#myform").valid();
});
0

I checked all answers and even in other similar questions, I tried to find optimal way with help of html class and custom rule.

my html structure for multiple checkboxes are like this

$.validator.addMethod('multicheckbox_rule', function (value, element) {
			var $parent = $(element).closest('.checkbox_wrapper');
			if($parent.find('.checkbox_item').is(':checked')) return true;
            return false;
}, 'Please at least select one');
<div class="checkbox_wrapper">
<label for="checkbox-1"><input class="checkbox_item" id="checkbox-1"  name="checkbox_item[1]" type="checkbox" value="1" data-rule-multicheckbox_rule="1" /> Checkbox_item 1</label>
<label for="checkbox-2"><input class="checkbox_item" id="checkbox-2" name="checkbox_item[2]" type="checkbox" value="1" data-rule-multicheckbox_rule="1" /> Checkbox_item 1</label>
</div>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.