zen of coding

Multiple checkboxes

One question that I’ve seen come up a few times is: “How do I handle multiple checkboxes in a form?”
The only trick here is the way you name your checkbox form element. Let’s consider an example where you’d like to select multiple messages (by using checkboxes) and then delete these messages in your controller.

Let’s say that in your controller you did a $messages = $this->Message->find… and you have set the resulting array for the view $this->set(‘messages’, $messages).
Now, in the view you will loop through all the $messages and construct a form by doing something like this:

[sourcecode language=’php’]

checkbox(‘Messages.id.[‘.$message[‘Message’][‘id’].’]’, array(‘value’ => $message[‘Message’][‘id’])); ?> link($message[‘Message’][‘subject’], ‘/messages/read/’.$message[‘Message’][‘id’]);?>


[/cc]

So your checkboxes will now be named Messages.id.[1], Messages.id.[2], Messages.id.[3]… and so on.

Now if you’d like to delete all selected messages, do this in your ‘deleteMsg’ action in the controller:

[sourcecode language=’php’]
data[‘Messages’] as $key => $value) {
if($value != 0) {
$this->Message->del($value);
}
}
[/cc]

 

  • joe mak

    Thanks a lot!
    You make the life easier.

  • teknoid

    @joe mak

    No problem, glad to help.

  • John

    Shouldn’t it be foreach($this->data[‘Messages’][‘id’] as $key => $value)? And do you need to set the value? If you don’t, the value will be set to 1 when the user selects it, thus satisfying the if statement.

  • teknoid

    @John

    foreach() works with arrays, so you loop through all id’s and delete each one, the code above is correct.

    There is another option to use deleteAll(), if you don’t want to do the foreach() loop.

  • Very useful resource.. best I found on arrays for checkboxes in cake.. I will book mark this.

    many thanks :D

  • teknoid

    @james mikkelson

    You’re welcome ;)

  • very useful indeed , nice site bro

  • teknoid

    @mzee.richo

    Thanks

  • Should row #3 not be this:
    checkbox(‘Messages.id.’.$message[‘Message’][‘id’].”, array(‘value’ => $message[‘Message’][‘id’])); ?>

    This works for me. So thank you :)

  • @Mathieu

    The proposed solution works as well, but if you prefer another method that’s really up to you.
    I’m sure though this is slightly outdated as cake has grown in some automagical ways it handles the check boxes since the time of writing.

  • kryska

    I am a newbie…What`s wrong here?:

    view index.ctp:

    checkbox(‘Clientes.id.[‘.$cliente[‘Cliente’][‘id’].’]’, array(‘value’ => $cliente[‘Cliente’][‘id’])); ?>

    link(‘Borrar’,array(‘action’=>’borrarseleccionados’)) ?>

    clientes_controller:
    function borrarseleccionados() {
    foreach($this->data[‘Clientes’] as $key => $value) {
    if($value != 0) {
    $this->Cliente->del($value);
    }
    }
    }

    I get the error:Invalid argument supplied for foreach() but i dont know why…..
    Thank you very much!

  • @kryska

    what’s the value of $this->data[‘Clientes’]?

  • kryska

    I dont know, i guess teh value ot $this->data[‘Clientes’] is nothing…

    view index.ctp:
    $cliente[‘Cliente’][‘id’]));
    echo $html->link(‘Borrar’,array(‘action’=>’borrarseleccionados’)) ?>

    clientes_controller:
    function borrarseleccionados($value) {
    foreach($this->data[‘Clientes’] as $key => $value) {
    if($value != 0) {
    $this->Cliente->del($value);
    }
    }
    }

    In this case, if i write “function borrarseleccionados($value) “…the error is:Missing argument 1 for ClientesController::borrarseleccionados().
    Is wrong that $value=$cliente[‘Cliente’][‘id’] ?

    Please, help me!
    Thank you very much!

  • Chrono

    Hey!

    This Code doesn’t work if Security Componment is enabled? Do you have a solution anyway?

    Thank you in advance,
    Chrono

  • Chrono

    Hey again!

    use Messages.$id.id instead of Messages.id.$id to let it work with Security componment. Of course you’ll need to change the foreach loop, too! ;-)

    checkbox(‘Messages.’.$message[‘Message’][‘id’].’.id’, array(‘value’ => $message[‘Message’][‘id’]));
    ?>

    Best regards
    Tim

  • @Chrono

    Hey Choro, thanks for sharing your solution. This post is rather old, so I’m sure things have changed in the core since then. But this will be helpful to many people.

    So thanks again.

  • bhoomi

    hi..
    it prints the checked data which is checked in check box

  • @bhoomi

    What prints the data?

  • trace

    hi, I’m new to cakephp..

    I have a problem regarding checkboxes..
    please help me out..

    my code goes like this:

    checkbox(‘done’);

    foreach($prodGroupData as $arr)
    {
    echo $arr[‘ProductGroup’][‘PROD_GROUP_NO’] . &nbsp .
    $arr[‘ProductGroup’][‘PROD_GROUP_NAME’] . &nbsp .
    $form->checkbox(‘done’);
    }
    ?>

    so each checkbox other than the first is created individually..

    now the thing is,
    if i ticked off the first checkbox, all the generated checkbox has to be checked..
    same should happen if i uncheck the main checkbox…

    please help…

  • @trace

    This is not a really a cake question. It is done with javascript.

    Please google for something like “Automatically check/uncheck multiple checkboxes”

  • bond681

    hi!

    i’ve tried you code but it does not works for me :(

    Can you please tell me what is wrong with this:

    My View:

    Name
    Phone
    Delete

    checkbox(‘contacts.id.[‘.$contact[‘Contact’][‘id’].’]’, array(‘value’ => $contact[‘Contact’][‘id’])); ?>

    image(“/img/menu/ex.png”, array(“alt” => “”,’url’ => array(‘controller’=>’Contacts’, ‘action’=>’delete’,$contact[‘Contact’][‘id’]))); ?>
    // if i put $contact[‘Contact’][‘id’] in my html link it always sends the last row’s id

    My controller:

    // it doesn’t do anything

    function delete(){
    if(!empty($this->data)){
    foreach($this->data[‘Contact’] as $key->$value){
    if($value !=0){
    $this->Contact->del($value);
    }
    }

    }
    }
    }

    thanks for you help

  • bond681

    sorry there is a mistake in my post in here is the correct one:

    My View:

    Name
    Phone
    Delete

    checkbox(‘contacts.id.[‘.$contact[‘Contact’][‘id’].’]’, array(‘value’ => $contact[‘Contact’][‘id’])); ?>

    image(“/img/menu/ex.png”, array(“alt” => “”,’url’ => array(‘controller’=>’Contacts’, ‘action’=>’delete’,$contact[‘Contact’][‘id’]))); ?>
    // if i put $contact[‘Contact’][‘id’] in my html link it always sends the last row’s id

    My controller:

    // it doesn’t do anything

    function delete(){
    if(!empty($this->data)){
    foreach($this->data[‘Contact’] as $key->$value){
    if($value !=0){
    $this->Contact->del($value);
    }
    }

    }
    }
    }

    thanks for you help

  • Thank you! A simple answer to a simple question :-)

  • in cakePHP 1.3.2

    use echo $form->checkbox(‘Messages.id.$message[‘Message’][‘id’], array(‘value’ => $message[‘Message’][‘id’]));

    instead of
    echo $form->checkbox(‘Messages.id.[‘.$message[‘Message’][‘id’].’]’, array(‘value’ => $message[‘Message’][‘id’]));

  • @Revath S Kumar
    For the given example, it should still work… but to keep consistent with format for saveAll(), you first approach would be required.

  • Raymond

    Thanks.
    I believe it is the most easy-implement solution for multi-checkbox in cakePHP.

  • hi,
    For me it didn’t work like this

    foreach($this->data[‘Messages’] as $key => $value) {
    if($value=!0) {
    $this->User->del($value);
    }
    But like this :

    foreach($this->data[‘Messages’] as $key => $value) {
    if($value ) {
    $this->User->del($value);
    }

  • teknoid

    @Mehdi

    A lot has probably changed since the writing of this post…

    However ($value =! 0) doesn’t seem like a correct comparison operator ;)

  • MAYULI A. PLAZA

    sorry, I’m exporting a list of data to excel, and I would like to know if there is any way to create dynamic checkbox to select specific things from my related tables ….? if you have any information?, apologizes for this wording … I am Venezuelan …

  • teknoid

    @MAYULI A. PLAZA

    I would look at some jQuery (JS) tutorials. The things you are looking for are hardly cakephp related…

  • Hi…
    I’ve just find a nice solution…
    if you need something like array[] instead of array[something] just call
    checkbox(‘array. ‘,
    i.e. put space after dot and you will have array[ ] at a page

  • Adrian

    Hi, i tried your example in an ajax call

    function imprimir(){
    new Ajax.Updater(‘imprimir’, ‘http://localhost/gestionBioser/clientes/divImpresion’);
    }

    function divImpresion()
    {
    foreach($this->data[‘Clientes’] as $key => $value) {
    if($value != 0) {
    debug($value);
    }
    }
    $this->layout = ‘ajax’;
    }

    but this->data is empty! maybe because muy checkboxes are not in a form?

    this is the checkbox code from the view

    checkbox(‘Clientes.id.’.$cliente[‘Cliente’][‘id’], array(‘value’ => $cliente[‘Cliente’][‘id’])); ?>

    thank in advance

  • teknoid

    @Adrian

    Try to debug $this->params, to see if you have the needed data from AJAX.

  • Pingback: CakePHP1.3 お手軽な複数チェックボックスの作り方 | Code Life()

  • abc

    VERRRRRRRYYYYYYYYYYYY HELPFULLLLLLLLLLLLL!!!!! THANK YOU FOR POSTING THIS CODES

  • Freeman

    i am new to php and cakephp and i would like code to save data to mysql from a check box. my view looks like this

    1: Linux Administration:Sat and Sun 8am to 5pm (3 weeks)
    2: Networking :Mon-Fri 9am to 4pm
    3: Web Design 1 :Mon-Fri 9am to 4pm

  • That is bloody brilliant!

%d bloggers like this: