I want to fetch data from my table using CActiveDataProvider in Yii. Everything seems to be working well but when I want to display the data from another related table using relations, I get an error. 'Undefined variable $data'.
here is my admin.php view:
<h1>Manage Teams</h1>
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'team-grid',
'dataProvider'=>$dataProvider,
'columns'=>array(
'id',
'team_name',
array(
'name'=>'league_id',
'type'=>'raw',
'value'=>$data->league->league_name,
),
'create_time',
'update_time',
array(
'class'=>'CButtonColumn',
),
),
)); ?>
and here is my actionAdmin method on TeamController.php
public function actionAdmin()
{
$dataProvider=new CActiveDataProvider('Team', array(
'criteria'=>array(
'order'=>'create_time DESC',
),
'pagination'=>array(
'pageSize'=>20,
),
));
$this->render('admin',array(
'dataProvider'=>$dataProvider,
));
}
The relation is, obviously, a team belongs to a league.
You should just put the $data->league->league_name in quotes and then it will recognize the $data variable. It should look like this:
array(
'name'=>'league_id',
'type'=>'raw',
'value'=>'$data->league->league_name',
),
you need to do it like this :
your column should be
array(
'name'=>'league_id',
'value'=>array($this,'league_name'),
),
and you controller shod have a function like this:
public function league_name($data,$row)
{
return $data->league->league_name;
}
Related
I'm just trying to wrap my head around the yii framework at the moment and I've created a function to delete multiple database records at once. In the view I've got a grid with a reference to each item and a checkbox next to it
<?php $this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$dataProvider,
'htmlOptions'=>array(
'class'=>''
),
'columns'=>array(
...
array(
'class'=>'CLinkColumn',
'header'=>'Handle',
'labelExpression'=>'$data->handle',
'urlExpression'=>'Yii::app()->createUrl(".../item/view", array("id"=>$data->id))',
),
array(
'class'=>'CCheckBoxColumn',
'header'=>'Select',
'selectableRows'=>'2',
),
),
Then further down the page I want a button (delete selected) which sends an array of all of the items to a delete function. My thoughts were it would be something akin to this:
<a href="
<?php echo Yii::app()->createUrl('.../item/bulkDelete','array("id" => $data->id)')?>"
class="btn">Delete Selected</a>
But I don't understand how to get a reference for each checked item instead of :
"id" => $data->id
as I used to call pass an item to the view function earlier. If anyone can help it will be greatly appreciated.
Edit:
View:
$form = $this->beginWidget('CActiveForm', array(
'id' => 'itemForm',
'action' => array('.../item/bulkDelete'),
));
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$dataProvider,
'htmlOptions'=>array(
'class'=>''
),
array(
'class'=>'CLinkColumn',
'header'=>'Handle',
'labelExpression'=>'$data->handle',
'urlExpression'=>'Yii::app()->createUrl(".../item/view", array("id"=>$data->id))',
),
array(
'class'=>'CCheckBoxColumn',
'header'=>'Select',
'selectableRows'=>'2',
),
... //More Columns
), //End of Grid
...
echo CHtml::SubmitButton('Delete Multiple');
$this->endWidget();
Controller:
public function actionBulkDelete()
{
if(isset($_POST['id'])&& !empty($_POST['id']))
{
Yii::app()->user->setFlash('success', 'Delete Items');
$this->redirect(array('.../item/index'));
}
else
{
Yii::app()->user->setFlash('success', 'No Items Selected');
$this->redirect(array('.../item/index'));
}
}
Wrap the grid view inside a form, and do the following changes in your columns array:
$form = $this->beginWidget('CActiveForm', array(
'id' => 'some-grid-form',
'action' => array('myController/myAction'),
));
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$dataProvider,
'selectableRows' => 2,
'columns'=>array(
array(
'id' => 'id',
'class' => 'CCheckBoxColumn',
),
//... rest of your columns
),
array(
'class'=>'CButtonColumn',
),
),
));
echo CHtml::SubmitButton('Multiple Delete');
$this->endWidget(); // end form
And in your Controller's myAction:
public function actionmyAction()
{
if(isset($_POST['id']) && !empty($_POST['id'])) { //you'll get all the ids in an array
//print_r($_POST['id']);
//your delete function here, also add a few validation here to authenticate deletion
$ids = $_POST['id'];
$criteria = new CDbCriteria;
$criteria->addInCondition('id',$ids);
MyModel::model()->deleteAll($criteria);
//.... render with success flash message etc.
}
}
Yii 1.1.14
I have an employee table and a comment table
In the employee view i want to show all the comments of the employee in a grid (after the employee fields)
I tried to follow the example here
Here is where I am :
New code to defining a new search function in the model :
public $commentdate_param;
public $commentobservation_param;
...
public function rules()
{
return array(
...
array('public $commentdate_param, commentobservation_param, ...', 'safe', 'on'=>'search, searchIncludingComments'),
);
public function relations()
{
return array(
...
'employeecomments' => array(self::HAS_MANY, 'Employeecomments', 'employee_id'),
);
}
public function searchIncludingComments($parentID)
{
$criteria=new CDbCriteria;
$criteria->with=array('employeecomments');
$criteria->together = true;
$criteria->compare('t.employee_id',$parentID,false);
$criteria->compare('employeecomments.date', $this->commentdate_param,true);
$criteria->compare('employeecomments.observation', $this->commentobservation_param,true);
$sort = new CSort;
$sort->attributes = array(
'commentdate_param' => array(
'asc' => 'date_desc',
'desc' => 'date_desc DESC',
), '*', /* Treat all other columns normally */
);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
'sort'=>$sort,
));
}
Adding code in the controller actionView :
...
$child_model = new Employee("searchIncludingComments");
$child_model->unsetAttributes();
$this->render('view',array(
'model'=>$this->loadModel($id),
'child_model'=>$child_model,
'parentID' => $id
));
Adding code in the view :
...
<h3>Comments</h3>
<?php
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'child-grid',
'dataProvider'=>$child_model->searchIncludingComments($parentID),
'filter'=>$child_model,
'columns'=>array(
'date',
'observation',
array(
'class'=>'CButtonColumn',
),
),
));
...
But I must have missed something because when it comes to grid rendering stops - but no error in log
Would be nice if somebody could help me !
I found the solution for me - all my changes and controler are worthless because now I do all stuff in the view :
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'comments-grid',
'dataProvider'=>new CActiveDataProvider('Employeecomment',array(
'criteria'=>array(
'condition'=>'employee_id=:eid',
'params'=>array(':eid'=>$model->id),
),
'sort'=>array(
'defaultOrder'=>'date DESC',
),
)),
Sure there is something I did not understand why it did not work ...
Certain class has a property called status (that can be 0 or 1). In the corresponding model I have defined two variables STATUS_CLOSED = 1 and STATUS_OPEN = 2.
I am using a CDetailView to display model info inside a "View" view like:
$this->widget('zii.widgets.CDetailView', array(
'data'=>$model,
'attributes'=>array(
'account_number',
'account_type',
array(
'label'=>'Banco',
'type'=>'raw',
'value'=>CHtml::encode($model->bank->bank_name),
),
),
));
I have defined these two functions in my model:
public function statusLabels()
{
return array(
self::STATUS_CLOSED => 'Inactiva',
self::STATUS_OPEN => 'Activa',
);
}
public function getStatusLabel($status)
{
$labels = self::statusLabels();
if (isset($labels[$status])) {
return $labels[$status];
}
return $status;
}
I need to customize the CDetailView (possibly using these two functions) to display the corresponding label, depending on the status value.
I thought this would work:
$this->widget('zii.widgets.CDetailView', array(
'data'=>$model,
'attributes'=>array(
'account_number',
'account_type',
array(
'label'=>'Estado',
'type'=>'raw',
'value'=>$model->statusLabel($model->status),
),
),
));
But I get: Missing argument 1 for BankAccount::getStatusLabel()
What I am doing wrong?
Ok so first off you don't need to send in the status for a model since the model already knows its own status so I would change your function to this:
public function getStatusLabel() {
$labels = self::statusLabels();
if (isset($labels[$this->status])) {
return $labels[$this->status];
}
return $this->status;
}
So then your widget would just be like this:
$this->widget('zii.widgets.CDetailView', array(
'data'=>$model,
'attributes'=>array(
'account_number',
'account_type',
array(
'label'=>'Estado',
'type'=>'raw',
'value'=>$model->statusLabel
),
),
));
Also it doesn't cause an error but in reality you should make the function statusLabels() a static function.
public static function statusLabels() {
...
}
I have 2 tables/models:
Tmp1
Header
QuestionText
Tmp2
Header
Part
OutOf
I'm trying to display the columns: Header, QuestionText, Part, OutOf
in a single CGRIDVIEW.
In Tmp1 model:
public function relations()
{
return array(
'tmp2s' => array(self::HAS_MANY, 'Tmp2', 'Header'),
);
}
In Tmp2 Model:
public function relations()
{
return array(
'header' => array(self::BELONGS_TO, 'Tmp1', 'Header'),
);
}
Controller:
public function actionReviewAll()
{
$tmp1 = new Tmp1('search');
$tmp1->unsetAttributes();
if(isset($_GET['Tmp1'])){
$model->attributes=$_GET['Tmp1'];
}
$this->render('ReviewAll',array(
'tmp1'=>$tmp1,
));
}
View:
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'tmp-grid',
'dataProvider'=>$tmp1->search(),
'filter'=>$tmp1,
'columns'=>array(
'Header',
'QuestionText',
array(
'name' => 'tmp2.OutOf',
'value' => '$data->tmp2[0].OutOf',
'type' => 'raw'
),
),
)); ?>
Error:
Property "Tmp1.tmp2" is not defined.
Any help is greatly appreciated
You have a sintax error:
Tmp1.tmp2 = Tmp1.tmp2s
The relation alias is with 's'. "tmp2s".
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'tmp-grid',
'dataProvider'=>$tmp1->search(),
'filter'=>$tmp1,
'columns'=>array(
'Header',
'QuestionText',
'tmp2s.Part',
'tmp2s.OutOf',
),
)); ?>
But you are trying to show a 'self::HAS_MANY' relationship, you can't show that on a normal CGridView widget...
Your code probably works (I haven't tried it), but not in cases where your tmp1 model has no tmp2's. You must make sure there is a tmp2 before accessing it:
'value' => 'isset($data->tmp2) ? $data->tmp2[0].OutOf : Null',
You can also pass a function($data,$row) to value to make it look less messy. (Yes, that's important to me.)
The code following doesn't work when it is put in the admin.php file. It seems that the actionAdmin doesn't preload the models. How can I fix it?
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'templateset-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'id',
'name',
array(
'name'=>'disable',
'value'=>$model->numberToStatus(),
),
array(
'class'=>'CButtonColumn',
),
),
));
The function numberToStatus is defined as
public function numberToStatus()
{
$disabled=Yii::t('myExtension', 'disabled');
$non_disabled=Yii::t('myExtension', 'non-disabled');
$statusArray=array($disabled, $non_disabled);
return $statusArray[$this->disable];
}
I have try many methods and failed, Do you have any ideas? Thank you for your help.
you need to use
'value' => '$data->numberToStatus()',