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.