CGridView + Ajax Pagination + CActiveDataProvider issue with criteria

Hello,

I have a form that a user fills out to conduct a search, upon post, they are sent to a results page. Everything worked fine until I tried paging.

It would break because I was generating the Criteria object dynamically in the controller. I am doing this because the form doesn’t have easy filters, I have to check many things, for example:




	public static function createCriteria($formData){

	    $fields = array();

	    

	    foreach($formData['Model'] as $k=>$v){

	        if( $v != '')

	            $fields[$k] = $v;

	    }

	    

	    $criteria=new CDbCriteria;

	    foreach($fields as $k=>$v){

	        if(!self::isRangeField($k)){

	            $criteria->compare($k, $v);

	        }else{

	            if(stristr($k, '_from')){

	                $field = str_replace('_from', '', $k);

	                if(self::isDateField($field)){

	                    $criteria->addBetweenCondition($field, date('c', strtotime($v)), date('c', strtotime($fields[$field.'_to'])));

	                }else{

	                    $criteria->addBetweenCondition($field, $v, $fields[$field.'_to']);

	                }    

	            }

	            

	        }

	    }

	    

	    return $criteria;

	}



The only solution I could come up with was saving the criteria object in the php session.

I was wondering if there was a cleaner way to pass/maintain this criteria with the ajax call and the controller.

I’d prefer setting public properties rather than setting a session variable.

Code is provided below, thanks in advance!

The view has:




if(isset($_SESSION['criteria'])){

$dataProvider=new CActiveDataProvider('EbayListing', array(

    'criteria'=>$_SESSION['criteria'], //hack to get ajax pagination to work

    'pagination'=>array(

        'pageSize'=>10,

    ),

));


$this->widget('zii.widgets.grid.CGridView', array(

    'dataProvider'=>$dataProvider,

	'columns'=>array(

...



The controller has:




  public function actionSearchResults()

  {

    $model = new Model;

    if(isset($_REQUEST['Model']))

    {

      $model->attributes=$_REQUEST['Model'];

      

      if($model->validate())

      {

        $formData = $_REQUEST;

        $criteria = Model::createCriteria($formData);

        $_SESSION['criteria'] = $criteria; //hack to get ajax pagination to work

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

      }

      else

      {

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

      }

      

    }

    else if(!Yii::app()->request->isAjaxRequest)

    {

      $this->redirect('searchlistings');

    }else{

        //doing ajax

        $this->render('search_results');

    }

  }



I would also do so.

Introducing some properties for search parameters in the model class would make things much simpler and easier.

Each link button of a CGridView pager will pass all those search parameters of the current page if they are the properties of the current model. And the rest of the ajax pagination job is done by Yii. There should be not much to do by yourself. (This is just how the things are in an ‘admin’ CRUD page right after the Gii has created it. I think you can pull out and modify the ‘detaild search’ form to suit your needs.)