0

Table

id  name            level   delete_user

1   visitor         1       N
2   user            2       N
3   moderator       3       N
4   administrator   4       Y

Then I fetch array from database:

$groups = array (
    array ( 'id' => 1, 'name' => 'visitor', 'level' => 1, 'delete_user' => 'N'),
    array ( 'id' => 2, 'name' => 'user', 'level' => 2, 'delete_user' => 'N'),
    array ( 'id' => 3, 'name' => 'moderator', 'level' => 3, 'delete_user' => 'N'),
    array ( 'id' => 4, 'name' => 'administrator', 'level' => 4, 'delete_user' => 'Y')
);

Then I create simple FORM to show actual settings of groups.

<form action="" method="post">
    <table class="groups">
        <thead>
            <tr>
                <td>name</td>
                <td>level</td>
                <td>delete user</td>
            </tr>
        </thead>
        <tbody>
            <?php foreach ($groups as $group) { ?>
                <?php 
                    $checkbox['delete_user_' . $group['id']] = 'N';
                    $checked = ($group['delete_user'] === 'Y') ? 'checked="checked"' : '';
                ?>    
                <tr>
                    <td><?php echo $group['name']; ?></td>
                    <td><?php echo $group['level']; ?></td>
                    <td>
                        <input type="checkbox" name="delete_user_<?php echo $group['id']; ?>" <?php echo $checked; ?> value="Y">
                    </td>
                </tr>
                <?php
            }
            ?>
        </tbody>    
    </table>
    <input type="submit" name="save_groups" value="Save" class="save_button">
</form>

Question: How to check if checkbox checked or not, and if checked then change it in database?

My work:

This is raw idea, but not pretty ...

<?php
if (isset($_POST['save_groups'])) {

    foreach ($_POST as $k => $v) {
        if (array_key_exists($k, $checkbox)) {
            $checkbox[$k] = $v;
        }
    }
    echo 'NEW';
    print_r($checkbox);
    echo '<hr>';
    foreach($checkbox as $k => $v) {
        $id = str_replace('delete_user_', '', $k);
        echo 'changing '. $id . ' to '. $v. '<br>';
        // changing value
        /**
         * $id int - id of group
         * $v string - value in delete_user ('Y' / 'N')
         */
        $this->change_value($id, $v);
    }

}
2
  • does it have to be send when it gets checked or once a button is pressed Commented Jun 5, 2014 at 14:47
  • when submit form, there for when button is pressed Commented Jun 5, 2014 at 15:40

3 Answers 3

3

While unchecked checkboxes will not be serialized during form submission, you can simply take advantage of this very common trick:

To determine whether checkbox is checked or not, you can prepend <input type="hidden" /> before a checkbox itself, like this:

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

So if a checkbox is checked, $_POST['foo'] will contain 1, and if its not checked, then $_POST['foo'] will contain 0

Sign up to request clarification or add additional context in comments.

4 Comments

Instead of opening your web app up like this, you could simply query the database twice to determine which delete_user fields are set to 'N' and which ones are set to 'Y'. With this information in two arrays stored in $_SESSION, ahead of displaying the actual form, the technique above becomes unnecessary (and more of a risk, if anything).
Well, no I simply do something like this: When it comes to scenario like removing users by checked inputs, I simply name those checkboxes as <input type="checkbox" name="toDelete[id]" /> where id is an id generated inside foreach before a page appeared. Then to get selected ids, I submit a form and I simply retrieve selected ids like array_keys($_POST['toDelete']) and that's it. No need to query a database at all! Then we have what we need - an array of only checked inputs (their ids to be exact)
Well, not "at all." You mean one query instead of two. What the person who asked the question forgot to mention is that 'N' must be the default state of delete_user field. Otherwise, it would not be sufficient to delete users only. You are assuming that updating the record means DELETE. I am not. Your solution assumes you only need to do 1/2 of the work. Mine assumes there is another 1/2 of work to do.
In other words, what is the point of updating the delete_user field if all you intend on doing is deleting it from the table? He wants to change the value, not use DELETE to delete the record. Thus, you must have a system to keep track of the original state of the delete_user field for each record before you try to update it.
0

One approach would be to make the checkbox into an array and change it so it returns the group ID, not just a "Y". UPDATE: Based on Anthony's comment below, you need to track the existing check state too:

<td>
    <?php if ($group['delete_user'] === 'Y') { ?>
    <input type="hidden" name="existing[]" value="<?php echo <?php echo $group['id']; ?>">
    <?php } ?>
    <input type="checkbox" name="delete_user[]" <?php echo $checked; ?> value="<?php echo <?php echo $group['id']; ?>">
</td>

Now all you have to do in your POST code is:

<?php
$previously_checked = $_POST['existing'];
$group_ids = $_POST['delete_user'];
$updated_state = array();

// Check if previously-selected checkbox has been unchecked
foreach($previously_checked as $group_id) {
   if (!in_array($group_id, $group_ids)) {
      $updated_state[] = array('group_id' => $group_id, 'delete_user' => 'N');
   }
}
// Check for currently-selected checkbox was previously unchecked
foreach($group_ids as $group_id) {
   if (!in_array($group_id, $previously_checked)) {
      $updated_state[] = array('group_id' => $group_id, 'delete_user' => 'Y');
   }
}

// Do the update...

1 Comment

@AnthonyRutledge: Good point. There's really three cases to deal with: unchanged; was unchecked, now checked; and was checked, now unchecked.
0

Don't do what @Scorpion, @Ken, or what I wrote earlier. Simply give all your checkbox input controls their own name based on the id (primary key) (like you started out doing) and during your input validation, use isset($_POST['yourKeyHere']) to detrmine if the record's checkbox has been successfully submitted or not. If so, run a "positive" UPDATE on the associated record. If not, run a "negative" update on the record. Simple and sweet, if not a bit wasteful. This method does not compromise the security of your form application, but it may run unnecessary updates on your table (because the field is already either 'N' or 'Y').

You don't want to invite people to submit garbage to your app. Oh, there's a way to do that simply by changing the HTML, but when the checkbox is unchecked, I do not want my backend to receive anything for that input control!

4 Comments

My new approach is to capture all checked checkboxes. And before submiting checked values, I reset all values in database to N. So after that I set values to Y only those checkboxes which was checked.
Whatever works for the scenario you are working in, good. Never submit unnecessary data to your app. Good job.
Still considering another approaches.
@Ing.MichalHudak As you should be. As you should be.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.