Create Multiple Checkboxes Instead of a Multiple-Select in your Views

By Joshua McFarren (joshuamcfarren)
From a usablitiy stand point, multiple-select boxes are a nightmare. Forget to hold down the modifier key when adding an option and you loose all your selections. When the number of options are managable, multiple checkboxs are a better choice for average users. This functionality is coming to cake in future versions but you can have it now with this helper.
Save this as habtm.php in app/views/helpers
Download code <?php
class HabtmHelper extends HtmlHelper {
    
    
/**
     * Returns a list of checkboxes.
     *
     * @param string $fieldName Name attribute of the SELECT
     * @param array $options Array of the elements (as 'value'=>'Text' pairs)
     * @param array $selected Selected checkboxes
     * @param string $inbetween String that separates the checkboxes.
     * @param array $htmlAttributes Array of HTML options
     * @param  boolean $return         Whether this method should return a value
     * @return string List of checkboxes
     */
    
function checkboxMultiple($fieldName$options$selected null$inbetween null$htmlAttributes null$return false) {
        
$this->setFormTag($fieldName);
        if (
$this->tagIsInvalid($this->model$this->field)) {
            if (isset(
$htmlAttributes['class']) && trim($htmlAttributes['class']) != "") {
                
$htmlAttributes['class'] .= ' form_error';
            } else {
                
$htmlAttributes['class'] = 'form_error';
            }
        }
        if (!
is_array($options)) {
            return 
null;
        }    
        if (!isset(
$selected)) {
            
$selected $this->tagValue($fieldName);
        }
        foreach(
$options as $name => $title) {
            
$optionsHere $htmlAttributes;
            if ((
$selected !== null) && ($selected == $name)) {
                
$optionsHere['checked'] = 'checked';
            } else if (
is_array($selected) && array_key_exists($name$selected)) {
                
$optionsHere['checked'] = 'checked';
            }
            
$optionsHere['value'] = $name;
            
$checkbox[] = "<li>" sprintf($this->tags['checkboxmultiple'], $this->model$this->field$this->parseHtmlOptions($optionsHere), $title) . "</li>\n";
        }
        return 
"\n" sprintf($this->tags['hiddenmultiple'], $this->model$this->fieldnull$title) . "\n<ul class=\"checkboxMultiple\">\n" $this->output(implode($checkbox), $return) . "</ul>\n";
    }
    
}
?>

Add this snip of css to your stylesheet and adjust the li width to your taste
Download code ul.checkboxMultiple {
    margin:0;
    padding:0;
    list-style-type:none;
    }
ul.checkboxMultiple li {
    display:block;
    float:left;
    width: 220px;
    margin: 0 8px 0 0;
    }

And add these tag templates to app/config/tags.ini.php
Download code ; Tag template for an input type='hidden' tag.
hiddenmultiple = "<input type="hidden" name="data[%s][%s][]" %s/>"

; Tag template for a input type='checkbox ' tag.
checkboxmultiple = "<input type="checkbox" name="data[%s][%s][]" %s/>%s"

Then you can use the new helper exactly the same way as $html->selectTag(...) just change your method call to $habtm->checkboxMultiple(..) instead.

Acknowledgment: This is based off code by MrRio in the Trac system:
https://trac.cakephp.org/ticket/1260

 

Comments 294

CakePHP Team Comments Author Comments
 

Comment

1 Displaying many options

If you alter the CSS for the UL slightly you can accommodate many options on the form and not have them break the layout too much:

ul.checkboxMultiple {
margin:0;
padding:0;
height: 8em;
overflow: auto;
list-style-type:none;
}

This will limit the list to 8(ish) visible items and provide display scrollbar to reach the others.
Posted Mar 20, 2007 by RichardAtHome
 

Comment

2 Tags and Naming

I've had a problem with using checkboxes for the longest time and this seems to be a great solution, thanks for putting it together. A couple issues came out of trying to use this though.. first, I don't have any tag definitions for 'hiddenmultiple' or 'checkboxmultiple'. I removed the 'multiple's from those definitions, and put in the $title var and got it to sort of work, but then comes the issue of naming the field. i.e., I have a 'Language' with a HABTM to 'Profile', and normally, I'd name the field 'Language/Language', but that doesn't seem to work in this case. It might work fine once we get those tag definitions though. Thanks again...

-ascendvisual
Posted Mar 20, 2007 by Chris Forrette
 

Comment

3 Tag Templates Added Above

Sorry about that Chris, I forgot the tag templates from the trac page. Doh!
Posted Mar 20, 2007 by Joshua McFarren
 

Comment

4 labels for checkboxes

I wanted labels attached to each check box for improved usability, so changed the definition of checkboxmultiple format in tags.ini.php to:

checkboxmultiple=<input type="checkbox" name="data[%s][%s][]" %s/>
i.e. removed the final %s and modified the helper function internals to:

/**
 * Returns a list of checkboxes.
 *
 * @param string $fieldName Name attribute of the SELECT
 * @param array $options Array of the elements (as 'value'=>'Text' pairs)
 * @param array $selected Selected checkboxes
 * @param array $htmlAttributes Array of HTML options
 * @param array $containerAttributes Array of HTML attributes used for the containing tag
 * @param boolean $showEmpty If true, the empty checkbox option is shown
 * @param  boolean $return         Whether this method should return a value
 * @return string List of checkboxes
 */
    function checkboxMultiple($fieldName, $options, $selected = null, $htmlAttributes = null, $containerAttributes = null, $showEmpty = true, $return = false) {
        $this->Html->setFormTag($fieldName);
        if ($this->Html->tagIsInvalid($this->Html->model, $this->Html->field)) {
            if (isset($htmlAttributes['class']) && trim($htmlAttributes['class']) != "") {
                $htmlAttributes['class'] .= ' form_error';
            } else {
                $htmlAttributes['class'] = 'form_error';
            }
        }
        if (!is_array($options)) {
            return null;
        }
        if (!isset($selected)) {
            $selected = $this->Html->tagValue($fieldName);
        }
        if ($showEmpty == true) {
            $checkbox[] = sprintf($this->tags['hiddenmultiple'], $this->Html->model, $this->Html->field, $this->Html->parseHtmlOptions($htmlAttributes));
        }
        foreach($options as $name => $title) {
            $optionsHere = $htmlAttributes;
            if (!isset($htmlAttributes['id'])) {
            $optionsHere['id'] = $this->Html->model . Inflector::camelize($this->Html->field) . $name;
            }
            $optionsHere['value'] = $name;
            if (($selected !== null) && ($selected == $name)) {
                $optionsHere['checked'] = 'checked';
            } else if (is_array($selected) && array_key_exists($name, $selected)) {
                $optionsHere['checked'] = 'checked';
            }
            $checkbox[] = "<li>" . sprintf($this->tags['checkboxmultiple'], $this->Html->model, $this->Html->field, $this->Html->parseHtmlOptions($optionsHere), $title)
                                 . $this->Form->labelTag($fieldName . $name, $title) . "</li>\n";
        }
        return "\n<ul".$this->Html->parseHtmlOptions($containerAttributes).">\n" . $this->Html->output(implode($checkbox), $return) . "</ul>\n";
    }
As you can see I've added the labelTag() method of the form helper to it, so we need to include the 'Form' helper in the array of helpers that this helper uses.

I've also added the id attribute to the optionsHere array for each option, so that the label has something to attach itself to.

I also wanted its use to be transparent with the Html helper's selectTag() method for multiple selects so modified the prototype by removing $inbetween and adding a $containerAttributes param that corresponds to the $optionAttributes param in selectTag(). It can be used to specify the class of the
    . I also added the $showEmpty param just like in selectTag().

    To invoke it you might use something like this:

    $habtm->checkboxMultiple('YourModel/YourModel', $options, $selected, array('class' => 'checkbox'), array('class' => 'checkboxMultiple'), true, true);

    Hope its useful
Posted Mar 28, 2007 by Neil Crookes
 

Comment

5 Very nice

Thanks for the acknowledgment :) Great idea making it into a helper.

Something like this (along with Neil's label modification) should make it's way into Cake I think.
Posted Apr 1, 2007 by James Hall
 

Comment

6 Working Example to download

I've made a working example based on the Posts / Tags in the manual that anyone can download. It contains the views / models / controllers and has your helper already applied.

Hope it comes in useful to somebody.

http://www.flipflops.org/example/habtm_checkbox_example.zip
Posted Apr 5, 2007 by John Elliott
 

Question

7 Unexpected Behaviour

I've been playing around with the checkbox helper some more and getting some very odd results (using PHP 4.4.3) - basically if I attempt to save a data and it is invalid so you return to a view with the error message, the wrong checkboxes are ticked (although the $selected array is correct).

Anyway I ended up rewriting part of the function (using while instead of foreach) - I was wondering if you had any ideas what the problem was - perhaps PHP4 vs 5?
/**
* Returns a list of checkboxes.
*
* @param string $fieldName Name attribute of the SELECT
* @param array $options Array of the elements (as 'value'=>'Text' pairs)
* @param array $selected Selected checkboxes
* @param string $inbetween String that separates the checkboxes.
* @param array $htmlAttributes Array of HTML options
* @param boolean $return Whether this method should return a value
* @return string List of checkboxes
*/
function checkboxMultiple($fieldName, $options, $selected = null, $inbetween = null, $htmlAttributes = null, $return = false)
{

$this->setFormTag($fieldName);
if ($this->tagIsInvalid($this->model, $this->field))
{
if (isset($htmlAttributes['class']) && trim($htmlAttributes['class']) != "")
{
$htmlAttributes['class'] .= ' form_error';
}
else
{
$htmlAttributes['class'] = 'form_error';
}
}

if (!is_array($options))
{
return null;
}

if (!isset($selected))
{
$selected = $this->tagValue($fieldName);
}

while(list($key, $name) = each($options))
{
$optionsHere = $htmlAttributes;

if(in_array($key, $selected))
{
$optionsHere['checked'] = 'checked';
}

$optionsHere['value'] = $key;
$checkbox[] = "
  • " . sprintf($this->tags['checkboxmultiple'], $this->model, $this->field, $this->parseHtmlOptions($optionsHere), $name) . "
  • \n";
    }


    return "\n" . sprintf($this->tags['hiddenmultiple'], $this->model, $this->field, null, $name) . "\n
      \n" . $this->output(implode($checkbox), $return) . "
    \n";
    }

    }

    ?>
    Posted Apr 10, 2007 by John Elliott
     

    Question

    8 Help with error messages in 1.2.0.4798alpha

    Thanks for the awesome helper and detailed steps to implement it! This is totally going to save me a ton of time. I'm attempting to use this with 1.2.0.4798alpha version and I'm seeing the following error messages.I tried searching the google groups and online in general and couldn't find anyone encountering similar issues.

    Notice (8): Undefined property: HabtmHelper::$model [CORE/app/views/helpers/habtm.php, line 20]
    Notice (8): Undefined property: HabtmHelper::$field [CORE/app/views/helpers/habtm.php, line 20]
    Any help is appreciated. Thanks again!
    Posted Apr 10, 2007 by DF
     

    Comment

    9 Partial solution.

    At least changeing $this->model to $this->model() and $this->field to $this->field() seems to get rid of thoses errors. I don't know if the meaning is equavilent to the old way.

    But I get two other errors as well.
    Notice (8): Undefined index: checkboxmultiple [CORE/app/views/helpers/habtm.php, line 51]
    And:
    Notice (8): Undefined index: hiddenmultiple [CORE/app/views/helpers/habtm.php, line 55]
    They are not defined anywhere. I can't figure out why it works in 1.1 either. Well i solved it this way.

    I added

    $this->tags['checkboxmultiple'] = '%s';

    AND

    $this->tags['hiddenmultiple'] = '%s';

    in the beginning of the code directly above $this->setForm.
    Posted Apr 18, 2007 by Kristoffer Darj
     

    Comment

    10 Quick Tips

    Kristoffer,

    Thanks for the heads up on the changes to "model()" and "field()". Regarding the other two errors, I solved those by putting the tag definitions right at the top of the function definition for checkboxMultiple.

    Like this:
    function checkboxMultiple($fieldName, $options, $selected = null, $inbetween = null, $htmlAttributes = null, $return = false) {
    # Tag template for an input type='hidden' tag.
    $hiddenmultiple = '';

    # Tag template for a input type='checkbox ' tag.
    $checkboxmultiple = '%s';

    $this->setFormTag($fieldName);

    ----------------------------------------->
    I came up with this quick solution in order to get the checkboxes to recognize existing selections. In my setup cars and sites have a habtm relationship between each other.

    if($this->data['Site'])
    {
    foreach($this->data['Site'] as $sv)
    {
    $selectedSites[$sv['id']] = $sv['name'];
    }
    }
    else
    {
    $selectedSites = '';
    }

    I put that in the "edit" method of my controller. Hope that helps.
    Posted Apr 20, 2007 by DF
     

    Comment

    11 Final version that works for 1.2

    Thank you Kristoffer & DF,

    I had to make all the changes you suggested to get it to work with 1.2

    The final code that works for 1.2 would be the following.


       function checkboxMultiple($fieldName, $options, $selected = null, $inbetween = null, $htmlAttributes = null, $return = false)
            {
                # Tag template for a input type='checkbox ' tag.
                $checkboxmultiple = '<input type="checkbox" name="data[%s][%s][]" %s/>%s';
                # Tag template for an input type='hidden' tag.
                $hiddenmultiple = '<input type="hidden" name="data[%s][%s][]" %s/>';

                $this->setFormTag($fieldName);
                if ($this->tagIsInvalid($this->model(), $this->field())) {
                    if (isset($htmlAttributes['class']) && trim($htmlAttributes['class']) != "") {
                        $htmlAttributes['class'] .= ' form_error';
                    } else {
                        $htmlAttributes['class'] = 'form_error';
                    }
                }
                if (!is_array($options)) {
                    return null;
                }
                if (!isset($selected)) {
                    $selected = $this->tagValue($fieldName);
                }
                foreach($options as $name => $title) {
                    $optionsHere = $htmlAttributes;
                    if (($selected !== null) && ($selected == $name)) {
                        $optionsHere['checked'] = 'checked';
                    } else if (is_array($selected) && array_key_exists($name, $selected)) {
                        $optionsHere['checked'] = 'checked';
                    }
                    $optionsHere['value'] = $name;
                    $checkbox[] = "<li>" . sprintf($checkboxmultiple, $this->model(), $this->field(), $this->_parseAttributes($optionsHere), $title) . "</li>\n";
                }
                return "\n" . sprintf($hiddenmultiple, $this->model(), $this->field(), null, $title) . "\n<ul class=\"checkboxMultiple\">\n" . $this->output(implode($checkbox), $return) . "</ul>\n";

            } /// checkboxMultiple()

    And this is how you use it...

    echo $myHtml->checkboxMultiple('MyModel/MyModel', $arrAllBoxes, $selectedBoxes, array('multiple' => 'multiple', 'class' => 'selectMultiple'));

    But the addition I had to make to the controller method was following.

                                if($this->data['MyModel']['MyModel'])
                                {
                                    foreach($this->data['MyModel']['MyModel'] as $selectedItem)
                                    {
                                        $selectedBoxes[$selectedItem] = $selectedItem;
                                    }
                                }
                                else
                                {
                                    $selectedBoxes = '';
                                }

    Posted Aug 6, 2007 by Pranav Desai
     

    Comment

    12 A little hack.

    If we want it to work with the SecurityComponent without blackholing everything, another change is needed.

    It has to use FormHelper::input .. and actually this could be done by a little hack.

    $form->input('Model.field][');
    By appending ][ to the end the result will be
    [Model][field][] Something like we wanted all along.
    Posted Aug 7, 2007 by Kristoffer Darj
     

    Comment

    13 tagValue() is deprecated

    Using 1.2.0.5427alpha I recieved Method tagValue() is deprecated in HtmlHelper: see HtmlHelper::value.

    Using value insterad of tagValue seems to work great. Thanks to all for putting this together.
    Posted Aug 12, 2007 by Ian
     

    Bug

    14 When a form invalidates...

    I receive an amount of error messages equal to the amount of checkboxes it needs to show... although the checkboxes seem to be fine!

    The error message is:


    Notice: Uninitialized string offset: 0 in D:\TYPO3\Apache\htdocs\cake\app\views\helpers\habtm.php on line 36

    EDIT: It seems I based this bug on older code... which I don't understand because I copied it just last week. Anyway, the problem I have using the code mentioned in the article is that the checkboxes don't keep their current state when the form does not validates.

    This does seem to work for me:


    <?php
    class HabtmHelper extends HtmlHelper {
        
        
    /**
         * Returns a list of checkboxes.
         *
         * @param string $fieldName Name attribute of the SELECT
         * @param array $options Array of the elements (as 'value'=>'Text' pairs)
         * @param array $selected Selected checkboxes
         * @param string $inbetween String that separates the checkboxes.
         * @param array $htmlAttributes Array of HTML options
         * @param  boolean $return         Whether this method should return a value
         * @return string List of checkboxes
         */
        
    function checkboxMultiple($fieldName$options$selected null$inbetween null$htmlAttributes null$return false) {
            
    $this->setFormTag($fieldName);
            if (
    $this->tagIsInvalid($this->model$this->field)) {
                if (isset(
    $htmlAttributes['class']) && trim($htmlAttributes['class']) != "") {
                    
    $htmlAttributes['class'] .= ' form_error';
                } else {
                    
    $htmlAttributes['class'] = 'form_error';
                }
            }
            if (!
    is_array($options)) {
                return 
    null;
            }    
            if (!isset(
    $selected)) {
                
    $selected $this->tagValue($fieldName);
            }
            foreach(
    $options as $name => $title) {
                
    $optionsHere $htmlAttributes;
                if ((
    $selected !== null) && ($selected == $name)) {
                    
    $optionsHere['checked'] = 'checked';
                } else if (
    is_array($selected) && count($selected) >0) {
                    foreach(
    $selected as $array) {
                        if(
    $array == $name) {
                            
    $optionsHere['checked'] = 'checked';
                        }
                    }
                }
                
    $optionsHere['value'] = $name;
                
    $checkbox[] = "<li>" sprintf($this->tags['checkboxmultiple'], $this->model$this->field$this->parseHtmlOptions($optionsHere), $title) . "</li>\n";
            }
            return 
    "\n" sprintf($this->tags['hiddenmultiple'], $this->model$this->fieldnull$title) . "\n<ul class=\"checkboxMultiple\">\n" $this->output(implode($checkbox), $return) . "</ul>\n";
        }
        
    }
    ?> 
    Posted Aug 27, 2007 by Bo
     

    Comment

    15 Solution for wrong check boxes being selected

    Hey guys,

    If your checkboxes are being selected in wierd ways (ie: if you select 3 our of 10 at random spots, after a save error the first 3 are ticket not the ones you wanted, there is a simple solution.

    Change the following line:

    } else if (is_array($selected) && array_key_exists($name, 
    $selected)) { 

    To:

    } else if (is_array($selected) && array_search($name, $selected)) {
    Posted Oct 18, 2007 by Phillip Savage
     

    Comment

    16 array search

    check php manual for array_search() -
    sometimes it returns 0 - which is not false, so manually check for false

    } else if (is_array($selected) && array_search($name , $selected)!==false) {
    Posted Nov 15, 2007 by Joe Weil
     

    Question

    17 Hidden fields and empty array elements

    I'm sure this is my stupidity, but can some explain the reason for the hidden field before the checkboxes? I get an empty array element before the actual checkbox values when I submit the form... I've removed the code creating it, but as I'm not entirely sure why its there I thought I'd better check...
    Cheers!
    Posted Jan 4, 2008 by Toby Bradshaw
     

    Comment

    18 CakePHP 1.2 update

    I just noticed that multiple checkboxes can be used inherently in the current beta version of CakePHP 1.2. It can easily be used via the following method:

    View:
    <?php echo $form->input('Post.Tag', array('type'=>'select''multiple'=>'checkbox''options'=>$tags'label'=>'Tags:'));?>

    Selecting list data is a bit different in this most recent version as well.

    Model:
    <?php
    class Tag {
        
    // The column value to show in SELECT OPTION's.
        
    var $displayField 'name';
    }
    ?>

    Controller:
    <?php
    function index() {
        
    $this->set('tags'$this->Tag->find('list'));
    }
    ?>
    Posted Jan 5, 2008 by Matt Huggins
     

    Question

    19 i think i was missing something

    i dont know is it what you really mean or not...but why did i get a selectbox when i use

    View Template:


    <?php echo $form->input('Post.Tag', array('type'=>'select''multiple'=>'checkbox''options'=>$tags'label'=>'Tags:'));?>

    didn't we talk about checkbox ???


    i'm sorry if i was mistaken
    Posted Jan 16, 2008 by riki pribadi
     

    Comment

    20 check your cake version

    Perhaps you are not on cake1.2beta?
    this exact snippet works a-ok for me.

    i dont know is it what you really mean or not...but why did i get a selectbox when i use

    View Template:


    <?php echo $form->input('Post.Tag', array('type'=>'select''multiple'=>'checkbox''options'=>$tags'label'=>'Tags:'));?>

    didn't we talk about checkbox ???


    i'm sorry if i was mistaken
    Posted Jan 21, 2008 by ambiguator
     

    Comment

    21 im sorry

    im so sorry..

    previously, i was using cake 1.2.0.5875 pre-beta then i try it on cake 1.2.0.6311 beta and its working..

    thanx ambiguator
    Posted Feb 1, 2008 by riki pribadi
     

    Comment

    22 How to do this without the helper...

    In Cake 1.2 I find that with an options variable generated from Model->find('list'):

    Controller Class:

    <?php 
    $options 
    $this->Model->find('list');
    $this->set('options'$options);
    ?>

    View Template:


    <?php
    foreach ($options as $id=>$label) {
        echo 
    $form->input("Model.id.$id"
            array(
                
    'label'=>$label,
                
    'type'=>'checkbox',
                
    'checked'=>($this->data["Model"]["id"][$id] == 'checked' false)
                )
            );
    }
    ?>

    Works fine if you'd rather not use yet another helper.
    Posted Apr 12, 2008 by Fredrik Motin
     

    Comment

    23 Problem with multiple checkbox when saving data

    I have a code in controller:

    foreach($this->data as $user){
    foreach($user['user_id'] as $userid){
    // If User already assigned then Update else Insert
    if($this->Project->query("SELECT id,user_id,project_id FROM tts_users_projects ProjectUser WHERE user_id = '".$userid."' AND project_id = '".$id."'")){
    //$this->Project->query("UPDATE tts_users_projects SET user_id = '".$userid."' AND project_id = '".$id."' WHERE project_id = ".$id." AND user_id = ".$userid);
    }else{
    if (!$this->Project->query("INSERT INTO tts_users_projects(`user_id`,`project_id`) VALUES ('".$userid."','".$id."')")){
    $error[] = $user; // fetch Error(s)
    }
    }

    }
    }

    I dont understand why when I save data, and forexample I have checkboxes in the sequence below:
    [ ] Waqar
    [X] Mohsin
    [X] Mubashir
    [ ] Test

    if i check the "Test" it will be saved, but if I check "Waqar" which is above the checked checkboxes, it doesn't save.

    Any idea? Its confusing me.
    Posted Jul 16, 2008 by Waqar
     

    Question

    24 Problem with multiple checkbox when saving data

    I have a code in controller:

    foreach($this->data as $user){
    foreach($user['user_id'] as $userid){
    // If User already assigned then Update else Insert
    if($this->Project->query("SELECT id,user_id,project_id FROM tts_users_projects ProjectUser WHERE user_id = '".$userid."' AND project_id = '".$id."'")){
    //$this->Project->query("UPDATE tts_users_projects SET user_id = '".$userid."' AND project_id = '".$id."' WHERE project_id = ".$id." AND user_id = ".$userid);
    }else{
    if (!$this->Project->query("INSERT INTO tts_users_projects(`user_id`,`project_id`) VALUES ('".$userid."','".$id."')")){
    $error[] = $user; // fetch Error(s)
    }
    }

    }
    }

    I dont understand why when I save data, and forexample I have checkboxes in the sequence below:
    [ ] Waqar
    [X] Mohsin
    [X] Mubashir
    [ ] Test

    if i check the "Test" it will be saved, but if I check "Waqar" which is above the checked checkboxes, it doesn't save.

    Any idea? Its confusing me.
    Posted Jul 16, 2008 by Waqar
     

    Comment

    25 Re: How to do this without the helper

    I tried this because I wanted to add html links beside my checkboxes.
    I can't use input('Post.Tag', array('type'=>'select', 'multiple'=>'checkbox', 'options'=>$tags, 'label'=>'Tags:'));?> since it automatically generates the checkboxes and doesn't allow me to add anything beside them.

    Anyway, I think there's something wrong with the view code if used on an edit view.

    View Template:


    <?php
    foreach ($options as $id=>$label) {
        echo 
    $form->input("Model.id.$id"
            array(
                
    'label'=>$label,
                
    'type'=>'checkbox',
                
    'checked'=>($this->data["Model"]["id"][$id] == 'checked' false)
                )
            );
    }
    ?>

    It does not display the already checked checkboxes and it also doesn't pass the correct $this-data['Field'] data to the controller when an edit is submitted.

    I had to modify it to the ff to make it work

    View Template:


    <?php
    foreach ($options as $id=>$label) {
                
    $check false;

                
    //Determine if the checkbox is already checked or not
                
    foreach($this->data['Model'] as $data)
                {
                    if(
    $data['id'] == $id) {
                        
    $check true;
                        break;
                    }
                }

                
    //First param is weird but it works
                
    echo $form->input('Model.Model]['
                    array(
                        
    'label'=>$label,
                        
    'type'=>'checkbox',
                        
    'checked'=> $check,
                        
    'value' => $id
                        
    )
                    );

                echo 
    $html->link('My link beside the checkbox','/');
            }
    ?>


    Would there be an easier way to put a link (or whatever text) that's associated with a checkbox BESIDE the checkbox without having to do the above?

    -pacfan

    In Cake 1.2 I find that with an options variable generated from Model->find('list'):

    Controller Class:

    <?php 
    $options 
    $this->Model->find('list');
    $this->set('options'$options);
    ?>

    View Template:


    <?php
    foreach ($options as $id=>$label) {
        echo 
    $form->input("Model.id.$id"
            array(
                
    'label'=>$label,
                
    'type'=>'checkbox',
                
    'checked'=>($this->data["Model"]["id"][$id] == 'checked' false)
                )
            );
    }
    ?>

    Works fine if you'd rather not use yet another helper.
    Posted Nov 8, 2008 by Pac Fan
     

    Question

    26 $this->data["Model"]["id"][$id]?

    I dunno but is
    'checked'=>($this->data["Model"]["id"][$id] == 1 ? 'checked' : false
    really OK?

    If I pr($this->data), the HABTM array is like:
    [Model][0][id] [Model][1][id]

    In my case, list is like
    $options = $this->Model1->Model->find('list');
    tho.
    Posted Dec 12, 2008 by softdev
     

    Comment

    27 Automagic

    Let cake do this automatically now by adding the following code to your view:
    echo $form->input('Model', array('multiple'=>'checkbox'));
    Posted Jun 8, 2009 by Ken Frey
     

    Comment

    28 How to make it prettier in 1.2

    with the new 1.2 multiple=>checkbox magic, the output is fairly ugly. a long list of checkboxes, no scrolling, not lined up with the other input fields, etc. here are some simple bits of code that make it much nicer looking.

    in the view, add:
    $html->tags['checkboxmultiplestart'] = '<div class="checkboxmultiple">';
    $html->tags['checkboxmultipleend'] = '</div>';
    or i guess you could use $this->HtmlHelper->tags in the controller. that will put a div wrapper around the list of checkboxes so you can format it.

    then add a css blob to your css file, or inline, or whatever:
    div.checkboxmultiple {
        clear: none;
        height: 6em;
        overflow: auto;
        max-width: 250px;
        border: 1px solid gray;
    }
    of course those values might need to be tweaked for your site.

    Posted Jun 24, 2009 by Joe Pruett