_Form With Cgrid

Hello people!

I’m finally starting to write one of the mail functions in my app: adding people to events.

What I have:

3 models - Person , Event , Person_Event. The last one is not only a connection table but a whole model with CRUD as well , because it has additional info about the person who attended an event , and thus I have 2 belongs_to relations with the other two models.

How it should work:

Person_Event has its own PK with auto-increment , but needs to get the person_id and event_id from the other models.

Now with event_id there is no problem , cause I’m sending it by URL from Event.view

However , I want my user to be able to pick several people for a certain event. Now , I could use a multi-dropdown list ,

but I want to provide him with more info about every person , and thus, I want the user to pick the people from a CgridView.

So far:

In the Person_event form , the event_id is sent by URL , and a CgridView of people is being shown. The grid has a checkbox column , which , as far as I know , saves the id of the selected person.

I’m failing to write the actionCreate in the controller , it keeps saying that person_id is empty , thus doesn’t get the checked people from the grid.

Here is my action:


public function actionCreate()

	{

		$model=new Person_Event;

		$model->event_id=$this->_event->id;              //event_id by URL

		

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

		{

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

			if($model->save())

			{

				foreach ($_POST['Person_Event']['person'] as $model)  //person is the name of the relation with Person model

				{

					$model->event_id=$this->_event->id;        //as above , do I need it again?

					$model->person_id = $model;                     //probably what doesn't work?

					if (!$model->save()) print_r($model->errors);

				}

				

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

			}

		}


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

			'model'=>$model,

		));

	}

EDIT: tried with ajax instead , didn’t work


public function actionCreate()

	{

		

		$model=new Person_Event;

		$model->event_id=$this->_event->id; //event_id by URL

		

		if(Yii::app()->request->getIsAjaxRequest())

                {

			$checkedIDs=$_GET['checked'];

                         foreach($checkedIDs as $id)

				{

                                                $model->person_id=$id;

						$model->event_id=$this->_event->id;

				}

		}

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

				'model'=>$model,

			));

	}

Hi MarkBrass,

There are 2 "$model" in your code. The one is at the outside of the foreach loop, and the other inside.

And the saving of the 1st $model is failing because it doesn’t have person_id yet. Also the code inside the foreach loop won’t work because of the variable conflict.

Maybe the following will be a skeleton for the function:




public function actionCreate()

{

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

   {

        foreach ($_POST['Person_Event']['person'] as $personId)

        {

            $model=new Person_Event;

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

            $model->event_id=$this->_event->id;

            $model->person_id = $personId;

            if (!$model->save())

            {

                ...

            }

        }

    }

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

        'model'=>$model,

    ));

}



Thank you softark!

Based on your code I wrote this function:


public function actionCreate()

	{

		$model=new Person_Event;

		$model->event_id=$this->_event->id;

		


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

		{

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

			if($model->save())

			{

				if(isset($_POST['Person_Event']['person']))

				{

					foreach ($_POST['Person_Event']['person'] as $cId)

					{

						$posCat = new Person_Event;

						$posCat->event_id = $model->event_id;

						$posCat->person_id = $cId;

						if (!$posCat->save()) print_r($posCat->errors);

					}

				}

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

			}

		}


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

			'model'=>$model,

		));

	}

I had to put the $model creation outside the loop , because otherwise I got a "non existing index model".

However , I still get that Person_id is empty.

I thought to use the checkboxColumn instead of a dropdown list in the form , and pass the model’s via relation (person) - IS IT POSSIBLE AT ALL?

Or do I need to send the arrays of the checked ids via ajax?


public function actionCreate()

{

	$model=new Person_Event;

	$model->event_id=$this->_event->id;


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

	{

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

		// At this point, $model->person_id is not yet set. So $model->save() will fail.

		if($model->save())

		{

			...



If you are sure $_POST[‘Person_Event’][‘person’] is an array and contains an array of person ids, then I think it should work as expected.

I don’t think that you have to use ajax here.

Wuh , ok , problem solved.

The only thing I need to solve now it that the filters of Person’s grid in Person_Event form are not working . . . .

I based my solution on softark’s answer about the save() and with this article:

Turns out , I had to give the checkboxColumn an id and sent it , instead of the relation.

Still had to create 2 models , cause otherwise the render wouldn’t worked.

this is my working code:


	public function actionCreate()

	{

		$model=new Person_Event;

		$model->event_id=$this->_event->id;

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

	   {

			foreach ($_POST['selectedIds'] as $personId)

			{

				$pmodel=new Person_Event;

				$pmodel->event_id=$this->_event->id;

				$pmodel->attributes=$_POST['Person_Event'];

				$pmodel->person_id = $personId;

				if (!$pmodel->save()) print_r($pmodel->errors);

			}

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

		}

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

			'model'=>$model,

		));

	}

As for the filers , I have no idea why they don’t work , because the dataProvider do:


	<div class="row">

		<?php echo $form->labelEx($model,'person_id'); ?>

		<?php $this->widget('zii.widgets.grid.CGridView', array(

	'id'=>'person-grid',

	'dataProvider'=>Person::model()->search(array('join'=>'INNER JOIN tbl_person_job ON tbl_person_job.person_id=id AND tbl_person_job.job_id=1','condition'=>'status_id="פעיל"')),

	'filter'=>Person::model(),

	'columns'=>array(

		array(

			'name'=>'create_time',

			'htmlOptions'=>array('style' => 'text-align: center;'),	

		),

		array(        

			'name'=>'level_id',

		    'value'=>'$data->getLevelText()',

			'htmlOptions'=>array('style' => 'text-align: center;'),

			'filter'=>CHtml::listData(Person::model()->findAll(array('order'=>'level_id DESC')),'level_id','level_id'),

		),

		array(

			'name'=>'last_name',

			'htmlOptions'=>array('style' => 'text-align: center;'),	

		),

		array(

			'name'=>'first_name',

			'htmlOptions'=>array('style' => 'text-align: center;'),	

		),

		array( 

            'header'=>'Num',

            'value'=>'$row+1',

			'htmlOptions'=>array('style' => 'text-align: center;'),

        ),

		array(     

				'id' => 'selectedIds',

				'class'=>'CCheckBoxColumn',

				'selectableRows' =>2,				

			),

	),

)); ?>

		<?php echo $form->error($model,'person_id'); ?>

	</div>