Link to home
Start Free TrialLog in
Avatar of Crazy Horse
Crazy HorseFlag for South Africa

asked on

form validation - make sure at least 1 checkbox is selected

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
Avatar of SniperCode Sheva
SniperCode Sheva

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

Avatar of Crazy Horse

ASKER

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.
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
Avatar of Peos John
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

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.
SOLUTION
Avatar of SniperCode Sheva
SniperCode Sheva

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
@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

@ 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.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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.
@ 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

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.
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".
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
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

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.