We help IT Professionals succeed at work.

New podcast episode! Our very own Community Manager, Rob Jurd, gives his insight on the value of an online community. Listen Now!

x

form validation - make sure at least 1 checkbox is selected

Black Sulfur
Black Sulfur asked
on
5,330 Views
Last Modified: 2017-03-20
I am having trouble with form validation for checkboxes. But this is for example 3 sets of checkboxes generated by php.

Here is the checkbox code for 3 generated sets.

<div class="form-group">
	<div class="checkbox checkbox-danger checkbox-inline">
		<input type="checkbox" name="defect[]" value="{$ng_id}">
	</div>
</div>
<div class="form-group">
	<div class="checkbox checkbox-danger checkbox-inline">
		<input type="checkbox" name="defect[]" value="{$ng_id}">
	</div>
</div>
<div class="form-group">
	<div class="checkbox checkbox-danger checkbox-inline">
		<input type="checkbox" name="defect[]" value="{$ng_id}">
	</div>
</div>

Open in new window


If I just do something like this then it echo's out whatever I select.

foreach($_POST['defect'] as $defects) {
echo $defects;
}

Open in new window


I have tried to use the empty function on its own as well as this:

if(empty($defects) || count($defects) < 1) {

Open in new window


I also did try :

if(!isset($_POST['defect'])) {

Open in new window


but I just keep getting the error:

Undefined index: defect
Comment
Watch Question

You can use Jquery to do it:
<html>
<head>
     <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
</head>
<body>

<script type="text/javascript">
$(document).ready(function () {
    $('#YourButtonValidation').click(function() {
      checked = $("input[type=checkbox]:checked").length;

      if(!checked) {
        alert("You must check at least one checkbox.");
        return false;
      }

    });
});

</script>

<div class="form-group">
	<div class="checkbox checkbox-danger checkbox-inline">
		<input type="checkbox" name="defect[]" value="{$ng_id}">
	</div>
</div>
<div class="form-group">
	<div class="checkbox checkbox-danger checkbox-inline">
		<input type="checkbox" name="defect[]" value="{$ng_id}">
	</div>
</div>
<div class="form-group">
	<div class="checkbox checkbox-danger checkbox-inline">
		<input type="checkbox" name="defect[]" value="{$ng_id}">
	</div>
</div>

Open in new window

Author

Commented:
Thanks SniperCode Sheva,

The problem with that is if I check one checkbox in the one set, and not the other 2, it then accepts it and doesn't give me the error. It needs to produce an error if at least one checkbox is not checked in all three sets.
Most Valuable Expert 2011
Author of the Year 2014

Commented:
Looks to me like the HTML will produce a structure like this when the form is submitted
$_POST['defects][]

In other words, the "defects" element of $_POST will be an array.  Inside that array the checkboxes, if any, will be present.  You can use var_dump() to see what $_POST contains.  Unfired checkboxes and radio buttons are not present in the request.

This article might have some helpful value, too.
https://www.experts-exchange.com/articles/5450/Common-Sense-Examples-Using-Checkboxes-with-HTML-JavaScript-and-PHP.html
Here is a working sample
CERTIFIED EXPERT

Commented:
if you want to do this in PHP, please check the below code

<form action="checkbox.php" method="post"  >
<div class="form-group">
	<div class="checkbox checkbox-danger checkbox-inline">
		<input type="checkbox" name="defect[]" value="1">
	</div>
</div>
<div class="form-group">
	<div class="checkbox checkbox-danger checkbox-inline">
		<input type="checkbox" name="defect[]" value="2">
	</div>
</div>
<div class="form-group">
	<div class="checkbox checkbox-danger checkbox-inline">
		<input type="checkbox" name="defect[]" value="3">
	</div>
</div>
<input type="submit" value="submit" name="submit">
</form>

 

<?php 

      if (isset($_POST['submit']))
	  {
          if (!empty($_POST['defect'])) 
		  {
              foreach ($_POST['defect'] as $selected)
			  {
                  echo "<p>".$selected ."</p>";
              }
          }
          else 
		  {
              echo "<b>Select at least any one of the checkbox</b>";
          }
      }
 ?>

Open in new window

Author

Commented:
Thanks Peos John,

I get the same result as the other solution that was posted regarding doing it with jQuery. If I check one box then the error goes away. In theory, 3 boxes have to be checked to succeed. One from every set.

So, the page would show something like this:

Set 1

choice 1    choice 2    choice 3




Set 2

choice 1    choice 2    choice 3





Set 3

choice 1    choice 2    choice 3


With your code, if I only select choice 1 from Set 3, the validation passes which it shouldn't. The user MUST choose at least 1 option from Set 1, Set 2 and Set 3.
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION

Author

Commented:
@SniperCode Sheva

That is pretty cool. But I want to user server side validation (PHP, specifically) and not jQuery.
using the code of Peos John, it will be something like this:
<form method="post">
<div class="form-group">
	<div class="checkbox checkbox-danger checkbox-inline">
		<input type="checkbox" name="defect1[]" value="1">
        <input type="checkbox" name="defect1[]" value="7">
	</div>
</div>
<div class="form-group">
	<div class="checkbox checkbox-danger checkbox-inline">
		<input type="checkbox" name="defect2[]" value="2">
        <input type="checkbox" name="defect2[]" value="6">
	</div>
</div>
<div class="form-group">
	<div class="checkbox checkbox-danger checkbox-inline">
		<input type="checkbox" name="defect3[]" value="3">
        <input type="checkbox" name="defect3[]" value="4">

	</div>
</div>
<input type="submit" value="submit" name="submit">
</form>

 

<?php 

      if (isset($_POST['submit']))
	  {
          if (!empty($_POST['defect1'])&& !empty($_POST['defect2']) && !empty($_POST['defect3'])) 
		  {
              
          }
          else 
		  {
              echo "<b>Select at least any one of the checkbox</b>";
          }
      }
 ?>

Open in new window

Author

Commented:
@ SniperCode Sheva, I will not have defect1, defect2 and defect3 because the checkboxes are dynamically generated with this code:

<div class="form-group">
	<div class="checkbox checkbox-danger checkbox-inline">
		<input type="checkbox" name="defect[]" value="{$ng_id}">
	</div>
</div>

Open in new window


If the user for example enters 3 in a text field, it will generate the above x 3. If they enter 4, it will generate the above x 4.
Most Valuable Expert 2011
Author of the Year 2014
Commented:
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION
Most Valuable Expert 2011
Author of the Year 2014

Commented:
will not have defect1, defect2 and defect3 because the checkboxes are dynamically generated...
You probably want to change that design.  You need to know the names of your checkboxes, and you need to know which group they are a part of.  Without a signal in the name of the checkbox, you can't validate the POST request.

Author

Commented:
@ Ray,

Thanks for that. Okay, so I changed my code to this:

<div class="form-group">
	<div class="checkbox checkbox-danger checkbox-inline">
		<input type="checkbox" name="defect[$item]" value="{$ng_id}">
	</div>
</div>

Open in new window


$item is just a count which counts how many sets I generate:

$counter = 0;
$item = 0;
			
	while($counter < $times) {
		$counter++;
		$item++;

Open in new window


So, my checkboxes now look like:

<input type="checkbox" name="defect[1]" value="5">

<input type="checkbox" name="defect[2]" value="5">

<input type="checkbox" name="defect[3]" value="5">

So, I would have to apply this now somehow without knowing how many there will be. hmmm

 if (empty($_POST['defect']))      echo "<br>Nothing selected in A or B";
    if (empty($_POST['defect']['a'])) echo "<br>Nothing selected in A";
    if (empty($_POST['defect']['b'])) echo "<br>Nothing selected in B";

Open in new window


If I do this manually it works well. But obviously I can't do it like this because of the fact that the number of "sets" will be unknown.

 if (empty($_POST['defect'][1])) echo "<br>Nothing selected in 1";
 if (empty($_POST['defect'][2])) echo "<br>Nothing selected in 2";
 if (empty($_POST['defect'][3])) echo "<br>Nothing selected in 3";

Open in new window

Author

Commented:
Did this:

	$counter = 0;
		
		while($counter < 3) {
			
			$counter++;
				 if (empty($_POST['defect'][$counter])) echo "<br>Nothing selected in " . $counter;
		
		}

Open in new window


This works but I still have the same problem where 3 needs to not be static. Argh.

Author

Commented:
Ahah. I just set a session variable when creating the sets of checkboxes:

$times = $non_green;
			$counter = 0;
			$item = 0;
			$_SESSION['times'] = $times;
			
			while($counter < $times) {
				$counter++;
				$item++;

Open in new window


Looped this:

<div class="form-group">
	<div class="checkbox checkbox-danger checkbox-inline">
		<input type="checkbox" name="defect[$item]" value="{$ng_id}">
	</div>
</div>

Open in new window


And did this:

	$counter = 0;
		
		while($counter < $_SESSION['times']) {
			
			$counter++;
				 if (empty($_POST['defect'][$counter])) echo "<br>Nothing selected in " . $counter;
		
		}

Open in new window


This works! :)

Question is, is there anything wrong with using the Session variable like I did? I am glad it's working but don't want to do it like this if it's "wrong".
Most Valuable Expert 2011
Author of the Year 2014

Commented:
It's not wrong at all -- that's probably a good use of the PHP session.  There is a tiny risk, however, that the session could time out after someone has requested the form and before they have filled it in and submitted it.  The session usually lives for 24 minutes after the last HTTP request.
https://www.experts-exchange.com/articles/11909/PHP-Sessions-Simpler-Than-You-May-Think.html

Author

Commented:
Good point. I think I will just check that the session is in fact there then otherwise redirect them.

if(!isset($_SESSION['times'])) {
// redirect them

Open in new window

Author

Commented:
Oops. I just realized that SniperCode Sheva did post something pretty similar to Ray (but I don't think it would have worked in it's current state) and I should award that points instead of the jQuery post! Please could admin help me out and allow me to change the points assignment.
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a sample view!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.