Selecting at least one multiple checkbox

I have a form with several checkboxes i want a warning that at least one checkbox should be selected before submit. Tried a few things but to no joy. This form also has link to add extra locations.

Thanks

Code of my page…

<?php 
ob_start();
session_start();
include('database1.php');

include('../inc/config.php');
include(ROOT_PATH . 'inc/functions.php');

authCheck('maintenance');


include(ROOT_PATH . 'inc/header.php');

if (!empty($_POST['list'])) {
	$items = $_POST['list'];
	$json = json_encode($items);

	$results = $db->prepare("INSERT INTO checkboxform (content) VALUES (?)");
	$results->bindParam(1,$json);
	$results->execute();
header("Location: viewlocation1.php");

	
	exit;
	
	ob_end_flush();
}


?>

<!--Jquery Link-->

<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>

<link rel="stylesheet" href="main.css?ver=1.2">


<section class="login">
    <div class="container">

<center><p><a id="link" href="/demoadmin/maintenance/index.php"><b><h2>Maintenance Admin</h2></b></a></p></center>


<form method="post">
    
    

<fieldset id="business-details">
    
   

	<div class="container">
	    
	    
	    
	     

		Fire Extinguisher Locations

		<input type="text" name="list[0][location]" required>

		<label>Type</label>
		
		<div><input type="checkbox" name="list[0][water]">Water</div>
		<div><input type="checkbox" name="list[0][powder]">Dry Powder</div>
		<div><input type="checkbox" name="list[0][foam]">Foam</div>
		<div><input type="checkbox" name="list[0][CO2]">CO2</div>
		<div><input type="checkbox" name="list[0][chemical]">Chemical</div>


	</div>

</fieldset>

<a href="#" id="add-row">+</a> Add Another Location

<?php include(ROOT_PATH . 'inc/captcha.php'); ?>




<button type="submit" class="button">Submit</button>

</form>




    </div>
</section>

<p><center><img src="/256.jpg" class="responsive"></center></p>

<script>

$(document).ready(function() {
	var x = 0;
	//Once remove button is clicked

    $('#business-details').on('click', '.remove-field', function(e) {

		e.preventDefault();

		$(this).parent('.container').remove();

    });

	

    //Once add button is clicked

	$('#add-row').click(function(e) {

		e.preventDefault();

		x++;

		var list_fieldHTML = '<div class="container">' +
		'<label>Fire Extinguisher Location</label>' + 
		'<input type="text" name="list['+x+'][location]">' + 
		'<label>Type</label>' + 
		'<div><input type="checkbox" name="list['+x+'][water]">Water</div>' +
		'<div><input type="checkbox" name="list['+x+'][powder]">Dry Powder</div>' + 
		'<div><input type="checkbox" name="list['+x+'][foam]">Foam</div>' +
		'<div><input type="checkbox" name="list['+x+'][CO2]">CO2</div>' +
		'<div><input type="checkbox" name="list['+x+'][chemical]">Chemical</div>' +
		'<br><a href="#" class="remove-field">-</a> Remove Location</div>';

		$('#business-details').append(list_fieldHTML);


    });

});

</script>

<script>
    
    
    $(document).ready(function(){
    $("form").submit(function(){
		if ($('input:checkbox').filter(':checked').length < 1){
        alert("Please select at least one fire extinguisher type !");
		return false;
		}
    });
});
    
    
</script>


<?php include(ROOT_PATH . 'inc/footer.php'); ?>

I don’t use the jQuery library as I just use Vanilla JavaScript, but it’s easier to keep everything separate. By that I mean PHP, JavaScript and HTML separated as much as possible.

Here’s an example of what I’m talking about.

Part of my JavaScript →

submit.addEventListener('click', (e) => {

   e.preventDefault();

   sendEmail.phone = phone.value;
   sendEmail.website = website.value;
   sendEmail.response = submit.getAttribute('data-response');
   if (email.value === '') {
       email.placeholder = "Email Address is Invalid!";
       email.style.borderColor = "red";
       email.focus();
   }
   if (sendStatus.name && sendStatus.email && sendStatus.comments) {
       submit.style.display = "none";
       notice.style.display = "grid";

       // Change graphic to indicate sending in progress
       document.querySelector('.pen').setAttribute('src', 'assets/images/hour-glass.png');

       message.style.display = "flex";
       saveRequest(sendUrl, sendUISuccess, sendUIError);
   } else {
       notice.style.display = "block";
       notice.textContent = "Name, Email, and Message Required!";
   }
}, false);

my PHP →

<?php
// send_email.php
require_once __DIR__ . '/../config/config.php';

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;

require_once "vendor/autoload.php";

use brainwave\ErrorHandler;
use brainwave\Database;


$errorHandler = new ErrorHandler();

// Register the exception handler method
set_exception_handler([$errorHandler, 'handleException']);

$database = new Database();
$pdo = $database->createPDO();
$mail = new PHPMailer(true); // Pass `true` to enable exceptions
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $inputData = file_get_contents('php://input');
    $postData = json_decode($inputData, true);

    $name = $postData['name'];
    $email = $postData['email'];
    $comment = $postData['comments'];
    $mail->isSMTP();                                            //Send using SMTP
    $mail->Host = 'smtp.ionos.com ';                     //Set the SMTP server to send through
    $mail->SMTPAuth = true;                                   //Enable SMTP authentication
    $mail->Username = '[email protected]';                     //SMTP username
    $mail->Password = EMAIL_PASSWORD;                               //SMTP password
    $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;            //Enable implicit TLS encryption
    $mail->Port = 465;                                    //TCP port to connect to; use 587 if you have set `SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS`

    //Recipients
    $mail->setFrom( $email, $name);
    $mail->addAddress('[email protected]', 'John Pepp');     //Add a recipient
    $mail->addCC($email, $name);
    //Content
    $mail->isHTML(true);                                  //Set email format to HTML
    $mail->Subject = 'Inquiry of Website Development';
    $mail->Body = $comment . " " .  $email;



    try {
        $mail->send();
        // Replace these variables with actual values based on your email sending process
        $status = 'success';
        $message = 'Email sent successfully';

        $response = array(
            'status' => $status,
            'message' => $message
        );
    } catch (Exception $e) {
        $response['status'] = 'error';
        $response['message'] = "Email could not be sent. Mailer Error: {$mail->ErrorInfo}";
    }

    header('Content-Type: application/json');
    echo json_encode($response);
}

and the contact page →

// Include the configuration file and autoload file from the composer.
require_once __DIR__ . '/../config/config.php';
require_once "vendor/autoload.php";

use brainwave\{
    ErrorHandler,
    Database,
};

$errorHandler = new ErrorHandler();

// Register the exception handler method
set_exception_handler([$errorHandler, 'handleException']);

$database = new Database();
$pdo = $database->createPDO();

?>
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=yes, initial-scale=1.0">
    <title>Contact Form</title>
    <link rel="stylesheet" media="all" href="assets/css/admin.css">


</head>
<body class="site">
<header class="headerStyle">
    <div class="loginStyle">
        <h1 class="intro">Brain Wave Blitz - Web & Game Development, Design, & Photography</h1>
    </div>
</header>
<div class="nav">
    <!-- Button for mobile navigation -->
    <button class="nav-btn" id="nav-btn">
        <span></span>
        <span></span>
        <span></span>
    </button>

    <!-- Navigation links -->
    <nav class="nav-links" id="nav-links" itemprop="breadcrumb">
        <?php $database->regular_navigation(); ?>
    </nav>
</div>

<main class="main_container">
    <form class="contact" name="contact" action="contact.php" method="post" autocomplete="on">

        <!--                <input id="token" type="hidden" name="token" value="--><!--">-->
        <input type="hidden" name="reason" value="message">
        <figure class="owner">
            <img src="assets/images/img-john-pepp-150-150-001.jpg" alt="John Pepp" width="150" height="150">
            <figcaption>John Pepp</figcaption>
        </figure>
        <hr class="horizontal_line">
        <div class="contact_name">
            <label class="labelstyle" for="name" accesskey="U">Contact Name</label>
            <input name="name" type="text" id="name" tabindex="1" placeholder="Full Name" autofocus
                   required="required">
        </div>

        <div class="contact_email">
            <label class="labelstyle" for="email" accesskey="E">Email</label>
            <input name="email" type="email" id="email" placeholder="Email" tabindex="2" required="required">
        </div>

        <div class="contact_phone">
            <label class="labelstyle" for="phone" accesskey="P">Phone <small>(optional)</small></label>
            <input name="phone" type="tel" id="phone" tabindex="3">
        </div>

        <div class="contact_website">
            <label class="labelstyle" for="web" accesskey="W">Website <small>(optional)</small></label>
            <input name="website" type="text" id="web" tabindex="4">
        </div>


        <div class="contact_comment">
            <label class="textareaLabel" for="comments">Comments Length:<span id="length"></span></label>
            <textarea name="comments" id="comments" spellcheck="true" placeholder="Your Message" tabindex="6"
                      required="required"></textarea>
        </div>

        <div id="recaptcha" class="g-recaptcha" data-sitekey="6Le0QrobAAAAAGDacgiAr1UbkPmj0i-LFyWXocfg"
             data-callback="correctCaptcha"></div>

        <div id="message">
            <img class="notice" src="assets/images/email.png" alt="email icon">
            <img class="pen" src="assets/images/fountain-pen-close-up.png" alt="fountain pen">
        </div>

        <button id="submitForm" class="submit_comment" type="submit" name="submit" value="Submit" tabindex="7"
                data-response="">Submit
        </button>
        <!-- Use a data callback function that Google provides -->
    </form>
</main>


<aside class="sidebar">
    <div id="successMessage" class="successStyle" style="display: none;color: #009578;">Your email has been sent successfully!
    </div>
    <ul class="cards">
        <li class="card-item">
            <a href="https://flickr.com/photos/pepster/">
                <figure class="cards">
                    <img src="assets/images/img_flickr_pictures.jpg" alt="Flickr" width="348" height="174">
                    <figcaption class="caption">
                        <h3 class="caption-title">Flickr Images</h3>
                    </figcaption>
                </figure>
            </a>
        </li>
        <li class="card-item">
            <a href="https://github.com/Strider64/brain-wave-blitz">
                <figure class="cards">
                    <img src="assets/images/img_github_repository.jpg" alt="GitHub Repository">
                    <figcaption class="caption">
                        <h3 class="caption-title">GitHub Repository</h3>
                    </figcaption>
                </figure>
            </a>
        </li>
        <li class="card-item">
            <a href="https://www.facebook.com/groups/822623719581172/">
                <figure class="cards">
                    <img src="assets/images/img-facebook-group.jpg" alt="FaceBook Group">
                    <figcaption class="caption">
                        <h3 class="caption-title">Facebook Group</h3>
                    </figcaption>
                </figure>
            </a>
        </li>
    </ul>
</aside>

<footer class="colophon">
    <p>&copy; <?php echo date("Y") ?> Brain Wave Blitz - <span class="freepik_icons">Icons made by <a
                    href="https://www.freepik.com" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/"
                                                                                       title="Flaticon">www.flaticon.com</a></span>
    </p>

</footer>

<script src="assets/js/contact.js"></script>
</body>
</html>```

My point is it's easier to follow and debug when things go wrong. The full code can be found at my repository -> [https://github.com/Strider64/brain-wave-blitz](https://github.com/Strider64/brain-wave-blitz)

I'm sure someone with more jQuery can help you out better than I can. I like using Vanilla JavaScript as it's easy to transport from one project to another and I found out that it really doesn't use all that more coding. It's actually about the same when you factor in the jQuery Library.

Here’s a laundry list of points for this code -

  1. don’t use output buffing to make your code work. fix whatever is causing the problem.
  2. use ‘require’ for things your code must have.
  3. include/require are not functions. the () do nothing. leave them out.
  4. there’s no consistency in where you are storing required files.
  5. it appears that inc/header.php is part of the html document. you should require it after the form processing code.
  6. the code for any page should be laid out in this general order - 1) initialization, 2) post method form processing, 3) get method business logic - get/produce data needed to display the page, 4) html document.
  7. the post method form processing should first detect if a post method form was submitted.
  8. you need to trim all input data before validating it.
  9. you need to validate all inputs on the server before using them.
  10. by using the same root name ‘list’ for all the form fields, it makes using the data more difficult. the root name for the location should be different from the checkbox root name.
  11. the redirect you perform upon successful completion of the post method form processing should be to the exact same URL of the current page to cause a get request for that page. this will prevent the browser from trying to resubmit the form data should that page get reloaded or browsed away from and back to.
  12. if there are server-side validation errors, you need to output the correct number of fields and repopulate the fields/checked checkboxes with existing data so that the user doesn’t need to keep reentering data over and over.
  13. if the last dynamically added set of fields is empty, you either need to make it ‘required’ and expect the user to remove it if it is not used or you need to detect it and remove it on the server before processing the form data.
  14. no php code will get executed following an exit; statement.
  15. the jquery version you are using is ancient and should be updated to the latest 3 version.
  16. you need to validate the resulting web pages at validator.w3.org
  17. the point of a <label>...</label> is it is associated with a specific form field, so that when you click anywhere on the label it is the same as clicking on the corresponding field. therefore, there should be one label per form field.
  18. for a label to work, you must either have a for=’…’ attribute in the opening label tag and a matching id=’…’ attribute in the field OR you must put the field between the label tags with the label text.
  19. the existing preventDefault() calls do nothing for the events being used.
  20. you should number the dynamically added field index by getting the current number of fields using the .length property.
  21. any dynamic value you output in a html context needs to have htmlentities() applied to it to help prevent cross site scripting.
  22. to validate (count) the number of checked checkboxes per location, you need to find, then count them per a specific container class in the document.

Here’s example code that addresses most of these points -

<?php

// initialization
session_start();

require 'database1.php';
require '../inc/config.php';
require ROOT_PATH . 'inc/functions.php';

authCheck('maintenance');

// examine the input data
echo '<pre>'; print_r($_POST); echo '</pre>';

// post method form processing
if (!empty($_POST['list']))
{
	$items = $_POST['list'];
	$json = json_encode($items);
	$results = $db->prepare("INSERT INTO checkboxform (content) VALUES (?)");
	$results->bindParam(1,$json);
	$results->execute();
	header("Location: viewlocation1.php");
	exit;
}

// html document
?>
<?php require ROOT_PATH . 'inc/header.php'; ?>
<!--Jquery Link-->
<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<link rel="stylesheet" href="main.css?ver=1.2">

<section class="login">
<div class="container">
<center><p><a id="link" href="/demoadmin/maintenance/index.php"><b><h2>Maintenance Admin</h2></b></a></p></center>

<form method="post">
<fieldset id="business-details">
<?php
// define the type choices
$types['water'] = "Water";
$types['powder'] = "Dry Powder";
$types['foam'] = "Foam";
$types['CO2'] = "CO2";
$types['chemical'] = "Chemical";

foreach(array_keys($_POST['location']??[0]) as $key)
{
	?>
	<div class="container chk">
	<label>Fire Extinguisher Location <input type="text" name="location[<?=$key?>]" value="<?=htmlentities($_POST['location'][$key]??'',ENT_QUOTES)?>" required></label>
	<div>Type -</div>
	<?php
	foreach($types as $name=>$label)
	{
		$chk = isset($_POST['type'][$key][$name]) ? 'checked' : '';
		?>
		<div><label><input type="checkbox" name="type[<?=$key?>][<?=$name?>]" <?=$chk?>><?=$label?></label></div>
		<?php
	}
	?>
	</div>
	<?php
}
?>
</fieldset>
<a href="#" id="add-row">+</a> Add Another Location

<?php require ROOT_PATH . 'inc/captcha.php'; ?>

<button type="submit" class="button">Submit</button>
</form>

</div>
</section>

<p><center><img src="/256.jpg" class="responsive"></center></p>

<script>
$(document).ready(function() {
	//Once remove button is clicked
	$('#business-details').on('click', '.remove-field', function(e) {
		$(this).parent('.container').remove();
	});
	
	//Once add button is clicked
	$('#add-row').click(function(e) {
		// generate the array index by counting the existing number of elements
		var x = $("input[name^=location]").length;
		var list_fieldHTML = '<div class="container chk">' +
		'<label>Fire Extinguisher Location ' +
		'<input type="text" name="location['+x+']" required></label>' +
		'<div>Type -</div>' +
		'<div><label><input type="checkbox" name="type['+x+'][water]">Water</label></div>' +
		'<div><label><input type="checkbox" name="type['+x+'][powder]">Dry Powder</label></div>' +
		'<div><label><input type="checkbox" name="type['+x+'][foam]">Foam</label></div>' +
		'<div><label><input type="checkbox" name="type['+x+'][CO2]">CO2</label></div>' +
		'<div><label><input type="checkbox" name="type['+x+'][chemical]">Chemical</label></div>' +
		'<br><a href="#" class="remove-field">-</a> Remove Location</div>';
		$('#business-details').append(list_fieldHTML);
	});
});
</script>

<script>
$(document).ready(function(){
	$("form").submit(function(e){
		// loop over a collection of .chk elements
		$(".chk").each(function() {
			var y = $(this).find('input[type=checkbox]:checked').length;
			if (y < 1){
				// I would instead display a message near the relevant checkboxes
				alert("Please select at least one fire extinguisher type !");
				e.preventDefault();
			}
		});
	});
});
</script>

<?php require ROOT_PATH . 'inc/footer.php'; ?>
Sponsor our Newsletter | Privacy Policy | Terms of Service