Yii CGridView can't show custom SQL attribute - php

In the Type model's search() function, I want to display three attributes in CGridview:
type.name, type.description and count(dataset_type.dataset_id)
public function search()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->alias='t';
$criteria->select='t.name, t.description, count(dataset_type.dataset_id) as number';
$criteria->join='LEFT JOIN dataset_type ON dataset_type.type_id=t.id';
$criteria->group='t.id';
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
This is the view:
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id' => 'type-grid',
'dataProvider' => $model->search(),
'filter' => $model,
'itemsCssClass' => 'table table-bordered',
'columns' => array(
'name',
'description',
'number',
array(
'class'=>'CButtonColumn',
),
),
)); ?>
but in this way the columns in CGridView can only display model attributes, it shows type.number can't find in model Type, how can I display the count()?

You will also have to add the attribute to your model to be able to use it as a column in your CGridView:
class Type extends CActiveRecord {
public $number;

Related

Cgridview In Parentview

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 ...

Displaying data from two tables in Yii CGridView

I want to show 2 tables with a right join, but the code I wrote does not work as expected. Can anyone tell me what I am doing wrong ?
view : admin.php
$this->widget('bootstrap.widgets.TbGridView', array(
'id' => 'punish-grid',
'dataProvider' => $model->searchJoin(),
'type' => 'striped bordered condensed',
'filter' => $model,
'columns' => array(
array(
'header' => 'No',
'type'=>'raw',
'htmlOptions'=>array('style'=>'width: 25px'),
'value'=>'$this->grid->dataProvider->pagination->currentPage
*$this->grid->dataProvider->pagination->pageSize + $row+1',
),
// i want to display p.kode,p.status from table status
'berlaku_punish',
'nilai',
array(
'class'=>'bootstrap.widgets.TbButtonColumn',
),
),
));
and my model : BasePunish.php
public function relations() {
return array(
'idStatus' => array(self::BELONGS_TO, 'Status', 'id_status'),
);
}
public function searchJoin() {
$criteria = new CDbCriteria;
$criteria->select = 'p.kode,p.status,t.nilai,t.berlaku_punish';
$criteria->join= 'RIGHT JOIN status p ON (t.id_status=p.id)';
$criteria->condition = 't.id_status IS NULL';
return new CActiveDataProvider($this, array(
'criteria' => $criteria,
'sort'=>array(
'defaultOrder'=>'kode ASC',
),
)
);
}
I might really did not understand what you are asking but still if nothing is working for you then you can try this
array(
'header'=>'Products',
'value'=>array($model,'gridCreateUser'),
),
In this, the value will try to find the function gridCreateUser in the class of which $model is the object. In your case i guess $model is the object of the BasePunish.
So in your BasePunish.php create a function gridCreateUser() and then you can return the value which you want to display in your widget.
eg:-
In your BasePunish.php
public function gridCreateUser($data)
{
// you can access the object $data here
// do what ever you want to do
$value='return whatever you want to return';
return $value;
// this $value will be displayed there
}

Displaying attributes from another model using CGRIDVIEW

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.)

Yii Relation data issue with HasMany

Currently we have two tables.
Locations and Addresses
Locations are a 1 to many relation to addresses on addresses.location_id.
We are trying to output all addresses related to a specific location in the cgridview:
admin.php
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'locations-grid',
'dataProvider'=>$location->search(),
'filter'=>$location,
'columns'=>array(
'id',
'name',
array(
'name' => 'address',
'value' => 'implode("<br>",CHtml::listData($data->addresses(),"id","address"))',
'filter' => CHtml::activeTextField($location, 'address'),
'type' => 'html',
),/**/
array(
'class'=>'CButtonColumn',
),
),
)); ?>
model (locations.php)
public function search()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->together = true;
$criteria->with = array('addresses');
$criteria->compare('id',$this->id);
$criteria->compare('name',$this->name,true);
$criteria->compare('addresses.address',$this->address,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
Is there a better way of going about getting the address data rather then imploding the $data->addresses function?
You can add a getter method to your Locations model.
public function getAddressNames($separator='<br>')
{
$names = array();
foreach($this->adresses as $address) {
$names[] = $address->address;
}
return implode($separator, $names);
}
Then you can use addressNames like a regular attribute in your gridview.

How to display one CGridView from two databases

i am trying to display two database tables source in one CGridView..
2 tables were reg.students and login.user..
my students model relation is,
public function relations()
{
Yii::app()->getModule('user');
return array(
'royaltyOutstandings' => array(self::HAS_MANY, 'RoyaltyOutstanding', 'studentID'),
'srkMedicalInfos' => array(self::HAS_MANY, 'SrkMedicalInfo', 'studentID'),
'parents' => array(self::HAS_ONE, 'SrkParents', 'studentID'),
'srkStudentWorksheets' => array(self::HAS_MANY, 'SrkStudentWorksheet', 'studentID'),
'user' => array(self::BELONGS_TO, 'User', 'centre_id'),
);
}
In user module,
public function tableName()
{ return 'login.user'; }
in cgridview columns array,
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'students-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
array(
'header' => 'No.',
'value' => '$row+1',
),
array('name' => 'user.centre_id',
'value'=>'$data->user->centre_id',
),
'... // & so on
Controller action is,
public function actionAdmin()
{
$this->layout = 'column3';
$form = new Reports ;
$model=new Students('search');
$model->unsetAttributes(); // clear any default values
if(isset($_GET['Students']))
$model->attributes=$_GET['Students'];
$this->render('admin',array(
'model'=>$model,
'form'=>$form,
));
}
If I understand you correctly, you want to show one or more relations in your gridview.
If this is what you want, have a look at this tutorial: http://www.yiiframework.com/wiki/281/searching-and-sorting-by-related-model-in-cgridview/
This tutorial doesn't only show you how to show a relation in your gridview but it also shows you how to sort and filter the data. good luck!

Categories