How to keep filters simple in CGridView

  1. Keep is simple
  2. One step ahead

The problem is not new: after setting some filters in a grid (typically in admin view), and gone to another page, returning in the grid's page I would like to find the filters with previous setting mantained.

There are extensions doing that (and more) but I always look for the simplest solution. So, thanking some users that in various contributes approach the problem, this is the simplest way I found.

Keep is simple ¶

The admin action has usually this structure, where the render command calls a view containing the CGridView widget ("Fornitore" is the model):

public function actionAdmin() {
    $model = new Fornitore('search');
    $model->unsetAttributes();

    if (isset($_GET['Fornitore']))
        $model->attributes = $_GET['Fornitore'];

    $this->render('admin', array(
        'model' => $model,
    ));
}

The added code to obtain the result is just a few lines, as follows:

public function actionAdmin() {
    $model = new Fornitore('search');
    $model->unsetAttributes();

    if (isset($_GET['Fornitore'])) {
        $model->attributes = $_GET['Fornitore'];
        // stores filters setting in user's variable
        Yii::app()->user->setState('filtroFornitore', $_GET);
    } else {
        if (isset(Yii::app()->user->filtroFornitore) {
            // restores the previous stored filters setting
            foreach (Yii::app()->user->filtroFornitore['Fornitore'] as $campo => $valore) {
                $model->$campo = $valore;
            }
        } else {
            // optional default filters
            $model->attivo = 1;
        }
    }

    $this->render('admin', array(
        'model' => $model,
    ));
}

The settings are stored in a persistent user session variable; customizing the name of the variable with model name, it's possible to use the mechanism in several models pages at the same time.

Using a user session variable, it's lost when user logoff, so there are no problem in multiuser environment. More, if you want to restore filters setting through sessions, I think it's simple to store them in database (but I didn't try it).

The "optional default filters" let you decide to set some filters as default when the page is open for first time.

One step ahead ¶

Some more to let clearing filters simpler too. Just a little action, and a link somewhere in the grid's page to call it.

// this in the controller...
public function actionPulisciFiltro() {
    if (isset(Yii::app()->user->filtroFornitore)) {
        unset(Yii::app()->user->filtroFornitore);
    }
    $this->redirect(array('admin'));
}

// ...and this in the view
echo CHtml::link('Pulisci filtri', Yii::app()->controller->createUrl('pulisciFiltro'));

Destroying the variable, it restores the initial situation, clearing filters and setting, if present, the default values too.

It's all. Hope this is useful.