yii CGridView dataprovider and filter - yii

I know we can show a gridview with a model and it's search method and filter the results, but can we make a gridview with another dataprovider and another model like this and filter its results? Does filter needs to be a part of dataprovider?
$attr = Yii::app()->request->getParam($name);
$model = new User('search');
$model->unsetAttributes();
$model->setAttributes($attr);
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider' => $myDataProvider,
'filter' => $model,
'columns' => array(
array(
'name' => 'username',
'type' => 'raw',
'value' => 'CHtml::encode($data->username)'
),
array(
'name' => 'email',
'type' => 'raw',
),
),
));
The above code doesn't work and I need to add a filter on a previously made data provider.
Btw $attr has a valid data, but grid is not filtered.

$model doesn't affect $myDataProvider since the data provider is not obtained using this model.
$model->search() returns a CActiveDataProvider which contains a CDbCriteria instance. Different CDbCriteria can be combined using mergeWith(). So if you would like the data to be filtered using the values from the $model
...
$model->setAttributes($attr);
$newDataProvider=$model->search();
$myDataProvider->criteria->mergeWith($newDataProvider->criteria);
$this->widget('zii.widgets.grid.CGridView', array(
...

Filter does not need to be a part of dataprovider, but data provider needs to take the model into account, if you want to use it for filtering.
The way this is done by default is to create the data provider using search method on your model, which sets conditions of your data provider based on model values, like so:
'dataProvider' => $model->search()
There is nothing preventing you from creating different data provider, for example:
'dataProvider' => $model->createAnotherDataProvider()
And in your User model:
public function createAnotherDataProvider() {
{
// create your second data provider here
// with filtering based on model's attributes, e.g.:
$criteria = new CDbCriteria;
$criteria->compare('someAttribute', $this->someAttribute);
return new CActiveDataProvider('User', array(
'criteria' => $criteria,
));
}

Related

Sorting in yii 1.1

I have question regarding yii 1.1 sort.
I have three tables ticket, repairLogs and part table .
Following relations have been defined in Ticket model.
'repairLogs' => array(self::HAS_MANY, 'RepairLog', 'ticket_id', 'order'=>'ts DESC'),
and in repairLogs Table
'part' => array(self::BELONGS_TO, 'Part', 'part_id'),
Part table has a column 'number' and I want to sort the data based on "number". Can anyone guide me how to do this since I am new to the yii 1.1 framework.
You can do this during the find()
Ticket::model()->with(array('part', 'repairLogs'))->findAll(
array(
// your conditions here
'order' => 'part.number DESC', // "part" is the alias defined in your relation array (in the Ticket model file)
'limit' => 10,
)
);
If you are using A dataProvider, you can set it as a default order:
new CActiveDataProvider('Ticket', array(
'criteria' => $criteria, // you criteria that should include the "with" part
'sort' => array(
'defaultOrder' => 'part.number DESC',
)
));

how to convert query with multiple group by columns to CActiveDataProvider in Yii 1.1.14?

I need to conver this sql statement that has a multi column group by clause into CActiveDataProvider in Yii version 1.1.4?
select * from my_table_name group by bookname,categorytitle,bookkey order by bookname,categorytitle,bookkey asc;
I need a CActiveDataProvider to feed a CGridView search function. Apparently, I only have a simple return in my model of the search function that runs my CGridView
return new CActiveDataProvider(get_class($this),
array(
'criteria' => $criteria,
'sort' => array(
'defaultOrder' => 'id ASC'
),
'pagination' => array('pageSize' => ActiveRecord::PAGE_SIZE),
));
so how to convert the sql statement that I gave into CActiveDataProvider format ?
You can do using two way -
Make sql view and than create yii model and use this in your
controller or page view.
Create custom search function in your existing model and use group by
e.g. -
<?php
public function new_search(){
$criteria = new CDbCriteria();
...
..
$criteria->group = "bookname, categorytitle, bookkey";
$criteria->order = "bookname, categorytitle, bookkey";
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
'pagination'=>array('pageSize'=>100)
));
}
?>

Yii data provider with clist view

i want to search multiple models in Yii application. The search result are displayed in CList view. Need to use dataprovider in list view. So how can i use multiple dataprovider in Clist view?
You cannot make use of multiple dataproviders rather you combine the result in a single dataprovider
Something like this to get you started:
public function actionSearch($q) {
// Sanitize input
$q = strtolower(strip_tags($q));
$q = preg_replace('/[^a-z 0-9 _ \- \']/', '', $q);
$model1 = Model1::model()->findAll('title LIKE "%'.$q.'%"');
$model2 = Model2::model()->findAll('title LIKE "%'.$q.'%"');
$rawData = array_merge($model1, $model2);
$dataProvider = new CArrayDataProvider($rawData, array(
'sort'=>array(
'attributes'=>array(
'datePublished DESC', 'title',
),
),
'pagination'=>array(
'pageSize'=>10,
),
));
$this->render('search', array(
'dataProvider' => $dataProvider,
'query' => $q,
));
}

How to sort the fields from relation table in Yii?

I am trying to implement sorting with Yii list view. I have joined 2 tables named provider_favourite and service_request in list view. And the fields and contents from both tables are listing in the list view. But sorting is working only in provider_favourite table, not from service_request table.How can I sort the fields from service_request table? Iam using csort for sorting. I also tried CGrid view. But the same problem is happening in grid view also ..
Iam using the following code to join
$criteria = new CDbCriteria;
$criteria->select = 'favourite_notes,favourite, favourite_added_date,max_budget,preferred_location,service_name';
$criteria->join = 'LEFT JOIN service_request AS s ON service_request_id = favourite';
$criteria->condition = 'favourite_type = 1';
$sort=new CSort('ProviderFavourite');
// $sort->defaultOrder='s.max_budget ';
$sort->applyOrder($criteria);
$sort->attributes = array(
'max_budget' => 'service_request.max_budget',
'service_name' => 'service_request.service_name',
'favourite_added_date'
);
$type = 2;
$data = new CActiveDataProvider('ProviderFavourite', array('criteria' => $criteria, 'pagination' => array('pageSize' => 4),'sort'=>$sort
));
$this->renderPartial('favourites', array(
'ModelInstance' => ProviderFavourite::model()->findAll($criteria),
'dataProvider' => $data, 'type' => $type, 'sort'=>$sort,
));
and also Iam providing sortable attributes in list view
$this->widget('zii.widgets.CListView', array('dataProvider'=>$dataProvider,'itemView'=>'index_1',
'id'=>'request',
'template' => ' {items}{pager}',
'sortableAttributes'=>array('favourite_notes','max_budget','service_name')
));
If more details needed, I will provide. Thanks in advance
You have to specify attributes property of your $sort instance. By default only fields of $modelClass (ProviderFavourite in your case) are sortable.
I think it could look like this (not tested):
$sort->attributes = array(
'service_name' => array(
'asc' => 's.service_name ASC',
'desc' => 's.service_name DESC'
),
// ...another sortable virtual attributes from service_request table
"*"
);
You should not create a CSort object in $sort. The CActiveDataProvider will already provide you with the right sort object. The way you do it, you apply the sort criteria to $criteria before you configure the sort attributes. That can not work.
You should try a simple setup like this instead:
$data = new CActiveDataProvider('ProviderFavourite', array(
'criteria' => $criteria,
'pagination' => array('pageSize' => 4),
'sort'=> array(
'attributes' => array(
'service_name' => array(
'asc' => 's.service_name ASC',
'desc' => 's.service_name DESC'
),
// ...
),
));
If you need to access the related CSort object (which you usually don't if you use a CGridView or CListView, because they deal with that for you), then you get it via $data->sort.

Yii View, Replacing some database values in CGridView

I am new with Yii, Sorry if my question might be stupid, I am using CGridView to show some fields of my database in a table:
<?php echo CHtml::link('Advanced Search','#',array('class'=>'search-button')); ?>
<div class="search-form" style="display:none">
<?php $this->renderPartial('_search',array(
'model'=>$model,
)); ?>
</div><!-- search-form -->
<?php
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'show-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'id',
'title',
'brief',
'tbl_season_id',
'on_season',
array(
'name'=>'status',
'value'=>'Lookup::item("NewsStatus",$data->status)',
'filter'=> Lookup::items('NewsStatus'),
),
array(
'class'=>'CButtonColumn',
),
),
)); ?>
</div>
I want to replace some of the values that are shown, for example, the on_season field is binary and in the table the values are 0 or 1, I want to change this values to Yes and NO,
And tbl_season_id is a foreign key form another table, I would like to get the name of the season and put it instead of the id which is not understandable by the users.
You can refer this wiki article for customizing your column values to your heart's content
Yii Documentataion: cgridview-render-customized-complex-datacolumns
Just remember that the value property can be an expression string, which is later evaluated for each data of rows. So you have a method call there which can dynamically calculate any value for you depending on the current values of that row.
Let you have two table
1): clients 2): projects
Relation is a client has many projects.
in model
and clients model the relation is (the Client table model name is Client)
class Client extends CActiveRecord{
}
and relations() method ;
return array(
'projects' => array(self::HAS_MANY, 'Projects', 'clients_id'),
);
project model the relation is (the project table model name is Projects)
class Projects extends CActiveRecord{
}
and relations() method ;
return array(
'clients' => array(self::BELONGS_TO, 'Client', 'clients_id')
);
Now
now you can use the following to get the client_name replace the client_id in proejct table
in CGridView
'dataProvider' => $model->search(),
'columns' => array(
'id',
'project_name',
array(
'name' => 'client Name',
'value' => '$data->clients->name', //where name is Client model attribute
),
)
and
Project view page in CDetailView you can use the following
'data' => $model,
'attributes' => array(
'id',
'project_name',
array(
'name'=>'Client Name',
'value'=>$model->clients->name ,
),
)
if you have client relation with company table (a company has many clients )
client model
'company' => array(self::BELONGS_TO, 'Company', 'company_id'),
you can also get the company name by following method in
index (CGridview)
array(
'name' => 'client Name',
'value' => '$data->clients->company->name', //where name is company model attribute
),
and in view CDetailView
array(
'name'=>'Client Name',
'value'=>$model->clients->company->name ,
),