Populate and Filter GridView by column click

Hello. I have a GridView setup with filters at the top of the columns. Some are dropdown and others are input text.

I would like my clients to click on cell data in the GridView and it react similar to them typing into the filter at the top of the column.

Scenario:

User clicks on one of the items in the column location in the GridView. Item name = “town”

1GridView column filter now reads “town”

2GridView updates and is now filtered/showing only data with “town”

I don’t care about the order of 1 and 2 … just that it accomplishes both.

Here is the code I have so far.

admin.php




<?php

$this->breadcrumbs=array(

	'Personnels'=>array('index'),

	'Manage',

);


$this->menu=array(

	array('label'=>'List Personnel', 'url'=>array('index')),

	array('label'=>'Create Personnel', 'url'=>array('create')),

);


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

$('.search-button').click(function(){

	$('.search-form').toggle();

	return false;

});

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

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

		data: $(this).serialize()

	});

	return false;

});

");

?>


<h1>Manage Personnels</h1>


<p>

You may optionally enter a comparison operator (<b>&lt;</b>, <b>&lt;=</b>, <b>&gt;</b>, <b>&gt;=</b>, <b>&lt;&gt;</b>

or <b>=</b>) at the beginning of each of your search values to specify how the comparison should be done.

</p>


<?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(

	'id'=>'personnel-grid',

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

	'filter'=>$model,

	'columns'=>array(

		//'id',

		'first_name',

		'last_name',

		'email',

		array(

			'name' => 'cell_phone',

			'filter' => false,

			'htmlOptions' => array(

				'style' => 'width: 100px; text-align: center;',

			),			

		),

		array(

			'name' => 'age',

			'htmlOptions' => array(

				'style' => 'text-align: center;',

			),			

		),

		array(

			'name' => 'status',

			'filter' => array(

				'0' => 'Single',

				'1' => 'Married',

				'2' => 'Divorced',

			),

			'htmlOptions' => array(

				'style' => 'width: 80px; text-align: center;',

			),

		),

		array(

			'name' => 'location',

			'type' => 'raw',

			//'value' => 'filterLinkHelper($data)',

			'value' => 'filterAJaxHelper($data)',

			'htmlOptions' => array( 

				'style' => 'text-align: center;',

			),

		),

		array(

			'name' => 'creation_date',

			'value' => 'substr($data->creation_date, 0, 10)',

			'htmlOptions' => array( 

				'style' => 'text-align: center;',

			),

		),


		array(

			'class'=>'CButtonColumn',

		),

	),

)); 


function filterLinkHelper($data)

{

	return CHtml::link(

		CHtml::encode($data->location),

		'#',

		array (

			'onClick' => '$(\'input[name="Personnel[location]"]\').attr("value", "'.$data->location.'");

			$.fn.yiiGridView.update("personnel-grid");

			return false;'

		)

	);

};


function filterAJaxHelper($data)

{

	return CHtml::ajaxLink(

		CHtml::encode($data->location),

		array('personnel/admin'),

		array('DONT_KNOW_WHAT_TO_PUT_HERE')

	);

};

?>




I’ve tryed the two different filter helpers but I’m still falling short. I don’t know what to put in filterAJaxHelper array.

Any help would be appreciated.

Thanks Me

Ok how about just a hint. Would this be best accomplished using ajax, or with javascript such as $.fn.yiiGridView.update(‘gridname’), or a combination of both?

hmmm… still wondering.

Perhaps something like this (not tested)




CHtml::activeName($this->grid->filter, 'location')



/Tommy

Thanks Tommy for help.

I’m not sure where that code should go. Would it go in the filterAJaxHelper function?

Yes, that was my idea. The reason would be that the model specified in the filter property of the gridview will contain the filter values posted to the controller. The format returned by CHtml::activeName should be filtermodel[attribute]. (Check the generated source code for the filter field names and use Firebug to examine what’s posted)

(Still not tested)

/Tommy

Finally got it. Hope this helps.




function filterHelper($data, $filter) {

	return CHtml::link(CHtml::encode($data->$filter),

		'#',

		array (

			'onClick' => '$.fn.yiiGridView.update("my-grid",{data:{"My['.$filter.']":"'.$data->$filter.'"}});

			return false;'

		)

	);

};



Then it can be called like this:




'columns'=>array(

	array(

		'id'=>'my_info',

		'name'=>'my_info',

		'type'=>'raw',

		'value'=>'filterHelper($data, "my_info")',

		'htmlOptions'=>array( 

			'style'=>'width: 100px; text-align: center;',

		),

	),

)