To keep you from wondering whether what you find here is applicable to your specific use, here's a quick overview of what we want to accomplish. We'll start with a set of radio-buttons; one of these will be used to show a hidden fieldset of checkboxes. From there, it's crucially important that users select at least one of these checkboxes before submitting our form; we'll use jQuery to set up some validation rules to ensure this happens.
Note: we could use pure JavaScript for this, but jQuery is in my experience a lot simpler to use when capturing checked values as variables.
First, let's look at our form. It's nothing special--we need a radio button that will reveal our checkboxes and another that will leave them hidden (or hide them, as the case may be). That may look something like this:
<form>
<fieldset>
<legend>
Either show or hide options:
</legend>
<input name="Options" type="radio" value="show" class="show"><label>Show</label><br>
<input name="Options" type="radio" value="hide" class="hide"><label>Hide</label><br>
</fieldset>
We'll use the show radio button to toggle our checkboxes open. Hide button will either leave them hidden or hide them. You'll want to pay close attention to the classes assigned to your inputs here. Once we get our checkboxes built out, we'll create a function that toggles them open based on input. Before we do that, though, let's put together our checkboxes:
<div id="list" style="display:none;">
<fieldset>
<legend>
Require at least one option before submit:
</legend>
<input name="Check 1" type="checkbox" value="one" class="one"><label>One</label><br>
<input name="Check 2" type="checkbox" value="two" class="two"><label>Two</label><br>
<input name="Check 3" type="checkbox" value="three" class="three"><label>Three</label><br>
<div id="alert" style="display: none;">
*Please select at least one option
</div>
</fieldset>
</div>
<button name="submit" type="submit" onclick="validateChoice();">
Submit
</button>
</form>
Our fieldset has a parent div that we'll hide by default--be sure to set display to none. Take note of the classes for each of the checkboxes; note that our alert div is also hidden by default; and lastly, note that we'll be giving an onclick function to the submit button.
From here, it's mostly downhill. We'll start by creating a jQuery function that will reveal the three checkboxes based on initial input. That will go something like this:
//When there is change on input items with the name attribute "Options", do function
$('input[name="Options"]').change(function() {
//create a variable for value of the input with a class of "show" when checked
var option = $("input[class='show']:checked").val();
//if that variable value is equal to show...
if (option == "show") {
//reveal the checkbox parent div using parent div ID...
$("#list").slideDown("slow");
//otherwise...
} else {
//hide the checkbox parent div
$("#list").slideUp("slow");
}
});
There we go! So far so good. This should be pretty straightforward; the trickiest part will be making sure that you reference the correct name attributes, classes and IDs--remember, jQuery is case sensitive in regard to those things.
The next step from here recycles (repurposes) some of the code from above. Now that we can use the "show" radio-button to reveal our checkboxes, we want to make sure that at least one of them gets checked before the form is submitted. Under normal circumstances, we'd rarely ever require someone to check a checkbox--unless the checkbox itself represents some sort of validation: i.e.; "I have read the terms and conditions". In most cases, though, checkboxes are used to allow multiple selections; very often, they can be left blank. What about when you have a mix of both of these scenarios? You'd like to let users choose which box they check, but they have to check at least one? jQuery offers a somewhat painless solution for this. In our case, we'll simply run a function that says, "if there's no checked value for any of these, don't submit the form (and remind users to check them)".
But--hold on! We're getting ahead of ourselves. You'll recall that our checkboxes are hidden for anyone who chooses not to show them. If we create a function requiring at least one of them, that would prevent users who leave them hidden from being able to submit the form. jQuery doesn't care that the checkboxes are hidden by a parent div, so that won't do. We'll need to use some extra logic in our function. We can't just require one of our checkboxes to be checked; we need to require one of them to be checked only when the user has chosen to show them. It's an extra piece of logic, but it's quite easy to setup. Remember that we gave an onclick function to our submit button in our HTML--it was called validateChoice(). Let's define that function now.
function validateChoice() {
/*this first variable was already defined in our first script. it's the radio button that's
used to open up the div with our checkboxes. we want to include it in our logic as a criterion
for the function. unfortunately, it's not a global variable, so we'll want to define it again...*/
var option = $("input[class='show']:checked").val();
//now, we define variables based on the checked values of each checkbox...
var value1 = $("input[class='one']:checked").val();
var value2 = $("input[class='two']:checked").val();
var value3 = $("input[class='three']:checked").val();
//if all of the following are true
if (option == "show" && value1 !== "one" && value2 !== "two" && value3 !== "three") {
//jump to the checkbox parent div using div ID...
location.hash = "list";
//and show a div with the ID of alert...
$("#alert").slideDown("slow");
//lastly, prevent the default action from ocurring
event.preventDefault();
//otherwise...
} else {
//keep calm and hide the alert div
$("#alert").slideUp("slow");
}
}
Here, we do something quite similar to what we did with our hide/show radio buttons; we start by capturing checked values as variables. We need to use the "show" radio button as a variable so that we can include it in our if statement. Basically, we're saying, if the "show" radio is checked, and values for none of the checkboxes return true (i.e.; value1 does not equal "one"; value2 does not equal "two", etc.), don't submit the form.
Now, originally, this code was part of a ticket on a very long form I put together for a client. Since the function is tied to the submit button, and since that button sits far at the bottom of the page, I included the location.hash business so we can jump back to the section users need to fill out. I also used the same slideDown effect from our previous script to show the alert div. Beyond the logic of the if statement, though, the key to this script is the event.preventDefault method; this is what stops the submit action from running.
I hope this all makes sense.
The logic of these kinds of scenarios is sometimes illusive. When I was first given the ticket, I was tempted to try a solution that involved checking for positive values on the checkboxes: i.e.; value1 == "one". I almost muttered aloud my anxiety over needing to figure out all the possible combinations of the three checkboxes that would allow the form to submit. After a few thoughtful moments, though, it dawned on me that this was wholly unnecessary; rather than figure out what would allow the form to submit, the real question was what would allow the form to not submit. There are multiple ways to find success, but only one way to fail--i.e.; to leave all the checkboxes blank. Rather than code for the multiple success possibilities, it's a much better use of my time to code for the one and only fail scenario.
For anyone who wants to play with this, here's a quick preview of the final deal--select "show" and then try submitting the form without checking any of the boxes: