Working with a checkbox list

I’m really confused as to how to store/work with a list of checkboxes. Is there a simple tutorial somewhere? I’ve gotten through the Yii 1.1 and PHP5 book, and I’m working on my first yii app that isn’t a tutorial, and I can’t seem to grok how to properly set up the database and models, controllers, views/forms…Basically I have a Project table, and I want to store Project Types. A Project could be of multiple types. I have a list of types that might grow, so I was thinking of having a Type table and model, and then a Project_Type table that has project_id and type_id…but that’s where I’m stuck. How do checkbox lists work? How do I integrate that list into the edit Project form?

Thanks for any help! I’m still new to Yii and struggling up the learning curve.

I solved the same problem today, just a couple of minutes before becoming crazy :lol:

I paste here the code, only the relevant parts. The models are in spanish, but if you have any doubt just ask!!

(Empleado = Employee, Sucursal = Department, Empresa = Company)

The example shows how to edit the Employee-Empleado form to include a checkBoxList with Departments he/she can be assigned to.

FIRST STEP:

Set the relations!

In this example I’m focusing on Employee, so:


	public function relations()

	{

		return array(

                        'empresa' => array(self::BELONGS_TO, 'Empresa', 'id_empresa'),

			'sucursales' => array(self::MANY_MANY, 'Sucursal', 'tbl_sucursal_empleado(id_empleado, id_sucursal)'),

		);

	}

SECOND STEP:

Install some extension that extends the MANY_MANY relation management. I’m using CAdvancedArBehavior but there are several.

THIRD STEP:

Here are the parts that you should add to your view, model and controller.


//////////= Empleado View _form: =//////////

<?php echo CHtml::activeCheckBoxList($model, 'sucursalesIDs', 

            CHtml::listData(

                Sucursal::model()->findAll(

                    'id_empresa = :id_empresa', 

                    array(':id_empresa'=>$model->id_empresa)

                ), 

                'id_sucursal', 

                'nombre_sucursal'

            ) /* In this case I want to show only the sucursales-departments that belong 

               * to the company that the Employee belongs to. Otherwise you just 

               * Sucursal::model()->findAll() without condition */

           ) ?>


//////////= Empleado Model: =//////////

class Empleado extends CActiveRecord

{

    /**

     * Array to manage the HAS_MANY relation. 

     * You can't assign values directly to $sucursales: 

     * it's a relation, so you have to bypass it

     */

    public $sucursalesIDs = array();

    

    /**

     * To sync the two "twins": the relation called 'sucursales' 

     * and the public variable 'sucursalesIDs'. If you don't do that 

     * you will not see checkbox checked for the departments-sucursales 

     * that are currently assigned to the Employee

     */ 

    public function afterFind()

    {

        if(!empty($this->sucursales))

        {

            foreach($this->sucursales as $n=>$sucursal)

                $this->sucursalesIDs[]=$sucursal->id_sucursal;

        }

    }

    

    // Just follow the extension installation

    public function behaviors(){ 

          return array( 'CAdvancedArBehavior' => array(

                'class' => 'application.extensions.CAdvancedArBehavior'));

    }

    

	public function rules()

	{

            ....

            array('sucursalesIDs', 'unsafe'), // I'm not sure about this. Actually I get a warning 'Failed to set unsafe attribute "sucursalesIDs"' but the application works.. does anybody know how to fix this? 

            ....

	}            

}


//////////= Empleado Controller: =//////////

public function actionUpdate($id)

{

    $model=$this->loadModel($id);


    if(isset($_POST['Empleado']))

    {

        $model->attributes=$_POST['Empleado'];

        $model->sucursales=$_POST['Empleado']['sucursalesIDs']; // If you don't do this it will not save the assigned sucursales-departments

        if($model->save())

            $this->redirect(array('view','id'=>$model->id_empleado));

    }


    $this->render('update',array(

        'model'=>$model,

    ));

}

I hope this solved your problem. If yes, mark the thread as [Solved] and let’s hope that one day Yii documentation will be better!

Regarding this… adding [SOLVED] to the title… we had a discussion a while ago - http://www.yiiframework.com/forum/index.php?/topic/14022-saving-passwords/page__view__findpost__p__69254

Thank you for replying with such detail! I hope it will help me. Unfortunately, I’ve been quickly asked to assist in a non-yii project here and it may take me a couple weeks before I get to circle back to this. I’ll reply again then with any questions.

Thank you so much though!

You should use a behaviour to set the many_many relations, f.e. this one:

http://www.yiiframework.com/extension/esaverelatedbehavior/

You should also use an activeCheckboxList, as Attilio discribed it.

The problem is, that an activeCheckboxList can only handle an attribute that contains an array of ids and not an array of objects. This might be fixed in Yii 1.1.8.

For the moment you would have to add another attribute to your model.

My solution to this is a bit different from Attilios, I am setting the extra

attribute only when its accessed (for better performance), something like this:




public $_typeIds = null;

public function getTypeIds() {

    if($this->_typeIds === null) {

        $this->_typeIds = array();

        if(!$this->isNewRecord) {

            foreach($this->types as $type)

                $this->_typeIds[]=$type->primaryKey;

        }

    }

    return $this->_typeIds;

}

public function setTypeIds($value) {

    $this->_typeIds = $value;

}



I’ve found that if two related model do the described trick you get a infinite loop. There’s a workaround for that and I describe the issue here:

http://www.yiiframework.com/forum/index.php?/topic/21243-reciprocal-afterfind-generates-infinite-loop/

I have fetched data and generated the report. Now i want to generate pdf on click of button in the generated report view. I want to call an action and want to pass array to the controller how to do that can any one help me…

I solved it…

Please follow the link to enable multiple checkbox list.

to store the values and get the selected values while updating

[html]http://www.yiiframework.com/forum/index.php/topic/54518-checkboxlist-in-yii-framework-multiple-check-box-list-with-css/page__p__250478__fromsearch__1#entry250478[/html]

Thanks,

Srikanth