Keep Filter And Sort

Problem:

1-I display cgridview with thousands of rows;

2-I filter let’s say 100 rows that i need to edit according to some criteria;

3-I update the first one of those 100 rows;

4-I now have cgridview with thousands of rows again.

How do I keep the filtered (and sort) of my 100 rows that I wish to edit so I can update them all one by one without having to filter all data each time? What’s the best approach to do this?

Thanks in advance.

The easiest way I can think of is to store your search filters ($_GET array) in session then after editing, redirect them back to your gridview but with the $_GET variables appended to the URL, so that your grid shows the last state it was in.

to store filter you can do something like:




    public function actionIndex() {

        $filter = new Model( 'search' );

        $filter->unsetAttributes();  // clear any default values


        //load session stored filter

        if( isset( Yii::app()->session['_ModelFilter'] ) ) {

            $filter->setAttributes( Yii::app()->session['_ModelFilter'], false );

        }


        //load filter provided in GET values

        if( isset( $_GET['Model'] ) ) {

            $filter->attributes = $_GET['Model'];

        }


        $this->render( 'index', array(

            'dataProvider' => $filter->search(),

            'filter' => $filter,

        ) );

        Yii::app()->session['_ModelFilter'] = $filter->getAttributes(); //important to have this AFTER view is rendered. If there are arrors in filter data (i.e. unrecognized date format) you will not store them in session causing everything to crash every time you visit index action..

    }



sotring sorting and page number is quite different story and as for now I do not have good solution. however those params are also sent as GET params so you can also store them…

What about trying to open the update action in a modal form so that the user never gets to leave the original cgridview state? Do you think this would be a good approach? if so, any idea on how to do it?

To whom might be of interest I think I’ve solved this problem.

I still would humbly ask for you opinion about my solution.




public function actionUpdate($id)

{

  $model=$this->loadModel($id);

  if(isset($_POST['alunos'])):	

      $model->attributes=$_POST['alunos'];

      if($model->save()):

	$this->redirect(array('index','fromupdate'=>'true')); <--add a 'I come from update...'

      endif;  

   endif;

    

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

          

  }



then in my action:





public function actionIndex()

{

 $model=new alunos('search');

 $model->unsetAttributes();  // clear any default values

 if (isset($_GET['sort'])):              

    Yii::app()->user->setState('alunos_sort', $_GET['sort']);       

 endif;

    

 if(isset($_GET['alunos'])):

    $model->attributes=$_GET['alunos'];

 endif;

 

 if(isset($_GET['fromupdate'])): <- and then I've added this piece of code

    $model=Yii::app()->user->getState('alunosModel');

    $_GET['sort']=Yii::app()->user->getState('alunos_sort');  

    $modal = $model->search();

 endif;

    

 Yii::app()->user->setState('alunosModel',$model);  


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


}




For now seems to be working fine. Any of you experient guys see a problem with this solution?

Thanks in advance…

it works only in simple scenario when you update and return to list. if the editing process is more complicated, or user can dig further (visit other pages) and then return to list - it will not work so nicely… also setting $_GET[‘sort’] in action is not very elegant (but I know there is no other choice to achieve that)…

if all that is OK for you then solution is good :)

ok. thanks for your concern. for now i’ll go with this solution.

This is very effective and simple solution.

The only problem I found is that it affects only table’s fields; how can it be extended to related fields in other tables?