搜索表单和内联cGridView过滤器的互操作性

时间:2013-02-04 23:52:23

标签: php yii cgridview

我会保持这个非常抽象,因为我相信(希望)这是一个易于解决的普遍问题。 我修改了一个gii生成的管理页面,如下所示。 修改搜索表单以选择与给定用户有关的记录。这有效,并且在搜索网格时更新。

我已经定制了网格的输出以包含各种与用户相关的数据,例如每条记录都反映了一些用户数据。

当我使用网格过滤器(到窗口小部件的顶部)时,过滤器结果很好,但是我丢失了用户的原始过滤器。

因此,我查询用户并选择一些结果,当我想在其他一些标准上过滤这些结果时,它会生成从整个数据集生成的结果,而不是用户过滤的结果。

附注,我已尝试安装http://www.yiiframework.com/extension/remember-filters-gridview/

这实际上会产生一些结果,因为当我按照上面指定的方式进行过滤时,它不起作用,但是当我刷新页面时,结果与保存上一个会话中的两个过滤器完全一致。

希望这很清楚, 请帮忙! 谢谢

2 个答案:

答案 0 :(得分:1)

代码总是有用但如果我正确理解你,我会做类似的事情来显示用户信息;我设置了一个初始过滤器,只查找发送给登录用户的消息,然后我还需要让用户按主题和发件人过滤消息。我不知道你的模型或标准的名称,所以这里是我如何做的简化示例:

控制器:

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));
}

查看:

$this->widget('zii.widgets.grid.CGridView', array(
    'id'=> 'message-grid',
    'dataProvider'=> $model->search(),
    'filter'=> $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),
    ));
}

如果您对默认过滤器的标准非常复杂,那么最好的办法是在模型中创建named scope,如下所示:

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',
        ),
    );

}

要使用该范围,您可以在CGridView中编写$model->inbox()->search()而不是$model->search() 您还应该删除$model->msg_to = Yii::app()->user->id;

最后一件事:如果您的标准需要用户输入,例如通过$ _GET变量,您可以使用“参数化命名范围”。请参阅此页面上的相应部分:http://www.yiiframework.com/doc/guide/1.1/en/database.ar#named-scopes您可以采用相同的方式使用这些内容:$model->inbox()->search()

答案 1 :(得分:0)

答案可能会有所不同,具体取决于您的代码条件:

1)user_id的表单是GET还是POST?如果是POST,则必须更改为GET,因为.CGridView用于GET

2)请记住,我们正在使用两个单独的表单,因此,如果在每种情况下都接收执行操作所需的参数,则必须验证您的代码...如果不是,则必须更改URL或sesion或cookie以始终接收您需要的所有数据。

3)CgridView将过滤器添加到当前url并发送给AJAX,我猜选择user_id的表单是普通的HTTP GET(不适用于AJAX),并且用于检索用户ID的表单字段的名称是USER_ID

a)过滤器字段名为CGridView“model_name ['attribute_name']”然后在控制器中:

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)如果用户ID表单也可以作为CGridWiew列使用:

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)你的actionAdmin就像actionAdmin()你必须用

来检索用户ID
yii::app()->request->getParam('user_id');