0

I have the following code in my form to submit multiple checkbox

application/views/form.php

<form action="<?php echo base_url().'admin/addMessage/'.$pd_name; ?>" method= "POST">
<div class="form-group">
    <label><strong>Message Type *</strong></label>
    <input type="text" class="form-control" name="msg_type" id="msg_type" placeholder="Enter Message Type" required>
</div>
<label><strong>Message Bit *</strong></label>
<div class="form-group">
    <div class="checkbox">             
        <table class="table">
        <tbody>
        <tr>
            <td><label>          P-1    &nbsp;&nbsp;</label><input type="checkbox" checked disabled readonly /></td>
            <td><label id="P17"> P-17   &nbsp;&nbsp;</label><input name="bitmsg" type="checkbox"  value="P17"/></td>
            <td><label id="P33"> P-33   &nbsp;&nbsp;</label><input name="bitmsg" type="checkbox" value="P33" /></td>
            <td><label id="P49"> P-49   &nbsp;&nbsp;</label><input name="bitmsg" type="checkbox" value="P49"/></td>
            <td><label id="S65"> S-65   &nbsp;&nbsp;</label><input name="bitmsg" type="checkbox" value="S65" /></td>
            <td><label id="S81"> S-81   &nbsp;&nbsp;</label><input name="bitmsg" type="checkbox"  value="S81" /></td>
            <td><label id="S97"> S-97   &nbsp;&nbsp;</label><input name="bitmsg" type="checkbox" value="S97" /></td>
            <td><label id="S113"> S-113 &nbsp;&nbsp;</label><input name="bitmsg" type="checkbox" value="S113"/></td>
        </tr>
        </tbody>
        </table>
    </div>
</div>
<button type="button" class="btn btn-default" id="reset" data-dismiss="modal">Cancel</button>
<button type="submit" value="submit" class="btn btn-primary"> Add New Message Type</button>
</form>

application/controller/Admin.php

public function addMessage($pdID)
{
    $this->load->helper('form');
    $this->load->library('form_validation');

    $this->form_validation->set_rules('msg_type', 'MessageType', 'required');


    if ($this->form_validation->run() == FALSE)
    {   
        echo '<script>alert("Please Select Valid Message Type"); window.history.back();</script>';
    }
    else
    {
        $this->model_general->set_message($pdID);
    }

}

application/models/Model_general.php

function set_message()
{
    $this->load->helper('url');
    $this->load->helper('form');

    //set default values    
    $dbEntry = array(
        'P17'  => 0,'P33' => 0,'P49' => 0,'S65' => 0,'S81' => 0,'S97' => 0,'S113' => 0
    );

    $postData = $this->input->post();

    foreach ($postData as $key => &$v) {

        if (array_key_exists($key, $dbEntry)) {

            $dbEntry[$key] = 1;
        }
        elseif ($key == 'bitmsg') {

            $dbEntry[$v] = 1;
        }
        else {

            $dbEntry[$key] = $v;
        }
    }

    $this->db->insert('msg_format', $dbEntry);
}

I did select all checkbox.. but $postData only return the last checkbox that i checked. E.g:

$postData return "MsgType1,0,0,0,0,0,0,1" <<= if select all

$postData return "MsgType2,0,0,0,0,0,1,0" <<= if i select all except S-113

Something missing and I couldn't find it.. :/

1 Answer 1

1

You have made it so that the name of the checkbox is the same and thus there is only ever one post entry that is submitted and it has a name of bitmsg. So, when you iterate you are checking if $key is in the array, but $key is always bitmsg in this case. As a result your first if statement never is true. Your elseif statement ends up true once because your post array contains just one entry for bitmsg (as is the case when your array key is always the same - one key has one value and the value is the last one that is set). This explains the behavior you saw where the last item checked in order was the only one to return what you expected. As for your else statement, I am not sure what your intent was. By having a pre-populated $dbEntry array with zeros as values, you already have an 'else' condition implicitly.

As an alternative, if you know that your list is always the keys listed in $dbEntry, then in your html form generation do something like:

<?php foreach ($dbEntry as $key => $v): ?>
    <td><label id="<?php echo $key; ?>"> <?php echo $key; ?> &nbsp;&nbsp;</label><input name="<?php echo $key; ?>" type="checkbox" value="true"/></td>
<?php endforeach; ?>

If you aren't comfortable with that, then just ensure that in your form you change name to the keys in $dbEntry.

Then, your set_message() foreach should look like this if you follow your approach:

foreach ($postData as $key => $v) {
    if (array_key_exists($key, $dbEntry)) {
        $dbEntry[$key] = 1;
    }
}

Note though, that generally it's better to work with data you're supplying and check inputs against it. Your model foreach code would look like:

foreach ($dbEntry as $key => $v) {
    if (array_key_exists($key, $postData)) {
        $dbEntry[$key] = 1;
    }
}

Or the lazy way, you can change the name to an array by using bitmsg[] as the name instead of bitmsg:

<td><label id="S113"> S-113 &nbsp;&nbsp;</label><input name="bitmsg[]" type="checkbox" value="S113"/></td>

Then in your model change $this->input->post() to $this->input->post("bitmsg"); so that your post data is the array of items selected. In this case $key will always be an integer index and the value will be the value of the selected checkboxes. So your model foreach loop could look like:

foreach ($postData as $v) {
    if (array_key_exists($v, $dbEntry)) {
        $dbEntry[$v] = 1;
    }
}

The same note about swapping $dbEntry and $postData applies here too:

foreach ($dbEntry as $key => $v) {
    if (array_key_exists($v, $postData)) {
        $dbEntry[$key] = 1;
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Firstly.. thank you very much for your detail explanation.. FYI.. there are other fields that I need to insert (which I didn't show in the code) and there are other keys that I need to consider so first alternative is not an option for my html form. I've tried to use array for 'bitmsg[]' as well but i cannot use '$this->input->post("bitmsg");' because it will only return value for bitmsg[] but not other input->post values.. I'll try out your other suggestions.. will update here later..
Without the context of what that other data is, it may be hard for someone to meaningfully answer. If you want to iterate through all post data and use the bitmsg[] method, you can just have an if inside your $postData foreach that checks if $key is bitmsg and do a nested foreach on that array because now it'll be an array of values under that one key inside the post return.
I changed the name to the $keys in $dbEntry.. and it works.. but i need to add extra checking in set_message() because it effect other fields in my form. my form contain mix type of input include checkboxes, radio, dropdown option and normal input text. some of $key are using same name.. so I need to change it accordingly. But well.. as long as it worked for my multi checkboxes.. i don't mind changing.. :) Thanks again for your advice..

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.