CGridView filter dropdown from array

Resolved

Hi! I have table of providers (id, title, onoff) where onoff column is a status: 1 = on, 0 = off I dont have table in DB for these statuses, so I don’t have model for statuses.


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

    'id'=>'provider-grid',

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

    'filter'=>$model,

    'columns'=>array(

        array(

            'name'=>'id',

            'htmlOptions'=>array('width'=>'40px'),

        ),

        'title',

        array(

            'name'=>'onoff',

            'filter'=>CHtml::dropDownList('Provider[onoff]', '',  

                array(

                    ''=>'All',

                    '1'=>'On',

                    '0'=>'Off',

                )

            ),

        ),

        array(

            'class'=>'CButtonColumn',

            'template'=>'{update}{delete}'

        ),

    ),

It filters data, but after ajax forget the state of dropdown What is the best way to build dropdown in this case?

And what is the best way to substitute 1 to On and 0 to Off in datagrid cells?

Well I haven’t tested it but I guess it’s more or less:




        …

        array(

            'name'=>'onoff',

            'value'=>'$data->onoff ? "On" : "Off"', // Notice the double quotes inside the single quotes. I guess it can be the opposite (single into double)

            'filter'=>CHtml::dropDownList('Provider[onoff]', 'onoff',  // you have to declare the selected value

                array(

                    ''=>'All',

                    '1'=>'On',

                    '0'=>'Off',

                )

            ),

        ),

        …



No, it doesn’t work too


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

'id'=>'provider-grid',

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

'filter'=>$model,

'columns'=>array(

    array(

        'name'=>'id',

        'htmlOptions'=>array('width'=>'40px'),

    ),

    'title',

    array(

        'name'=>'onoff',

        'value'=>'Crud::getOnoff($data->onoff)',

        'filter'=>CHtml::listData(Crud::getOnoffs(), 'id', 'title'),,

    ),

    array(

        'class'=>'CButtonColumn',

        'template'=>'{update}{delete}'

    ),

),

In model


public function getOnoffs()

{

return array(

    array('id'=>'1', 'title'=>'On'),

    array('id'=>'0', 'title'=>'Off'),

);

}

public function getOnoff($onoff)

{

if($onoff == 1) 

    return 'On';

else 

    return 'Off';

}

Hello,

I am having the same problem. I tried the solution posted by “gv0zd” but it didn’t work. After every selection in the dropbox, it returns to the “” value (in my case “ALL”).

This is what I tried also but it’s not working either:


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

	'id'=>'contents-grid',

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

	'filter'=>$model,

	'columns'=>array(

		array(

                    'header'=>'Active',

                    'name'=>'active',

                    'value'=>'Contents::model()->getActiveStateName($data->active)',

                    'filter'=>CHtml::dropDownList('Contents[active]','',CHtml::listData(Contents::model()->getActiveStatesArray(), 'value', 'name'),array('options'=>array('$data->active'=>'selected'))),

                    


...

...

...



Everything works fine except for this part:


array('options'=>array('$data->active'=>'selected'))

It seems like the $data->active is not applied in that case.

The end result is: “All” is selected after every dropdown selection. The selection doesn’t stick.

Anyone have any ideas?

Thank you!

Just as gv0zd has posted, you don’t have to set a dropdown list for the filter.

You just have to give the option list array for it.




                    'filter'=>CHtml::listData(Contents::model()->getActiveStatesArray(), 'value', 'name'),



The selection of the dropdown list should be automatically set … doesn’t it?

Hi softark,

I tried gv0zd’s original suggestion and it works fine (you are right) however there’s one small problem I was trying to fix, which took me down the dropDownList road (sorry I did not specify that).

When I use gv0zd’s code above, I get this output:


<select name="Contents[active]">

<option value=""></option>   <<//-- this is the line

<option value="" selected="selected">All</option>

<option value="1">Yes</option>

<option value="0">No</option>

</select>

There’s always that first EMPTY option that I don’t know how to get rid of. I tried removing the “All” option in getActiveStatesArray() but I would like to at least add a “name” for that option.

Any idea how I would do this?

Thank you very much for your reply.

I see. :)

So your Contents::model()->getActiveStatesArray() returns:




array(

    '' => 'All',

    '1' => 'Yes',

    '2' => 'No',

)



And the auto filter will add one more item:




    '' => '',



at the beginning of the array as the ‘empty’ entry meaning “don’t care”.

Now if your Contents::model()->getActiveStatesArray() had only returned ‘Yes’ and ‘No’, and if you could accept empty string for “don’t care”, then there had been nothing problematic.

Well, if you want ‘All’ for “don’t care”, then you have to set a dropdown list for the filter.

Would you please try this:




    'filter'=>CHtml::dropDownList(

        'Contents[active]',

        $model->active,

        CHtml::listData(Contents::model()->getActiveStatesArray(), 'value', 'name')

    ),



Or, with your getActiveStatesArray() returning only ‘Yes’ and ‘No’ …




    'filter'=>CHtml::dropDownList(

        'Contents[active]',

        $model->active,

        CHtml::listData(Contents::model()->getActiveStatesArray(), 'value', 'name'),

        array(

            'empty' => 'All',

        )

    ),



http://www.yiiframework.com/doc/api/1.1/CHtml/#dropDownList-detail

P.S.

I think you can declare your getActiveStatesArray() static and refer it simply by Contens::getActiveStatesArray().

Hi Softark,

I just tried both of your code variants but I get the same bug as before: when choosing "Yes" from the dropdown, the filtering works fine, however the selected item on the dropdown becomes "All" (or the first option) in all cases. This means that I can pick "Yes" or "No" in that field but I cannot select "All" to view all records without refreshing the page.

Here is a very short recording I made of the problem:

http://www.mediafire…qeobgl9cpnckamu

Please take a look when you have time and let me know what else I could try.

Side note: when I made the change the first time, it worked perfectly fine until I refreshed the page and tried on another browser. I immediately thought it might have something to do with caching, so I emptied the "assets" dir. But no luck after that first time.

Thank you very much for your great help and a great community!

Allright, everyone, I figured it out with some more tweaking. This was the line that worked without problems:

/protected/views/content/admin.php


                	'filter'=>CHtml::dropDownList(

                        	'Contents[active]',

                        	$model->active,

                        	CHtml::listData(

                                	Contents::model()->getActiveStatesArray(),

                                	'value',

                                	'name'),

                        	array('options'=>array('$data->active'=>'selected'))),

The only thing that was missing from my previous attempts was the $model->active, which softark informed me about.

Thank you very much for your help. I am very happy with the Yii platform and community, you guys rock!

Glad to hear that. :)

I think the ‘options’ you set for the dropdown is not written correctly.

Fortunately it seems to be causing no problem, either being totally ignored or just producing a garbage html code without meaning.

You can omit it safely. :)

You are absolutely correct about it working without the “options”. However, I don’t see any bad HTML generated with the “options” array in place. This is the output:


<select name="[url=""]Contents[active][/url]" id="[url=""]Contents_active[/url]">

<option value="" selected="[url=""]selected[/url]">All</option>

<option value="[url=""]1[/url]">Yes</option>

<option value="[url=""]0[/url]">No</option>

</select>

Well, in any case, I will remove the "options" array and leave it like that.

Thank you very much for your guidance and help!

Q : How to filter CGridview filter dropdown from controller array

I create an array at my controller

&#036;arr_method = array('Cash'=&gt;'Cash', 'Cheque'=&gt;'Cheque', 'Credit Card'=&gt;'Credit Card', 'Bank Transf'=&gt;'Bank Transf');

I call above array at Cgridview

array('name' =&gt; 'method',


			   'value'=&gt;'(isset(&#036;data-&gt;method)) ? CHtml::encode(&#036;data-&gt;method) :&quot;&quot;',


			   'filter'=&gt;CHtml::dropDownList('method', '', &#036;arr_method),


		),

dropdown list is appear at filter. but when I select something, filter is going back to ‘Cash’. and result is showing blank.




    array('name' => 'method',

    	'value'=>'(isset($data->method)) ? CHtml::encode($data->method) :""',

    	'filter'=>CHtml::activeDropDownList($model, 'method', $arr_method),

    ),



Or,




    array('name' => 'method',

    	'value'=>'(isset($data->method)) ? CHtml::encode($data->method) :""',

    	'filter'=>$arr_method,

    ),



Code for CGridView:

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

‘id’=>‘puzzle-grid’,

‘dataProvider’=>$model->search(),

‘filter’=>$model,

‘columns’=>array(

‘id’,

‘group.name’,

array(

‘name’=>‘group_id’,

‘filter’=>CHtml::listData(PuzzleGroup::model()->findAll(),‘id’,‘name’),

),

‘category.name’,

‘phrase’,

array(

‘name’=>‘enabled’,

‘filter’=>array(‘Yes’=>‘Yes’,‘No’=>‘No’),

),

array(

‘class’=>‘CButtonColumn’,

),

),

));

//‘group.name’,

?>

Relations between the two tables:

public function relations()

{

// NOTE: you may need to adjust the relation name and the related

// class name for the relations automatically generated below.

return array(

‘tbHints’ => array(self::HAS_MANY, ‘TbHints’, ‘puzzle_id’),

‘group’ => array(self::BELONGS_TO, ‘PuzzleGroup’, ‘group_id’),

‘category’ => array(self::BELONGS_TO, ‘PuzzleCategory’, ‘category_id’),

);

}

Code for search function:

public function search()

{

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

// should not be searched.

$criteria=new CDbCriteria;

$criteria->compare(‘id’,$this->id);

$criteria->compare(‘group_id’,$this->group_id);

$criteria->compare(‘category_id’,$this->category_id);

$criteria->compare(‘phrase’,$this->phrase,true);

$criteria->compare(‘enabled’,$this->enabled,true);

return new CActiveDataProvider($this, array(

‘criteria’=>$criteria,

));

}

For the above code can anyone please let me know how to create CGridView for Puzzle with dropdownlist filters containind puzzlegroup name from PuzzleGroup which is related to Puzzle with group_id.

Also i want to display PuzzleGroup name instead of id in the CGridView.

Hi,

I think your code should work … doesn’t it?

About displaying the name instead of the id, you could do it like this:




array(

    'name'=>'group_id',

    'filter'=>CHtml::listData(PuzzleGroup::model()->findAll(),'id','name'),

    'value'=>'$data->group->name',

),



just


'filter'=>array('1'=>'On','0'=>'Off'),

is enough.

Thanks,

Great Solutoin.

LOL simple way like that !