Search Form Broken In Admin.php After Using Csqldataprovider

Hi everyone!

I’m having trouble after customizing the CGridView using CSqlDataProvider in admin.php




        public function loadProvider()

	{

		$count = Yii::app()->db->createCommand('SELECT COUNT(*) FROM TABLE')->queryScalar();

		$sql = "SELECT * FROM TABLE";		

		$dataProvider=new CSqlDataProvider($sql, array(

		    'totalItemCount'=>$count,

		    'sort'=>array(

		        'attributes'=>array(

		             'A','B','C',		

		        ),

		    ),

		    'pagination'=>array(

		        'pageSize'=>10,

		    ),

		));


		return $dataProvider;

	}



after assigning this to actionAdmin




        public function actionAdmin()

	{

		$model = $this->loadProvider();

		

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

			'model'=>$model,

		));

	}



CGridView works fine, except once I uncommented the search.


<?php echo CHtml::link('Advanced Search','#',array('class'=>'search-button')); ?>

<div class="search-form" style="display:none">

<?php  $this->renderPartial('_search',array(

	'model'=>$model,

)); ?>

I get the ff error


CSqlDataProvider and its behaviors do not have a method or closure named "getAttributeLabel". 

What should I do to fix it?

I’m assuming that the search view is expecting an instance of CModel (or a subclass such as CActiveRecord), but you’re providing a CSqlDataProvider.

Gii-generated admin page uses $model … it’s not a data provider but an CActiveRecord instance that holds the search parameters. The data provider that CGridView needs is created by search method.

Please take a look at this wiki to understand how the gii-generated admin page works:

http://www.yiiframework.com/wiki/381/cgridview-clistview-and-cactivedataprovider/

If you want the search function to work with CSqlDataProvider, you have to do two things:

  1. Pass an instance of CActiveRecord or CFormModel to the view so that the search form will work.

  2. Collect the input from the search form and construct your SQL according to the search parameters.

I bet you will consider using CActiveDataProvider … generally it’s far easier.

I tried your suggestion, it was able to remove the error, but I still couldn’t get the search to work as I wanted.

I did assign dbcriteria, so I’m not sure why it ain’t working.

Below is my code:

Controller:




        public function actionAdmin()

	{

		$model=new Flowbook('search');

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

		if(isset($_GET['Flowbook']))

		{

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

			$dataprovider = $this->loadProvider($model->getCriteria());

		}

		else 

			$dataprovider = $this->loadProvider();

		

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

			'model'=>$model,

			'dataprovider'=>$dataprovider,

		));

	}


        public function loadProvider($criteria = null)

	{

		$count = Yii::app()->db->createCommand('SELECT COUNT(*) FROM tbl_flowbook')->queryScalar();

		$sql = "SELECT tbl_flowbook.id as id, title, date_received, tbl_lookup.name as category, ".

			"description, keyword, tbl_flowbook.create_time as create_time, ".

			"update_time, username, contributor ". 

			"FROM tbl_flowbook ". 

			"INNER JOIN tbl_lookup ON tbl_flowbook.category = tbl_lookup.code ".

			"INNER JOIN tbl_user ON tbl_flowbook.author_id = tbl_user.id ".

			"WHERE tbl_lookup.type = 'Category'";		

		if (isset($criteria))

		{

			$dataProvider=new CSqlDataProvider($sql, array(

				'criteria'=>$criteria,

			    'totalItemCount'=>$count,

			    'sort'=>array(

			        'attributes'=>array(

			             'id', 'title', 'date_received','category','description',

						 'keyword','create_time','update_time','username','contributor',		

			        ),

			    ),

			    'pagination'=>array(

			        'pageSize'=>10,

			    ),

			));

		}

		else

		{

			$dataProvider=new CSqlDataProvider($sql, array(

			    'totalItemCount'=>$count,

			    'sort'=>array(

			        'attributes'=>array(

			             'id', 'title', 'date_received','category','description',

						 'keyword','create_time','update_time','username','contributor',		

			        ),

			    ),

			    'pagination'=>array(

			        'pageSize'=>10,

			    ),

			));

		}

		


		return $dataProvider;

	}



Model:




        public function getCriteria()

	{

		// Warning: Please modify the following code to remove attributes that

		// should not be searched.


		$criteria=new CDbCriteria;


		$criteria->compare('id',$this->id);

		$criteria->compare('title',$this->title,true);

		$criteria->compare('category',$this->category);

		$criteria->compare('date_received',$this->date_received);

		$criteria->compare('description',$this->description,true);

		$criteria->compare('keyword',$this->keyword,true);

		$criteria->compare('create_time',$this->create_time);

		$criteria->compare('update_time',$this->update_time);

		$criteria->compare('author_id',$this->author_id);

		$criteria->compare('contributor',$this->contributor,true);


		return $criteria;

	}

View




<?php echo CHtml::link('Advanced Search','#',array('class'=>'search-button')); ?>

<div class="search-form" style="display:none">

<?php $this->renderPartial('_search',array(

	'model'=>$model,

)); ?>

</div><!-- search-form -->


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

	'dataProvider'=>$dataprovider,

	'columns'=>array(

		'title',

		array(

			'name' => 'date_received',

			'header' => 'Date Received',

			'type' => 'raw',

			'value' => 'Yii::app()->controller->convertTime($data["date_received"])',

		),		

		'category',

		'description',

		'keyword',

		array(

			'name' => 'create_time',

			'header' => 'Create Time',

			'value' => 'Yii::app()->controller->convertTime($data["create_time"])',

		),

		array(

			'name' => 'update_time',

			'header' => 'Update Time',

			'value' => 'Yii::app()->controller->convertTime($data["update_time"])',

		),		

		'username',			

	),	

)); ?>



CSqlDataProvider has no ‘criteria’ property. It doesn’t receive the criteria you have made.

You have to construct the ‘WHERE’ clause of the SQL by yourself according to the search parameters.

I would use CActiveDataProvider instead of CSqlDataProvider in your case.

Thanks!