[EXTENSION] clear-filters-gridview

The EButtonColumnWithClearFilters extension adds up some functionality to the default possibilites of CButtonColumn implementation when you use extensions to Remember Filter Values. This extension helps you to clear those remembered filter values.

An image will be placed in the top column(on same line of AJAX filters). When clicked the filters will be cleared, the content will be refreshed with all items available.

Image

http://www.yiiframew…&attach_id=1216

Requirements

  • Yii 1.1

Download

Donate

Click here to donate

Resources

Clear-filters-gridview extension

Report a bug

Usage

Step 1

To use this extension, copy this file to your components/ directory, add ‘import’ => ‘application.components.EButtonColumnWithClearFilters’, […] to your config/main.php and use this column on each widget’s Column array you would like to inherit the new possibilities:


array(

  'class'=>'EButtonColumnWithClearFilters',

   //'clearVisible'=>true,

   //'onClick_BeforeClear'=>'alert('this js fragment executes before clear');',

   //'onClick_AfterClear'=>'alert('this js fragment executes after clear');',

   //'clearHtmlOptions'=>array('class'=>'custom-clear'),

   //'imageUrl'=>'/path/to/custom/image/delete.png',

   //'url'=>'Yii::app()->controller->createUrl(Yii::app()->controller->action->ID,array("clearFilters"=>1))',

   //'label'=>'My Custom Label',

 ),

All posible customizations have been enumerated above, you shall comment out those that you won’t override. The minial setup is just the class type for the Columns.

clearVisible: a PHP expression for determining whether the button is visible

onClick_BeforeClear: If you want to execute certain JS code before the filters are cleared out, use this property to pass your custom code. You are allowed to use ‘return false;’ only, when you want to stop the clear to happen. This will stop all further JS code, and HTTP request to be executed. You are not allowed to use ‘return true;’ it will break the components usage.

onClick_AfterClear: If you want to execute certain JS code after clear, but before the AJAX call use this property to pass your custom code. You are allowed to use ‘return false’ only, when you want to stop the AJAX call to happen. This will stop the form to be reloaded. If you want to clear the form by classic GET request, and not by ajax you shall ‘return true;’ here.

clearHtmlOptions: Associative array of html elements to be passed for the button

Default is: array(‘class’=>‘clear’,‘id’=>‘cbcwr_clear’,‘style’=>‘text-align:center;display:block;’);

imageUrl: image URL of the button. If not set or false, a text link is used

Default is: $this->grid->baseScriptUrl.’/delete.png’

url: a PHP expression for generating the URL of the button

Default is: ‘Yii::app()->controller->createUrl(Yii::app()->controller->action->ID,array(“clearFilters”=>1))’

label: Label tag to be used on the button when no URL is given

Default is: Clear Filters

Step 2

You need to add to your controller the following code.


if (intval(Yii::app()->request->getParam('clearFilters'))==1) {

    EButtonColumnWithClearFilters::clearFilters($controller,$model);

}

If you don’t need the clear filters button capabilities you can also pass a clearFilters parameter with a 1(one) value to the controller, for this you can use a link or a button.

This extension has also a pair Remember-filters-gridview

1216

clear_filters_10.png

This is a very useful enhancement, and one that I believe should be in Yii core. jeremy’s added code in the first post was, in my opinion, a nice addition as well. I took his idea a little further and made the ability to show/hide the clear filters button into a boolean property that can be passed in as an option. I named the option $autoHideClearFilter and defaulted it to true, as I like the auto-hide functionality. The default could be set to false so that stock functionality would remain unchanged. I’ve attached my enhancement, and set the version to 1.01. I also added the documentation in the appropriate areas.

Thanks again for these nice enhancements!

Sorry, I forgot to actually add the attachment (and didn’t see an edit post link – I’m new!).

1287

EButtonColumnWithClearFilters.php

…continuing the topic started in the Extension comment:

I have both EButtonColumnWithClearFilters and ERememberFiltersBehavior in my project. All of my models inherit from my class DRActiveRecord, which extends CActiveRecord. ERememberFiltersBehavior is installed as a behavior in DRActiveRecord, so all my models get it. EButtonColumnWithClearFilters is used all in my views/XXX/admin.php

I’ve made a few minor changes to EButtonColumn. Mainly, I show the “Clear Filters” link if and only if any filters are set. I keep track of whether any filters are set in ERememberFilterBehavior.saveSearchValues() by setting another state; then clearing it in .unsetFilters() method.

Originally I had also modified EButtonColumn javascript function to fire on .last() instead of .first(). This is because I also have a number-of-records drop-down selector in the top cell of the filter column. The original code fired on .first() so it was invoked by mistake every time the user changed the number-of-records, since that was the first element. So I made it fire on .last() which worked just as well.

BTW, my project requires javascript; if javascript is disabled then the user sees a page "Javascript is required".

If the user enters something in a filter field of gridview, then tabs out, of course the grid reloads and the records are filtered. Then the “Clear Filters” link appears (I don’t use the icon).

When they click the "Clear Filters" link, the javascript function rendered in EButtonColumn.init(), which is attached to the "clear filters" link, is invoked. This function (1) clears all the filter fields; (2) triggers "change" so the grid reloads.

==> When "change" is triggered, the grid is submitted without the "clearFilters=1" parameter ! Therefor the XXController.actionAdmin() never sees any GET parameter "clearFilters", and it never calls EButtonColumnWithClearFilters.clearFilters().

The result is the grid itself refreshes with all the records, since the filters present in the grid have been cleared.

==> But the user->states which were set previously by ERememberFilters.saveSearchValues() are never cleared.

Consider this sequence of events:

  1. user arrives at an Admin page

  2. user sets a filter. user->state is set behind the scenes to remember filter selection.

  3. grid refreshes, and filtered records are displayed

  4. user clicks "clear filters". grid filters are cleared, and "change" action is triggered to refresh grid. Grid is refreshed

=> but user->states are not cleared, per above explanation

  1. user navigates to another page

  2. user navigates back to the original Admin view

** 7. the original filters are STILL THERE even though they were previously cleared. Because user->state was never cleared.

As I wrote in the Extension comment, I solved the problem by removing the javascript function in EButtonColumn.init(). Now, pressing "clear Filters" causes a GET with parameter clearFilter=1; the actionAdmin() calls ERememberFilters.clearFilters(); then actionAdmin() is called again and the form refreshes. But the user->states have been cleared, so the problem described in point (7) does not occur.

Sorry for the long explanation. Hope this helps.

Step 7 is cleared in ERememberFiltersBehavior.saveSearchValues, actually this is not a clear. It is a state rewrite with an empty value as at that time the attributes should contain empty values.




private function saveSearchValues() {


        $modelName = get_class($this->owner);

        $attributes = $this->owner->getSafeAttributeNames();

        foreach ($attributes as $attribute) {

            if (isset($this->owner->$attribute)) {

                Yii::app()->user->setState($modelName . $attribute, $this->owner->$attribute);

            }

        }

    }

I am wondering if you have removed

[color=“black”][size=“2”]if[/size][/color][color=“olive”]size=“2”[/size][/color]

 [color="blue"][size="2"]$model[/size][/color][color="gray"][size="2"]->[/size][/color][color="green"][size="2"]attributes[/size][/color][color="gray"][size="2"]=[/size][/color][color="blue"][size="2"]$_GET[/size][/color][color="olive"][size="2"][[/size][/color][color="red"][size="2"]'[/size][/color][color="red"][size="2"]Company[/size][/color][color="red"][size="2"]'[/size][/color][color="olive"][size="2"]][/size][/color][color="gray"][size="2"];[/size][/color]

[color="#808080"][color="#000000"][font="arial, verdana, tahoma, sans-serif"]

[/font][/color][/color]

[color="gray"] [/color][color="#808080"][color="#000000"][font="arial, verdana, tahoma, sans-serif"]example code from your actionAdmin(). [/font][/color][/color][color="#808080"][color="#000000"][font="arial, verdana, tahoma, sans-serif"]

[/font][/color][/color][color="#808080"][color="#000000"][font="arial, verdana, tahoma, sans-serif"]You should not have any $model->attributes assignment in your controller method or elsewhere in processing. [/font][/color][color="#000000"][font="arial, verdana, tahoma, sans-serif"]Do you?[/font][/color][/color][color="#808080"][color="#000000"][font="arial, verdana, tahoma, sans-serif"]

[/font][/color][/color]

If this doesn’t help, please post your

actionAdmin()

behaviors definition

and zii.widgets.grid.CGridView setup code fragments.

to investigate further, as I am not able to reconstruct your problem.

[quote=“Pentium10, post:5, topic:33656”]

Step 7 is cleared in ERememberFiltersBehavior.saveSearchValues, actually this is not a clear. It is a state rewrite with an empty value as at that time the attributes should contain empty values.




private function saveSearchValues() {


...

            if (isset($this->owner->$attribute)) {

...



Thanks for the explanation. I see how it is supposed to work.

Now I see what happens. If it’s a normal text field, the state is overwritten by the above line. BUT if the filter is rendered as a drop-down list, then isset() on this field is FALSE after the filter is cleared, and the state is never cleared.

Debugging and inspecting objects (using NetBeans/xdebug), inside ERememberFiltersBehavior.saveSearchValues() : during a "clear" operation the drop-down fields are not present in $this->_owner->_attributes; whereas they are present when the user selects a value from the drop-down list.

Inspecting the GET in Firebug, the grid is sending all the fields when user adds a filter; but is only sending the text fields when "clear filters" is pressed. See attached screenshot. Notice that Translations[ModelClass] is present in the 1st GET (set filter); but not present in the 2nd GET (clear filters). The other 2 drop-down fields are not present in either GET because they are not populated in either case.

  • Jeremy

(p.s. please ignore ugly colors in the layout; the French text, etc. this is due to dev environment & debugging)

Hi!

Question: How to clear the search form fields also?

TIA!

Since that form can be customized highly by the developer, it cannot be done automatically by the extension, but you can make use of the onClick_AfterClear event.

Something like this would do it:




array(

            'class' => 'EButtonColumnWithClearFilters',

	    'onClick_AfterClear'=>'$(\'#yw0 :input\').clearFields();', // where #yw0 is the ID of the form

        ),

Hi,

I have installed extensions clear filters gridview for the gridview in a view page. I have Unit and UnitClass. Unit is the master and UnitClass is its detail.

In unit/view.php, I put CGridView of the UnitClass. I put the link like this,




<li><?php echo CHtml::link('Refresh', array('/unitClass/view', 'id' => $model->id, 'clearFilters' => 1)); ?></li>



But always, get error… It seems I lost my id parameter, any help?

Cheers,

Daniel

When I run your code, I get valid output, but the ID is part of the route, and not as a parameter. You have a route setup for that ID.

What do you mean by you lost ID? You probably want your action method to have ID as a parameter and it will work for you actionView($id) .

Thanks for the extension.

When I use it with other extension ‘SelGridView’, which uses a hidden CCheckBoxColumn (or something alike), the selector below used in cbcwr_clearFields() incorrectly selects the first checkbox of the checkbox column instead of the first input in the filters:




{$_beforeAjax} $('#{$this->grid->id} :input').first().trigger('change');



and thus the gridview is not updated. It may be better to add ‘.filter’ in the selctor as follow:




{$_beforeAjax} $('#{$this->grid->id} [color="#FF0000"].filters[/color] :input').first().trigger('change');



This is a great extension. I have it working successfully on all of my crgridviews.

However when I click the clear filters button, all the values are removed from the filter fields. If I refresh the page anywhere I have a select as a filter option, the value is inserted back into the select.

For some reason the search value is not cleared out of the session for filters where I am using a select.

I am doing a print_r($_SESSION) and can see that the variable is not cleared for the select.

Any ideas?

Do you have this piece of code in your aciton()?

[color=black]if[/color] color=olive[/color] [color=olive]{[/color] [color=green]EButtonColumnWithClearFilters[/color]::[color=green]clearFilters[/color]color=olive[/color];//where $this is the controller [color=olive]}[/color]

Thanks for the reply.

Yes,just checked and this line of code is in all of my controllers that are using this extension:

if (intval(Yii::app()->request->getParam(‘clearFilters’))==1) {

		EButtonColumnWithClearFilters::clearFilters(&#036;this,&#036;model);//where &#036;this is the controller


	}

Any ideas why it would clear the value in session for text fields, but not clear the value in session for select?

It might be that you are using a custom session component, or some different PHP setting.

With the stock components this works.

Pentium10, thanks for the reply and a I greatly appreciate your help. I just did a blank install of yii and ran a test again and got the same results. The dropdown filter would not clear out of session.

Here is the drop filter I am using in the cgridview:


array(

'name'=>'type_id',

'filter'=>CHtml::listData(LinesWlnType::model()->findAll(array('order'=>'id')),'id','type'),

),



And here is the html that is created on the page:

[html]<select name="LinesWln[type_id]">

<option value=""></option>

<option value="7" selected="selected">B1</option>

<option value="8">Cable</option>

<option value="9">Centrex</option>

<option value="10">Dry Loop</option>

<option value="11">DID</option>

<option value="12">Fiber</option>

<option value="13">Frame</option>

<option value="14">ISDN</option>

<option value="15">KT</option>

<option value="16">MPLS</option>

<option value="17">P2P</option>

<option value="18">PBX</option>

<option value="19">PRI</option>

<option value="20">Res</option>

<option value="21">RCF</option>

<option value="22">SIP</option>

<option value="23">T1</option>

<option value="24">Toll Free</option>

<option value="25">VOIP</option>

<option value="26">Wireless Device</option>

<option value="27">Satellite</option>

<option value="28">Private</option>

</select>[/html]

Any help would be greatly appreciated.

Thanks again, Brandon.

Any ideas? I can look in session and see that it is not clearing the value for any search field that is a dropdown list.

Would you be able to attach your sample project so I should debug on it?

I don’t know if it’s a valid way of doing things, but I also had the same problem as btilley with select lists not being cleared in the session.

I just changed one value in the $.fn.clearFields = $.fn.clearInputs = function() {;

else if (tag == ‘select’) {

this.selectedIndex = 0;//instead of -1

}

and this solved it for me. :)