how to make search gridview with custom query in yii - php

I created a simple gridview using a custom query. This is working fine for me but search box doesn't work. How do I make the search box work?
Here is my code:
UserController.php
public function actionAdmin()
{
$sql = 'SELECT * FROM user';
$rawData = Yii::app()->db->createCommand($sql);
$count = Yii::app()->db->createCommand('SELECT COUNT(*) FROM (' . $sql . ') as count_alias')->queryScalar();
$model = new CSqlDataProvider($rawData, array(
'keyField' => 'id',
'totalItemCount' => $count,
'sort' => array(
'attributes' => array(
'id','title', 'type'
),
'defaultOrder' => array(
'id' => CSort::SORT_ASC, //default sort value
),
),
'pagination' => array(
'pageSize' => 10,
),
));
$this->render('admin', array(
'model' => $model,
));
}
Admin.php (View file)
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'user-grid',
'dataProvider'=>$model,
'filter'=>$model,
'columns'=>array(
array('header'=>'firstname','value'=>'$data["firstname"]'),
array('header'=>'lastname','value'=>'$data["lastname"]'),
array('header'=>'username','value'=>'$data["username"]'),
),
)); ?>

Related

Yii Framework Undefined Offset: 0

I am trying to use CGridView with custom query, and trying to build a very simple with no sorting and stuff.
My View contains simple CGridView
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$dataProvider,
));
And my controller passes the $dataProvider to the view
$count=Yii::app()->db->createCommand('SELECT COUNT(*) FROM ( ' . $query . ' ) as count')->queryScalar();
$dataProvider=new CSqlDataProvider($query, array(
'keyField' => false,
'totalItemCount'=>$count,
'pagination'=>array(
'pageSize'=>10,
),
));
I don't have a keyField therefore I have set it to false. Moreover, I have tried printing out data using var_dump, data is present in the variable, but still I get this undefined offset error.
You need to set the mapping for sorting.
/*
Query results
array(
array(
'id' => 1,
'username' => 'username',
'email' => 'email'
),
...
)
*/
return new CSqlDataProvider($query, array(
'keyField' => 'id', //required, any field from query results
'totalItemCount'=> $count,
'pagination' => array(
'pageSize' => 10
),
'sort' => array(
'defaultOrder' => array(
'username' => CSort::SORT_DESC,
),
'attributes' => array(
'username',
'email',
),
),
));
//grid.columns
array(
array(
'name' => 'id' //WO sort
),
array(
'name' => 'username', //with sort (isset in dp.sort.attributes)
),
)
you have to provide keyfield other than false, change keyfield primary key of your query Table

how to apply sorting on model method in CGridView Yii

I have User model which contain a function that calculates the average revenue per user. Now i want apply sorting in CGridView on the column which is associated with getAvgRevenue() function. While license is relation in the User model.
Here is my code,
public class User{
$user_id;
$email;
public function getAvgRevenue(){
$count = 0;
$revenue = 0;
foreach ($this->license as $license){
$revenue += $license->price;
$count++;
}
if($count!= 0){
$averageRevenue = $revenue/$count;
return $averageRevenue;
}
else{
return null;
}
}
}
In Controller
$modelUser = new CActiveDataProvider('User', array(
'sort' => array(
'attributes' => array(
'user_id',
'email',
'averagerevenue'
),
'defaultOrder' => array(
'user_id' => CSort::SORT_ASC,
),
),
));
In view
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id' => 'user-grid',
'dataProvider' => $modelUser,
'columns' => array(
array(
'header' => 'User ID',
'name' => 'user_id',
),
array(
'header' => 'Email',
'name' => 'email',
),
array(
'header'=>'Average Revenue',
'value'=>'$data->averagerevenue',
),
)
));
?>
Sorting is applicable on user_id and email but Average Revenue column is not sortable. how to specify model method in sort() of CActiveDataprovider
Please help me to solve the problem.
Try this:
$modelUser = new CActiveDataProvider('User', array(
'sort' => array(
'attributes' => array(
'user_id',
'email',
'avgRevenue' //here's the change for you
),
'defaultOrder' => array(
'user_id' => CSort::SORT_ASC,
),
),
));
And your gridview column should be:
array(
'header'=>'Average Revenue',
'value'=>'avgRevenue',
),
and you can read more info on it over here:
http://www.yiiframework.com/wiki/167/understanding-virtual-attributes-and-get-set-methods/

How to make CGridView column sortable using CSqldataprovider?

How to make CGridView columns sortable (On clicking column title) using CSqldataprovider.
In controller
$sql = "select id ,name, address
from User
where city = 'ABC' ";
$rawData = Yii::app()->db->createCommand($sql);
return $allMovies = new CSqlDataProvider($rawData, array(
'keyField' => 'id',
'sort'=>array(
'attributes'=>array(
'id', 'name', 'address',
),
),
'pagination' => array(
'pageSize' => 10,
),
));
In view
$this->widget('zii.widgets.grid.CGridView', array(
'id' => 'all_movies',
'dataProvider' => $allMoviesStats,
'columns' => array(
'id',
'name',
'address',
'city'
)
)
);?>
It is giving error
"error":{"code":99,"text":"Property \"CGridView.sort\" is not defined.
You need to create object for CDbCriteria and Sort class and try to use as below and change the code for your requirement.
public function search()
{
$criteria=new CDbCriteria;
$criteria->condition="active=1";
if($this->name=="Enter Country Name" || $this->name=='') {
$this->name='';
} else {
$this->name=$this->name;
}
$criteria->compare('name',$this->name,true);
$sort = new CSort;
$sort->defaultOrder = 'id DESC';
$sort->attributes = array(
'name' => array(
'asc' =>'name',
'desc' =>'name DESC',
),
...
... // attributes to sort
);
return new CActiveDataProvider('Country', array( //Country is nothing but you model class name
'criteria' =>$criteria,
'sort' => $sort,
'pagination'=>array('pageSize'=> 10),
));
}

Yii Excel write generated header no rows

I'm using Excel write in Yii.
Every time I generate the Excel it gives me just the header but no output, although my database contains rows.
controller:
$sql = "SELECT trucker as Trucker, (SELECT COUNT(*) FROM courses where association_trucker_id = assoc_truckerid) as Units, CONCAT(buss_add_add,', ',buss_add_prov,', ',buss_add_city,', ',buss_add_zip) as Address, CONCAT(rep_lname,', ',rep_fname,' ',rep_mname) as 'Contact Person', rep_telno as 'Office No', rep_email as Email FROM `students`"; // your sql
$rawData = Yii::app()->db->createCommand($sql)->queryAll(); // you get them in an array
$count = Yii::app()->db->createCommand('SELECT COUNT(*) FROM (' . $sql . ') as count_alias')->queryScalar();
$model = new CArrayDataProvider($posts,
array(
'totalItemCount' => $count,
'sort' => array(
'attributes' => array(
'trucker'
),
),
'pagination' => array(
'pageSize' => 5000000, // large number so you export all to excel
),
)
);
$this->renderPartial('truckerexcel', array(
'model' => $model, 'truckerid' => $truckerlist,
));
View:
<?php
$this->widget('EExcelWriter', array(
'dataProvider' => $model,
'title' => 'EExcelWriter',
'stream' => TRUE,
'fileName' => 'TRUCKERS_'.date('Y-m-d', time()).'.xls',
'columns' => array(
'trucker'
),
));
?>
Instead of
$model = new CArrayDataProvider($posts,
you should be using the variable $rawData:
$model = new CArrayDataProvider($rawData,

CSqlDataProvider attributeLabels

<?php
//form
class SomeForm extends CFormModel
{
public $id;
public $user_id;
public function search()
{
$sql = 'SELECT id, name FROM some_table';
$sql_count = 'SELECT COUNT(id) FROM some_table';
return new CSqlDataProvider($sql, array(
'totalItemCount' => Yii::app()->db->createCommand($sql_count)->queryScalar(),
'sort' => array(
'attributes' => array(
'id', 'name',
),
),
'pagination' => array(
'pageSize' => 50,
),
));
}
public function attributeLabels()
{
return array(
'id' => 'ID',
'name' => 'NAME',
);
}
}
//grid
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider' => $model->search(), //$model = new SomeForm()
'columns' => array(
'id',
'name'
),
));
/*
Result:
id | name
---------
1 | John
EXPECTED Result:
ID | NAME
---------
1 | John
*/
How to set custom names for query columns ?
The simplest way:
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider' => $model->search(), //$model = new SomeForm()
'columns' => array(
'id::ID',
'name::NAME'
),
));
Another way:
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider' => $model->search(), //$model = new SomeForm()
'columns' => array(
array(
'header' => 'ID',
'name' => 'id'
),
array(
'header' => 'NAME',
'name' => 'name',
),
),
));
Link to api doc
If you don't want to use custom names; if you want to use your labels declared in your model, then you can do this:
Create an empty instance of your model and pass it to your view. The view will thus utilize the $data (CSqlDataProvider) as well as the empty model.
$labelModel = new my_model;
$this->widget('zii.widgets.CListView',array(
'dataProvider'=>$my_model->search(), //returns a CSqlDataProvider
'itemView'=> '_view',
'viewData' => array('labelModel' => $labelModel),
));
Use the empty model - together with getAttributeLabel - to echo labels.
Use $data['field_name'] to echo the data.
This link has more info on how to pass the additional model to the CListView or CGridView.

Categories