I'm trying to load a cGridView with the results of a query between two tables (charity and votes).
Trying to show the number of votes in the vote table for a charity. The vote table has a FK to the charity table.
I could do this in SQL with a left join, but cGridView requires a CActiveDataProvider object to display the data and I am unsure how I can join the two tables to return a result that not only counts, but also doesn't show any results that are equal to 0 and ordered by the votes.
I currently am doing:
in the Vote Model:
public function relations()
{
return array(
'voteCount'=>array(self::STAT, 'Vote', 'charity_id'),
);
}
charity_id being the FK for the charity table.
Then to build the CGridView widget:
$criteria=new CDbCriteria(array(
'with' => 'voteCount',
));
$dataProvider=new CActiveDataProvider('Charity', array(
'pagination' => false,
'criteria' => $criteria,
));
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$dataProvider,
'ajaxUpdate'=>true,
'columns'=>array(
'Name',
array(
'name'=>'vote.voteCount',
'value'=>'CHtml::encode($data->voteCount)',
),
),
));
Right now it's returning multiple results and I can't seem to figure out how to sort and add a where clause as well.
Any help?
Try add to Charity model
public function relations()
{
return array(
'vote'=>array(self::HAS_ONE, 'Vote', 'charity_id'),
);
}
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$dataProvider,
'ajaxUpdate'=>true,
'columns'=>array(
'Name',
array(
'name'=>'Vote Count',
'value'=>'CHtml::encode($data->vote->voteCount)',
),
),
));
You need some minor changes in
Vote.php (Vote Model)
public function relations()
{
return array(
'voteCount'=>array(self::STAT, 'Vote', 'charity_id'),
);
}
Add a field in attributeLabels()
'voteCount'=>'Votes',
and In CGridView add the 'Votes' column
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$dataProvider,
'ajaxUpdate'=>true,
'columns'=>array(
'Name',
'Votes',
),
));
Related
In my ClistView i'm trying to set a default sort and define my sortable attributes in my view. I've gotten this far
in my actionIndex()
$criteria=new CDbCriteria(array(
'condition'=>'make_code!="00"',
));
$dataProvider=new CActiveDataProvider('StoreNew', array(
'criteria'=>$criteria,
'sort'=>array(
'defaultOrder'=>'_make DESC',
'attributes'=>array(
'_make'=>array(
'asc'=>'_make',
'desc'=>'_make DESC',
),
'*', //if attributes contains a star ('*') element, the name will also be used to match against all model attributes.
)
),
));
in my model
public function relations()
{
return array(
'_state' => array(self::BELONGS_TO, 'State', 'state'),
'_make' => array(self::BELONGS_TO, 'pMake', '',
'foreignKey' => array('make_code'=>'make_code')),
);
}
and in my view
$this->widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider,
'itemView'=>'_view',
'sortableAttributes'=>array(
'_make' => 'Make',
'store',
'state',
),
));
im getting this error
CDbCommand failed to execute the SQL statement: SQLSTATE[42S22]: Column not found: 1054 Unknown column '_make' in 'order clause'. The SQL statement executed was: SELECT * FROM `store_new` `t` WHERE make_code!="00" ORDER BY _make DESC LIMIT 10
how to i sort table pMake.make?
try this in your actionIndex()
$criteria=new CDbCriteria(array(
'with' => array('_make'), // join the _make relation you defined in your model into this query
'condition'=>'t.make_code!="00"',
));
then
$dataProvider=new CActiveDataProvider('StoreNew', array(
'criteria'=>$criteria,
'sort'=>array(
'attributes'=>array(
'make'=>array(
'asc'=>'_make.make',
'desc'=>'_make.make DESC',
),
'*', //if attributes contains a star ('*') element, the name will also be used to match against all model attributes.
)
),
));
then in your view
'sortableAttributes'=>array(
'make' => 'Make', //you can call "make" base on 'attributes'=>array('make'=>array())
'store',
'state',
),
note tested. hope it works.
I have a admin.php created by gii, inside it there's a table column 'lang_id' have relation to primary key 'id' of table 'lang'.
What should I put in the columns array ? I think i should use "Lang.name" but it didn't work.
protect/view/mainmenu/admin.php
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'mainmenu-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'menu_id',
'Lang.name', // I want this column display the name of Language, instead of lang_id
'name',
'remark',
array(
'class'=>'CButtonColumn',
'template'=>'{update}'
),
),
)); ?>
protect/model/Mainmenu.php
public function relations(){
return array(
'lang'=>array(self::HAS_ONE, 'Lang', 'lang_id')
);
}
public function search(){
$criteria=new CDbCriteria;
$criteria->compare('id',$this->id,true);
$criteria->compare('menu_id',$this->menu_id);
$criteria->compare('lang_id',$this->lang_id);
$criteria->compare('name',$this->name,true);
$criteria->compare('sorting',$this->sorting);
$criteria->compare('remark',$this->remark,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
the relation name is lang. Whereas in the columns array you have used Lang (with l in uppercase).
So you will have to do this
'lang.name'
in the columns array
and second thing in the search()
You need to add one more line
$criteria->with = array(
'lang'
);
maybe this can work
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'mainmenu-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'menu_id',
array(
'name'=>'Lang',
'value'=>'$data->lang->name',
),
'name',
'remark',
array(
'class'=>'CButtonColumn',
'template'=>'{update}'
),
),
)); ?>
I have these codes in my view file:
<?php $this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$dataProvider,
'columns'=>array(
array(
'name' => 'Name',
'type'=>'raw',
'value' => 'CHtml::link(CHtml::encode($data->profile->first_name." ".$data->profile->last_name),array("match/view","id"=>$data->id))',
),
array(
'name' => 'Similiarity Score',
'type'=>'raw',
'value' => array($this, 'calculateScore'),
),
),
)); ?>
You will notice that the second column call the function calculateScore($data, $row) in the controller file. Is there anyway I can sort the table based on these scores?
I assume that your result is from a database and you use a CActiveDataProvider or CSqlDataProvider. In this case you will have to move the logic for calculateScore into the DB query somehow. You can add a public property score to your model class and add this to the select property of your CDbCriteria:
$criteria->select = array('*', '... SQL FOR SCORE CALC HERE ... AS score');
Then you will be able to sort by that score in the sort definition of your CActiveDataProvider:
'sort' => array(
'attributes' => array(
// ...
'score',
I have a problem , i have 2 tables users and data , relation is one to one , here is code for dataProvider
$dataProvider = new CActiveDataProvider('Users', array(
'pagination'=> array(
'pageSize'=> 10
),
'criteria'=>array(
'with' => array (
'data'=>array(
'joinType'=>'JOIN')
)
),
)
));
and relations 'data' => array(self::HAS_ONE, 'Data', 'id');
and code for TbGridView
$this->widget('bootstrap.widgets.TbGridView', array(
'dataProvider'=>$dataProvider,
'template'=>"{items} {pager}",
'itemsCssClass'=>'table table-striped table-bordered table-condensed tableNews',
'columns'=>array(
array('name'=>'id', 'header'=>'#'),
array('name'=>'name'),
array('name'=>'email'),
array('name'=>'data.id'),
array('name'=>'data.investment_amount')
));
for second table i have to put data.fildname , else is not working , and fildnames of second table is not clickable
what can be the problem , thank you
return new CActiveDataProvider("Users", array(
'criteria'=>$criteria,
'sort'=>array(
'defaultOrder'=>$defaultOrder,
'attributes'=>array(
'id'=>array(
'asc'=>'t.id',
'desc'=>'t.id DESC',
),
'data.investment_amount'=>array(
'asc'=>'data.investment_amount',
'desc'=>'data.investment_amount DESC',
),
but if you use sort you need to define all names inside attributes array
I have two tables Table A and Table B.
I have the pk of table A ,as fk called member_id in table B.
While girdview display of table B, I want to show the "Member name" in table A, using the "member_id" in table B.
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'transaction-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'id',
'member_id',
'Location',
...
array(
'class'=>'CButtonColumn',
'template'=>'{view}',
),
),
));
You need to setup a relation to that table, and you can use the relation to reference that field like this:
$data->member->name;
In your transaction model you would place something like:
public function relations() {
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'member' => array(self::BELONGS_TO, 'Member', 'member_id'),// foreign key
);
}
and for grid you would do like:
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'transaction-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'id',
array(
'header' => 'Member',
'name' => 'member_id',
'value' => '$data->member->name'
),
'Location',
...
array(
'class'=>'CButtonColumn',
'template'=>'{view}',
),
),
));