Populating checkboxes from database using PHP – only last option is getting checked

Tags: ,



I am trying to populate checkboxes with the data from my mysql database but for some reason only the last checkbox is being checked (for example if automotive, carpentry and hand tools should be checked, only hand tools is being checked) and I can’t figure out why. The mysql statement is running correctly and giving me the correct information. Here is the relevant code.

<?php

require_once('../../private/initialize.php');
require_login(); 
if(!isset($_GET['id'])) {
  redirect_to(url_for('/members/show_member_tools.php'));
}
$id = $_GET['id'];

if(is_post_request()) {

  // Handle form values sent by new.php

  $tool = [];
  $tool['tool_ID'] = $id;
  $tool['serial_number'] = $_POST['serial_number'] ?? '';
  $tool['tool_name'] = $_POST['tool_name'] ?? '';
  $tool['tool_description'] = $_POST['tool_description'] ?? '';
  $tool['tool_picture'] = $_POST['tool_picture'] ?? '';
  $category =[];
  $category = $_POST['category_ID'];
  $result = update_tool($tool, $category);

    //get info for checkboxes
    global $db;


  if($result === true) {
    $_SESSION['message'] = "The tool has been updated sucessfully";
    redirect_to(url_for('/members/show_tool.php?id=' . $id));
  } else {
    $errors = $result;
  }


} else {

  $tool = find_tool_by_id($id);
      if(isset($_GET['id'])){
    $id=$_GET['id'];
    $sql = "select category_name from category INNER JOIN tool_category ON category.category_ID = tool_category.category_ID where tool_category.tool_id=$id";
    $query = mysqli_query($db, $sql);

    while($row=mysqli_fetch_array($query)) {

//      $str = "";
      $str = $row['category_name'];
      echo $str;


      if (strpos($str , "automotive")!== false){
        $checked1 ="checked";
        echo "made it to automotive";
        } else {
        $checked1 ="";
      }

      if (strpos($str , "carpentry")!== false){
        $checked2 ="checked";
        echo "made it to carpentry";
        } else {
        $checked2 ="";
      }

      if (strpos($str , "home maintenance")!== false){
        $checked3 ="checked";
        echo "made it to home maintenance";
      } else {
        $checked3 ="";
      }

      if (strpos($str , "plumbing")!== false){
        $checked4 ="checked";
      } else {
        $checked4 ="";
      }

      if (strpos($str , "yard and garden")!== false){
        $checked5 ="checked";
      } else {
        $checked5 ="";
      }

      if (strpos($str , "hand tools")!== false){
        $checked6 ="checked";
      } else {
        $checked6 ="";
      } 

    }//end while loop    

  } //end if

} //end else
  $tool_set = find_all_tools();
  $tool_count = mysqli_num_rows($tool_set);
  mysqli_free_result($tool_set);
?>

<?php $page_title = 'Edit Tool'; ?>
<?php include(SHARED_PATH . '/header.php'); ?>

<div id="content">

  <div class="center">
    <a href="<?php echo url_for('/members/show_member_tools.php'); ?>">&laquo; Back to My Tools</a>


    <h2>Edit Tool</h2>
  </div>
    <?php echo display_errors($errors); ?>
    <form action="<?php echo url_for('/members/edit_tool.php?id=' . h(u($id))); ?>" method="post">

      <fieldset class="form">
         <img src ="<?php echo h($tool['tool_picture']); ?>"  alt="<?php echo h($tool['tool_picture']); ?>"width="150"><br>
        <label for="serial_number">Serial Number</label><br>
          <input type="text" name="serial_number" value="<?php echo h($tool['serial_number']); ?>" ><br>

        <label for="tool_name">Tool Name</label><br>
          <input type="text" name="tool_name" value="<?php echo h($tool['tool_name']); ?>" ><br>

        <label for="tool_description">Tool Description</label><br>
          <input type="text" name="tool_description" value="<?php echo h($tool['tool_description']); ?>" ><br>
        <label for="category_ID">Tool Category: </label><br>  
         <input type="checkbox" name="category_ID[]" value="1" <?php echo $checked1; ?>> <label for="1">Automotive</label> <br>
         <input type="checkbox" name="category_ID[]" value="2" <?php echo $checked2; ?>> <label for="2">Carpentry</label> <br>
         <input type="checkbox" name="category_ID[]" value="3" <?php echo $checked3; ?>> <label for="3">Home Maintenance</label> <br>
         <input type="checkbox" name="category_ID[]" value="4" <?php echo $checked4; ?>> <label for="4">Plumbing </label><br>
         <input type="checkbox" name="category_ID[]" value="5" <?php echo $checked5; ?>> <label for="5">Yard and Garden</label> <br>
         <input type="checkbox" name="category_ID[]" value="6" <?php echo $checked6; ?>> <label for="6">Hand Tools</label> <br>

        <input type="submit" value="Edit Tool" >

          <a class="block" href="<?php echo url_for('/members/delete_tool.php?id=' . $id); ?>">Delete Tool</a>

      </fieldset>

    </form>
    <div class="push"></div>
  </div>

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

Answer

You’re looping over your results. This means with every loop you’re setting one variable to “checked” and the rest to an empty string. So only the last one will be checked. The band-aid fix is to set unchecked as the default outside of the loop, and then change to checked only when it’s needed.

But the real fix is to be pulling this info from the database and working with it instead of manually mapping database IDs to labels. By moving your condition into the join, you pull all the categories. The rows that have a tool ID are checked, and the others are not. You’re also pulling the category names and IDs so you can programmatically build your checkboxes.

See here for DB sample: http://sqlfiddle.com/#!9/20b223/14/0

$tool = find_tool_by_id($id);
$tool["categories"] = [];
$sql = "SELECT c.category_name, c.category_ID, tc.tool_id
FROM category c
LEFT JOIN tool_category tc ON c.category_ID = tc.category_id
    AND tc.tool_id = ?";
$stmt = $db->prepare($sql);
$stmt->bind_param("i", $_GET["id"]);
$result = $stmt->execute();

while($row = $stmt->fetch_assoc()) {
    $id = $row["category_ID"];
    $name = $row["category_name"];
    $checked = $row["tool_id"] ? "checked" : "";
    $tool["categories"][$id] = ["name" => $name, "checked" => $checked];
}

Now later on you can do this to automatically build all your checkbox inputs:

<?php foreach ($tool["categories"] as $id=>$category): ?>
    <input type="checkbox" name="category_ID[]" id="category_<?=$id?>" value="<?=$id?>" <?=$category["checked"]?>>
    <label for="category_<?=$id?>">
        <?=htmlspecialchars($category["name"])?>
    </label><br/>
<?php endforeach ?>


Source: stackoverflow