GridView Questions

Dear All ,

I have few questions on Gridview , Could some one please throw some light on them ?

  1. In my model I have two fields Firstname and lastname , I want to show them together in one column field (some thing similar to ‘firstname lastname’) and also a filter field on this combined view field

  2. If the above case is not possible to implement , Can I write a DAO layer to provider my own implementation to this view ? But I see the data provider it is taking is CMODEL… Any ideas how to implement this and customize in our own way ?

  3. Filter field , I have to enter the text and press enter for it filter the data . Is there any way I can add event that triggers for keydown and filters … I mean automatically filtering for every character ( May be starting filter after entering 3 or 4 characters )

Thanks a lot for your help

Regards

Fan Of Yii ( Recent Fan )

You can do it by introducing an extra attribute to your model.

I would do it like this:

  1. Add some public attribute to the model.



class Customer extends CActiveRecord

{

	public $customername; // for firstname + lastname;

	....



  1. Declare it safe on search.



	public function rules()

	{

		return array(

			....

			array('id, firstname, lastname, ...., customername', 'safe', 'on'=>'search'),

		);

	}




  1. Set the label for it.



	public function attributeLabels()

	{

		return array(

			'id' => 'ID',

			'firstname' => 'First Name',

			'lastname' => 'Last Name',

			....

			'customername' => 'Customer Name',

		);

	}



  1. Add a search condition for it in "search()" method.



	public function search()

	{

		$criteria=new CDbCriteria;


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

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

		$criteria->compare('lastname',$this->lasttname);

		....

		if ( $this->customername != "" )

		{

			$crit2 = new CDbCriteria;

			$crit2->compare('firstname', $this->customername , true, 'OR');

			$crit2->compare('lastname', $this->customername , true, 'OR');

			$criteria->mergeWith($crit2);

		}

		....



  1. Add the sorting rule for it, also in the "search()" method.



		....

		return new CActiveDataProvider(get_class($this), array(

			'criteria' => $criteria,

			'sort' => array(

			 	'defaultOrder' => 'lastname, firstname',

				'attributes' => array(

					'customername' => array(

						'asc' => 'lastname, firstname',

						'desc' => 'lastname DESC, firstname DESC',

					),

					'*',

				),

			),

			'pagination' => array(

				'pageSize' => 20,

			),

		));



  1. And use the attribute in the grid.



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

	'id' => 'customer-grid',

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

	'filter' => $model,

	'columns' => array(

		....

		array(

			'name' => 'customername',

			'value' => '$data->firstname . " " . $data->lastname',

		),

		....



You might want some modification to satisfy your needs.

I used a public variable for the new attribute, but you can adopt the getter/setter approach as illustrated in this article: http://www.mrsoundless.com/post/2011/05/09/Searching-and-sorting-a-column-from-a-related-table-in-a-CGridView.aspx

[EDIT] fixed a bug in step 6.

Thanks a lot for this wonderful solution :rolleyes:

It worked like champ…

Only one small note in the 6th step … some how how on Value if I use

‘value’ => ‘$data->firstname’ . ’ ’ . ‘$data->lastname’, throwing the below error ,

but instead if I use

‘value’ => ‘CHtml::encode($data->firstname ." ".$data->lastname )’ ,

It is working fine

[b]Error

Parse error: syntax error, unexpected T_VARIABLE in C:\wamp\www\framework\framework\base\CComponent.php(619) : eval()'d code on line 1[/b]

Once again Thanks for this wonderful solution . Can be on Wiki…?

Regards

Yii Fan

Ah! sorry. Your right. It’s my mistake.

Corrected the error in the original reply. :P

As for the 3rd question, I’ve tried a little but got no successful result.

But when you use an independent search form outside of the grid, e.g. the folded "advanced" search form in the gii-generated admin page, you might want to try the following:




Yii::app()->clientScript->registerScript('ajax-search', "

$('form').submit(function(){

	$.fn.yiiGridView.update('customer-grid', {

		data: $(this).serialize()

	});

	return false;

});

var delay = (function(){

	var timer = 0;

	return function(callback, ms){

		clearTimeout(timer);

		timer = setTimeout(callback, ms);

	};

})();

$('#Customer_customername').keyup(function(){

	delay(function(){

		$('form').submit();

	}, 1000);

	return false;

});

");



#Customer_customername stands for the input field in the search form.

This will fire an ajax search as you type the search words with a delay of 1000 ms.

It’s very comfortable. :)

I’m quite satisfied with this trick and am using it in my pages with CGridView, where I have modified the folded “advanced” search form to be displayed all the time.

Nice trick softark :) . Before using Yii I wrote my own code for this and It is working pretty fast and good . But since lack of CSS skills , I couldn’t make it looking good :( I can share with you what I have . If it is fine for you I can upload it to rapidshare or somewhere and share you the code I have . It basically uses jquery.jqGrid.min.js .

Thank You again

Regards

Yii Fan

Thank you. But I have no experience with jquery.jqGrid. :( And could it be used with CGridView? I’m afraid not … So I think I will not be able to make use of your interesting code. I’m quite satisfied with Yii and CGridView, and have no mind right now to go the other way.

I’d rather request you to look into jquery.yiigridview.js to solve your 3rd question and show me how to do it. :P