Reputation: 315
I will keep this quite abstract as I believe (hope) this is a general problem with easy work-around. I have modified a gii generated admin page as followed. The search form is modified to select records pertaining to a given user. This works, and when searching the grid updates fine.
I have customized the output of the grid to contain various user related data, for example each record reflecting some user data.
When I use the grid filters (to the top of the widget) the filter results fine, however I lose the original filter of the user.
So, I query the user and it selects some some results and when I want to filter these results on some other criteria it produces the results generated from the entire dataset, rather than the user-filtered results.
A side note, I have tried installing http://www.yiiframework.com/extension/remember-filters-gridview/
This actually produces some result, as when I filter as specified above it does not work, but when I refresh the page, the results are exactly as desired as it has saved both filters from the previous session.
Hope this is clear, And please help! Thank you
Upvotes: 0
Views: 431
Reputation: 11
the answer may be different depending on the conditions of your code:
1 ) the form for user_id is GET or POST? if is POST, you must to be change to GET because the .CGridView is for GET
2) Keep in mind that we are working with two separate forms and, therefore, you must verify your code if in each case receive the arguments necessary for performing the operation... If not, you must change the URL or sesion or cookie to always receive all the data you need.
3) The CgridView add the filters to the current url and send for AJAX and I guess that the form for select the user_id is normal HTTP GET (not for AJAX) and the name of the form field to retrieve the user ID is user_id
a) The filter fields are named CGridView "model_name['attribute_name']" then in the controller:
public function actionAdmin($user_id="") {
...
if (!empty($user_id)) $model->user_id = intval($user_id);
if (isset($_GET['model_name'] ) $model->attributes = $_GET['model_name'];
...
}
b) If the user ID the form is also available as a column CGridWiew then:
public function actionAdmin($user_id="") {
...
if (isset($_GET['model_name'] ) {
if (! isset($_GET['model_name']['user_id']) && ! empty($user_id) ) {
$_GET['model_name']['user_id'] = $user_id;
}
$model->attributes = $_GET['model_name'];
} elseif (!empty($user_id)) $model->user_id = intval($user_id);
...
}
c) is your actionAdmin is like actionAdmin() you must retrive the user ID with
yii::app()->request->getParam('user_id');
Upvotes: 0
Reputation: 1912
Code is always helpful but if I'm understanding you correctly I do something similar for displaying user messages; I set an initial filter to find only the messages that were sent to the logged in user, and then I also need to let the user filter the messages by subject and sender. I don't know the names of your models or criteria, so here is a simplified example of how I do it:
Controller:
public function actionIndex()
{
$model = new Message('search');
$model->unsetAttributes();
if(isset($_GET['Message']))
$model->attributes = $_GET['Message'];
// Set default filter
$model->msg_to = Yii::app()->user->id;
$this->render('index', array('model' => $model));
}
View:
$this->widget('zii.widgets.grid.CGridView', array(
'id'=> 'message-grid',
'dataProvider'=> $model->search(),
'filter'=> $model,
));
Model:
public function search()
{
$criteria = new CDbCriteria;
$criteria->compare('from',$this->from);
$criteria->compare('msg_to',$this->msg_to);
$criteria->compare('from_name',$this->from_name,true);
$criteria->compare('subject',$this->subject,true);
$criteria->compare('body',$this->body,true);
$criteria->compare('read',$this->read);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
'pagination'=>array('pageSize'=>15),
));
}
If your criteria for the default filter is quite complicated, the best thing to do is to create a named scope in the model like this:
public function scopes()
{
return array(
'inbox' => array(
'condition' => 't.msg_to = :user_id',
'params' => array(':user_id' => Yii::app()->user->id),
'order' => 'min(t.read) ASC, t.posted_on DESC',
),
);
}
To use that scope you would write $model->inbox()->search()
in the CGridView instead of $model->search()
You should also then remove the $model->msg_to = Yii::app()->user->id;
line
One last thing: if your criteria requires input from the user, e.g. through a $_GET variable, you can use "Parameterized Named Scopes." See section on this page: http://www.yiiframework.com/doc/guide/1.1/en/database.ar#named-scopes You would use those in the same way: $model->inbox()->search()
Upvotes: 1