0

I've got a page with checkboxes generated with the database. When we press the checkbox and submit it, it is working fine and it is updating in the database. But when I try to uncheck "1" checkbox it is checking out all checkboxes which are selected.

Query:

if(isset($_POST['submit'])){
                foreach ($_POST['untrain'] as $room_id => $user_id) {
                    // This query needs protection from SQL Injection!
                    $user_id;
                $untrainQuery = "UPDATE room_users SET trained = '1'  WHERE user_id = $user_id AND room_id = $room_id";
                $db->update($untrainQuery);

                }

                }

if(isset($_POST['submit'])){
                foreach ($_POST['amk'] as $room_id => $user_id) {
                    // This query needs protection from SQL Injection!
                    $user_id;
                $untrainedQuery = "UPDATE room_users SET trained = '0'  WHERE user_id = $user_id AND room_id = $room_id";
                $db->update($untrainedQuery);

                }

                }

Checkboxes:

    <?php 
if($room->trained == 1) 
{ ?> 
<input type='hidden' value="<?php echo $room->user_id; ?>" name="amk[<?php echo $room->room_id; ?>]"> 
<input type='checkbox' value="<?php echo $room->user_id; ?>" name="trained[<?php echo $room->room_id; ?>]" checked> 
<?php echo "Y"; } 
else{ ?> 
<input type='checkbox' value="<?php echo $room->user_id; ?>" name="untrain[<?php echo $room->room_id; ?>]"> 
<?php echo "N"; 
}?> 
</td>
<Td><?php 
if($room->active == 1) { 
?> <input type='checkbox' name="<?php echo $room->room_id; ?>" checked> 
<?php echo "Active"; } 
else { ?> 
<input type='checkbox' name="<?php echo $room->room_id; ?>"  
<?php echo "Inactive"; } ?>

I used the trick with the "hidden" input before the checkbox, but the only problem is that it is not working. When I click on it, it resets all checkboxes to 0.

  • 1
    Please format your code so it is easy to read. That wouldn't only be helpful for us to help you but also for you to find those kind of errors easily. The checkbox construct especially is something I, as a code reviewer, would just throw in the bin. – β.εηοιτ.βε Apr 07 '15 at 20:03

1 Answers1

0

I think you are missing how the combo checkbox + hidden input does work.

So here you go freely inspired by this answer:

<input id="foo" name="foo" type="checkbox" value="1" />
<input name="foo" type="hidden" value="0" /> 

Looks like you do know, if you use the trick, that, if the checkbox is unchecked, it will not be present in the post. So to trick the form, we will always add an hidden field. And if the checkbox is checked, then the fact that it will be included in the post is going to override the value of the hidden input.

So for your specific problem :

<td>  
    <input type="checkbox" value="1" name="trained[<?php echo $room->room_id; ?>_<?php echo $room->user_id; ?>]" <?php echo ($room->trained == 1) ? ' checked' : '' ?> /> Trained
    <input type="hidden" value="0" name="trained[<?php echo $room->room_id; ?>_<?php echo $room->user_id; ?>]"/> 
</td>

Please note the use of the ternary operator on this part of the code <?php echo ($room->trained == 1) ? ' checked' : '' ?> which I may use a lot when writing html template.

Please also note the trick on the name trained[<?php echo $room->room_id; ?>_<?php echo $room->user_id; ?>] which is needed because we cannot set the user_id as value of the input.

Then for the processing part :

if ( isset ( $_POST['submit'] ) ) {
    foreach ( $_POST['trained'] as $ids => $value ) {
        // This query needs protection from SQL Injection! 
        // ^ good point, on which I would suggest you using PDO and prepared statement :)
        list($room_id,$user_id) = explode('_',$ids);
        // ^ now need to explode the name on the underscore to get both user_id and room_id cf the trick above
        $untrainQuery = "UPDATE room_users SET trained = '$value'  WHERE user_id = $user_id AND room_id = $room_id";
        $db->update ( $untrainQuery );
    }
}

Wash, rinse, repeat for every checkbox you need and you should be good to go.

β.εηοιτ.βε
  • 33,893
  • 13
  • 69
  • 83