PDA

View Full Version : Grid Filter (Plugin)



Pages : 1 2 [3] 4

hendricd
24 Jun 2008, 10:18 AM
I haven't seen one either. :-|

businessman332211
24 Jun 2008, 10:25 AM
Well this is going to be a challenge. I will do what I can and post the results back here to help other people (or to get help if I get stuck) or both...
I really have an idae.
I am guessing
store.filterBy();
I am guessing I just need to figure out how to grab those filters locally. That's the part I am confused about.
store.filterBy(filter.filter);
Confusing.
I will play with it and see what I can come up with.

hendricd
24 Jun 2008, 10:28 AM
That's the part I am confused about.
store.filterBy(filter.filter);

That, as I said before, is the GridFilter class's job when local == true. You shouldn't have to mess with that.

businessman332211
24 Jun 2008, 10:35 AM
I am completely confused. If that is true then basically ALL I have to do is set
filters.local = true;
That should be ALL I have to do?
I thought you meant I had to write up coding for the
store.filterBy to make it filter when it's set to local?
I am completely confused now.

So is it:
A:I set filters.local = true and the filtering is done without me doing ANYTHING else
Or
B: I set filters.local = true but then I have to modify the store.filterBy function and call it in order to filter?
Can you explain that real quick whether it's A or B. Because if its A then it should be already working with the code I displayed above?

hendricd
24 Jun 2008, 10:36 AM
A.

Your last script post should work as is. But, it don't, does it?

businessman332211
24 Jun 2008, 10:38 AM
Ok. Then I know something is wrong. No it's not working. As Local = false it wasn't sending the parameters and as Local = true it isn't automatically doing the filtering. Something is wrong here. Let me use firebug real quick and do some break points and do some analyzation and see if I can hunt down why it's acting up.

businessman332211
24 Jun 2008, 10:42 AM
I did just discover one thing. When I set up


var filters = new Ext.ux.grid.GridFilters({
filters:[
{type: 'numeric', dataIndex: 'u_id'},
{type: 'string', dataIndex: 'login_name', value: 'Adam'},
{type: 'string', dataIndex: 'first_name'},
{type: 'string', dataIndex: 'last_name'},
{type: 'string', dataIndex: 'group'},
{type: 'string', dataIndex: 'subarea'},
{type: 'string', dataIndex: 'city'}
]});
filters.local = true;

It actually set's the filter automatically to "Adam" and the right filter. It's checked and has that in the text field in the menu and everything. So it is reading what is being set but it's just not performing the actual "Filtering" for some reason.

businessman332211
24 Jun 2008, 10:49 AM
I did uncover one thing. Some strange error inside of firebug but I have NO idea where it came from.



Permission denied to get property XULElement.accessKey
XPCSafeJSObjectWrapper.cpp
Line 445

Does this have something to do with what my problem is?

hendricd
24 Jun 2008, 10:53 AM
try it on IE then.

FF3 and Firebug 1.2b****3 cause all sorts of trouble.

businessman332211
24 Jun 2008, 10:54 AM
I am. I have been testing it in both browsers at the same time (when I check one I check the other) for the past 7 days. That bug was something else. I am still digging into the code to see if I can find out what is preventing it from working. It's kind of strange. Everything "Seems" to be in place. I don't really see anything wrong with it at this point. I am trying a few other things to see if I can make it work.

businessman332211
24 Jun 2008, 11:17 AM
...It works now.. I somehow...had the wrong code.
I have the right version of the code now. It's strange I downloaded it on the front page jut 7 days ago and when I started wondering why it wasn't working I started looking for the Local variable and saw it nowhere. Then I started wondering....so just for a sanity check I downloaded the files again and saw the version at the top and the local variable and then noticed that...the coding I had in my system wasn't that same version. I overwrited all I had with the new version and it worked just fine.
:((:((:((

7 days of my life wasted because I used the wrong code...

businessman332211
24 Jun 2008, 11:40 AM
Just some advice to Ambience. I advise you to go ahead and your doing really good with the release history and showing the code. But above the main code file there is source. Yuo might want to consider packaging that example with the most current code as well. That's the code I downloaded because I thought I needed the code + example. But they are both the same download. I would get rid of that one, it threw me off. Either way tanks for all of the advice here.

businessman332211
24 Jun 2008, 12:26 PM
Since I have done nothing but take from the EXTjs community thus far I thought it might be time I give something back. My life runs on give/take principle. I took code from you to utilize. I took help that you offered and eventually got rewarded by a fully functional system. I always write up a personal notes database so I never forget what I have learnt. I learnt a lot and already wrote it up so I am going to paste it here and share it with the community so they can learn from the mistakes I have made. I will just put it below inside of quote tags for all to see down the road when they run through this post and hopefully any questions they might have it'll explain what I am able to explain here.




Overview


EXTJS is a Javascript framework that is used for multiple purposes. It comes with multiple widgets to get multiple things done.



Core Code


The core code can always be found here in it's most recent release.
Getting Started: http://extjs.com/learn/ (http://extjs.com/learn/)

Samples:

http://extjs.com/deploy/examples/samples.html (http://extjs.com/deploy/examples/samples.html)

API Docs:


http://extjs.com/depoy/docs/ (http://extjs.com/depoy/docs/)

Forums:


http://extjs.com/forum/ (http://extjs.com/forum/)


Just in case the site is discontinued I have attached it's latest release under "Attachments" and will try to keep it somewhat up to date.
Also extjs can be used stand alone and it also has adaptors for various other basic frameworks and extends onto them. For prototype and some others.
All of the necessary adapters have been attached and are included in the package. I will try to update that attachment from time to time when they come out with new versions. I just want a backup here incase it eventually goes down or something. or If I need it in a quick hurry and don't have internet access or whatever else.


Basically the core code can do a lot...but I only have done 1 thing with it and I only intend to go into detail as I learn new stuff. Right now I have done a basic grid with it.



Basic Grid - Using the core code


The core code has grid functionality and it's very simple. Sample Code




// create the Data Store
Ext.onReady(function(){
var store = new Ext.data.Store({
// load using an HttpProxy
proxy: new Ext.data.HttpProxy({
url: '{{$html->url('/admin/users/getusers')}}'
}),


// create reader that reads the records
reader: new Ext.data.JsonReader({
root: 'rows',
fields: [
{name: 'u_id'},
{name: 'login_name'},
{name: 'first_name'},
{name: 'last_name'},
{name: 'group'},
{name: 'subarea'},
{name: 'report_to'},
{name: 'city'}
]
}),
// turn on remote sorting
sortInfo: {field: 'login_name', direction: 'ASC'},
remoteSort: true
});
// create the Grid
var column_model = new Ext.grid.ColumnModel ([
{id: 'u_id', header: "User ID", width: 100, sortable: true, dataIndex: 'u_id'},
{id: 'login_name', header: "Login Name", width: 150, sortable: true, dataIndex: 'login_name'},
{id: 'first_name', header: "First Name", width: 150, sortable: true, dataIndex: 'first_name'},
{id: 'last_name', header: "Last Name", width: 150, sortable: true, dataIndex: 'last_name'},
{id: 'group_name', header: "Group", width: 150, sortable: true, dataIndex: 'group'},
{id: 'subarea', header: "Subarea", width: 150, sortable: true, dataIndex: 'subarea'},
{id: 'report_to', header: "Report To", width: 150, sortable: true, dataIndex: 'report_to'},
{id: 'city', header: "City", width: 150, sortable: true, dataIndex: 'city'}
]);
var grid = new Ext.grid.GridPanel({
el: 'audit-data-grid',
autoFitColumns: true,
loadmask: true,
store: store,
cm: column_model,
plugins: filters,
stripeRows: true,
height:350,
width:1100,
title:'Users Data'
});
grid.render();
store.load();
});
</script>
<link rel="stylesheet" type="text/css" href="/css/extcss/auditgrids.css" />
<!-- Common Styles for the examples -->


<div id="audit-data-grid"></div>
<br>


ALL you need are 3 elements. The store model, the column model, and the grid model. The store model contains the code that decides WHERE to get the data from. The data need's to be returned in a simple array format encoded in JSON. Basically just form PHP into a simple array (1 level deep at the most) and then encode that using JSON. Then just pass in the data here in this code and the built in JSON decoder will take care of there rest. There are tons of classes out there in PHP that will handle encoding in JSON so it's not very hard to do. Just ECHO out the JSON code and the javascript functionality will take over from there.
THen you have the fields setup which are the fields it's going to create using the data that is returned. Your column model outlines what teh columns id's and names are going to be and sets up the CSS for them. THen the Grid model is what brings them all together and performs loading up the actual grid functionality. At the very end the grid.render shows the grid styleing and the store.load loads all of the store information into the grid (that was created earlier). The EL parameter you see under var grid is the name of whatever div will be holding that grid information. At the very bottom of the page you see where our empty div is setup to allow us to show it. The CSS for the grid needs' to be in place about it and it's shown there but just as a simple example.


That's pretty much all that is required to get a fully functional grid up and running with no special features.


Filtering


There are multiple ways to handle filtering in this situation as well as multiple plugins you can get for it. I don't have a lot of experience with the various types as I have only used one so only one is what I will list here.
Basically you just attach the files needed for it to function and then you pass in some extra data to what we already have and the class will handle there rest and there is really nothing else to it (make sure you have the right version of the code).
I have attached the version to my personal files so I am sure I never lose it. That will make sure I have it here in case.




<script type="text/javascript">
// create the Data Store
Ext.onReady(function(){
Ext.ux.grid.filter.StringFilter.prototype.icon = 'img/find.png';
var store = new Ext.data.Store({
// load using an HttpProxy
proxy: new Ext.data.HttpProxy({
url: '{{$html->url('/admin/users/getusers')}}'
}),


// create reader that reads the records
reader: new Ext.data.JsonReader({
root: 'rows',
fields: [
{name: 'u_id'},
{name: 'login_name'},
{name: 'first_name'},
{name: 'last_name'},
{name: 'group'},
{name: 'subarea'},
{name: 'report_to'},
{name: 'city'}
]
}),
// turn on remote sorting
sortInfo: {field: 'login_name', direction: 'ASC'},
remoteSort: true
});
var filters = new Ext.ux.grid.GridFilters({
filters:[
{type: 'numeric', dataIndex: 'u_id'},
{type: 'string', dataIndex: 'login_name'},
{type: 'string', dataIndex: 'first_name'},
{type: 'string', dataIndex: 'last_name'},
{type: 'string', dataIndex: 'group'},
{type: 'string', dataIndex: 'subarea'},
{type: 'string', dataIndex: 'city'}
]});
filters.local = true;
filters.autoReload = true;
// create the Grid
var column_model = new Ext.grid.ColumnModel ([
{id: 'u_id', header: "User ID", width: 100, sortable: true, dataIndex: 'u_id'},
{id: 'login_name', header: "Login Name", width: 150, sortable: true, dataIndex: 'login_name'},
{id: 'first_name', header: "First Name", width: 150, sortable: true, dataIndex: 'first_name'},
{id: 'last_name', header: "Last Name", width: 150, sortable: true, dataIndex: 'last_name'},
{id: 'group_name', header: "Group", width: 150, sortable: true, dataIndex: 'group'},
{id: 'subarea', header: "Subarea", width: 150, sortable: true, dataIndex: 'subarea'},
{id: 'report_to', header: "Report To", width: 150, sortable: true, dataIndex: 'report_to'},
{id: 'city', header: "City", width: 150, sortable: true, dataIndex: 'city'}
]);
var grid = new Ext.grid.GridPanel({
el: 'audit-data-grid',
autoFitColumns: true,
loadmask: true,
store: store,
cm: column_model,
plugins: filters,
stripeRows: true,
height:350,
width:1100,
title:'Users Data'
});
grid.render();
store.load();
});
</script>
<link rel="stylesheet" type="text/css" href="/css/extcss/auditgrids.css" />
<!-- Common Styles for the examples -->


<div id="audit-data-grid"></div>
<br>


As you can see above the code is there. Same code as before but we just added a few lines. This is very simple implementation. T he filters.local = true sets it to where the thing will filter locally and all of that is handled automatically. This is a fully functioning filter system here. Just make sure the correct files are attached and everything else should take care of itself.

businessman332211
25 Jun 2008, 7:33 AM
This is kind of disturbing..any advice?
For my filter lists I need to be able to dynamically generate them. I need a filter that has a list of items out of the database.
Its not working..and it should.
PHP Code
In PHP I take an array and flatten it down then chain them into a string... So the end format that get's passed to the view is
'test1', 'test2', 'test3', 'test4', 'test5', 'test6'
That is the actual "String" passed into a variable. In javascript I grab it then put it into the list section.
Then it does something dumb and tries to make the filter one long list of all of the items..instead of individual list items (which it should)...

JS Code
That doesn't work for some reason...


var subareastring = "{{$subareastring}}";
var filters = new Ext.ux.grid.GridFilters({
filters:[
{type: 'numeric', dataIndex: 'u_id'},
{type: 'string', dataIndex: 'login_name'},
{type: 'string', dataIndex: 'first_name'},
{type: 'string', dataIndex: 'last_name'},
{type: 'string', dataIndex: 'group'},
{
type: 'list',
dataIndex: 'subarea',
options: [subareastring]
},
{type: 'string', dataIndex: 'report_to'},
{type: 'string', dataIndex: 'city'}
]});

businessman332211
25 Jun 2008, 9:07 AM
There is "No" way to create that list dynamically. I tried passing it as a string inside of a variable. I tried passing it as an array.
I tried looping THROUGH an array inside the [] and it shoots a syntax error.
This is really confusing. Is there ANYWAY to make the list of options under filter by dynamic.
My subarea, group, and report to list come from a DB and he's wanting a list of those choices to filter by instead of a text area. It's not working. 5 hours this morning and I have been able to come up with nothing.
Any advice?

hendricd
25 Jun 2008, 9:24 AM
Is there ANYWAY to make the list of options under filter by dynamic....

ListFilter support one of two options for defining list members:

1) Most common, static definitions:
{
type: 'list',
dataIndex: 'subarea',
options: [{id:1,text:'option 1'},{}.......]
}or, define a store in advance to hold them:

2)
{
type: 'list',
dataIndex: 'subarea',
store : new Ext.data.Store({
url: ?? load it yourself
,reader: new Ext.data.ArrayReader({id: 0}, ['id', 'text'])
})
}But, keep in mind, either options needs to be setup before the plugin.init call is made.

businessman332211
25 Jun 2008, 9:33 AM
I have a few questions if you have time.
You mentioned 2 ways.
So #1 is something I can ONLY do if I had static (non-changing) list options I wanted to use..right?
So nothing will be accepted there but static values. Then the second option is basically just that..for Non-Static lists.
So I would need to create a PHP function and echo it out (would it need to be echoed as JSON or as a straight PHP array in order for the reader to get it.

hendricd
25 Jun 2008, 9:35 AM
Option 2 would reload the store every time the filter menu is shown.

businessman332211
25 Jun 2008, 9:40 AM
I am confused. Ok. This is what I have.
PHP Code - This is a seperate function I created to get the array of subareas.



function admin_getsubarealist() {
// get subareas
$subareas = $this->User->Subarea->findAll("subarea_name != 'ALL'", 'subarea_name');
// put them in order
sort($subareas);
foreach ($subareas as $k => $v) {
$subareaarray = $v['Subarea']['subarea_name'];
}
echo $subareaarray;
}

Ok
Here is my javascript..this is the part of filters that I changed.
But it's returning a blank screen.


var filters = new Ext.ux.grid.GridFilters({
filters:[
{type: 'numeric', dataIndex: 'u_id'},
{type: 'string', dataIndex: 'login_name'},
{type: 'string', dataIndex: 'first_name'},
{type: 'string', dataIndex: 'last_name'},
{type: 'string', dataIndex: 'group'},
{
type: 'list',
dataIndex: 'subarea',
store : new Ext.data.Store({
url: '{{$html->url('/admin/users/getusers/getsubarealist')}}'
,reader: new Ext.data.ArrayReader({id: 0}, ['id', 'text'])
});
},
{type: 'string', dataIndex: 'report_to'},
{type: 'string', dataIndex: 'city'}
]});


I have to do report to and group as well but I am just trying to make the subarea work for now. Thisshould go visit that URL and get the data (in array format) thenthe array reader should change it around and use it as list options? But it's actually making the page go blank for some reason and the "Page" loads but the grid doesn't now.

hendricd
25 Jun 2008, 9:49 AM
Lose the semi-colon after store:

businessman332211
25 Jun 2008, 9:58 AM
Thank you again you have been loads of help so far.
That stopped the error and it's coming up now. It loads a few minute but then returns an empty result. So there is basically nothing being loaded. Maybe I am formatting my array wrong?
I just have a simple array. Which is auto-indexed. With 1 value (a flat array.
array - subareas
[0] - subarea1
[1] - subarea2
[3] - subarea3
[4] - subarea4
[5] - subarea5
[6] - subarea6
Is that the basic array format I need or is there something "Specific" I need to do to get it to work?

hendricd
25 Jun 2008, 10:24 AM
Have a look at the source for Ext.ux.grid.filter.ListFilter

It shows how it loads it's internal store for lists.

businessman332211
25 Jun 2008, 10:38 AM
I know it's related to this coding. I just can't tell exactly what it's doing. I can see the 2nd line is what shows the loading text when it's loading. Then it checks and see's something that doesn't make sense to me. Right now i am echoing the flat array from php and just Echoing it and when it goes to the URL and get's it..it's not changing it into the menu for some reason. It's kind of got me confused.


init: function(){
this.menu.add('<span class="loading-indicator">' + this.loadingText + '</span>');

if(this.store){
if(this.loadOnShow)
this.menu.on('show', this.onMenuLoad, this);

} else if(this.options){
var options = [];
for(var i=0, len=this.options.length; i<len; i++){
var value = this.options[i];
switch(Ext.type(value)){
case 'array': options.push(value); break;
case 'object': options.push([value.id, value[this.labelField]]); break;
case 'string': options.push([value, value]); break;
}
}

this.store = new Ext.data.Store({
reader: new Ext.data.ArrayReader({id: 0}, ['id', this.labelField])
});
this.options = options;

this.menu.on('show', this.onMenuLoad, this);
}
this.store.on('load', this.onLoad, this);

this.bindShowAdapter();
},

hendricd
25 Jun 2008, 10:42 AM
You'll need to get a basic Array-reading store to load an array via an HTTPProxy, first. Once thats working you're good to go.

businessman332211
25 Jun 2008, 10:51 AM
That's what is confusing me. Your code included a store and an array reader (it also had a URL with it.

For example.
My Javascript Code Just the section about my filters


var filters = new Ext.ux.grid.GridFilters({
filters:[
{type: 'numeric', dataIndex: 'u_id'},
{type: 'string', dataIndex: 'login_name'},
{type: 'string', dataIndex: 'first_name'},
{type: 'string', dataIndex: 'last_name'},
{type: 'string', dataIndex: 'group'},
{
type: 'list', // tell it what type (I want a list)
dataIndex: 'subarea', // This is what it's associated with
store : new Ext.data.Store({
url: '{{$html->url('/admin/users/getsubarealist')}}' // this is the URL
,reader: new Ext.data.ArrayReader({id: 0}) // This is what is done
})
},
{type: 'string', dataIndex: 'report_to'},
{type: 'string', dataIndex: 'city'}
]});



Ok that URL..when it visits that URL I have the function at that url (I am using cake) setup to create an array of the subareas and simply echo them out. That's all. But when the thing get's pulled back to the reader it doesn't do anything but load forever and then load an empty set of data or something (shows nothing in the menu).
I am confused about what Step(s) I might be missing.

businessman332211
25 Jun 2008, 10:58 AM
I "Think" I understand what you meant now. I added in the needed code and it does the same thing. Again my PHP file when it's called is simple 'Echoing" an array of the subarears.
Now i have the following for my JS.


var filters = new Ext.ux.grid.GridFilters({
filters:[
{type: 'numeric', dataIndex: 'u_id'},
{type: 'string', dataIndex: 'login_name'},
{type: 'string', dataIndex: 'first_name'},
{type: 'string', dataIndex: 'last_name'},
{type: 'string', dataIndex: 'group'},
{
type: 'list',
dataIndex: 'subarea',
store : new Ext.data.Store({
proxy: new Ext.data.HttpProxy({
url: '{{$html->url('/admin/users/getsubarealist')}}'
}),
reader: new Ext.data.ArrayReader({id: 0})
})
},
{type: 'string', dataIndex: 'report_to'},
{type: 'string', dataIndex: 'city'}
]});


Note the bold code is what I just added in since hte last post. NOW it should be opening a proxy properly to get the data and then the reader should be handling the obtained data, but it still does the same thing. Is this what you meant when you said I needed a Proxy as well?

businessman332211
25 Jun 2008, 11:25 AM
More piecing together.
I finally realized I needed actually JSON output (being echoed) instead of a straight PHP array. Atleast that's what I gathered. + I made modifications to my Javascript based on what I saw.


var filters = new Ext.ux.grid.GridFilters({
filters:[
{type: 'numeric', dataIndex: 'u_id'},
{type: 'string', dataIndex: 'login_name'},
{type: 'string', dataIndex: 'first_name'},
{type: 'string', dataIndex: 'last_name'},
{type: 'string', dataIndex: 'group'},
{
type: 'list',
dataIndex: 'subarea',
store : new Ext.data.Store({
proxy: new Ext.data.HttpProxy({
url: '{{$html->url('/admin/users/getsubarealist')}}'
}),
reader: new Ext.data.ArrayReader({root: 'subareaarray'})
})
},
{type: 'string', dataIndex: 'report_to'},
{type: 'string', dataIndex: 'city'}
]});


I modified some of my code and now I am completely up against a wall. I can't see a way to make this fall into place like this. I am 100% sure what is being echo'd out is actually JSON formatted output (the simple array simply turned into JSON and echod). but it's still JUST loading forever. Any advice?

hendricd
25 Jun 2008, 11:35 AM
If your server is returning an array of JSON records then set up the a JsonStore instead and define the fields it needs ( id, text). ;)

businessman332211
25 Jun 2008, 11:37 AM
I tried doing an array first and it wasn't working at all. I am not sure. I guess I would need an array then? for what I am tyring to do. But whether I echo "array" or echo 'json" either way it's not currently working. Given the old setup..with it echoing an array instead of JSON is there something wrong with the way I am trying to do it?

hendricd
25 Jun 2008, 11:40 AM
Post the response your currently sending back (not the Cake script itself). Let's see the actual response.

businessman332211
25 Jun 2008, 11:46 AM
I am limited on what I can show. I can't really show a list of all of the area names. It's just a full array.
That's just a sample part of it with the names replaced with area1 area2 and so forth. Also note the original output shows actualy 100+ key this is just cut down to show you what I am echoing out.


Array
(
[0] => area1
[1] => area2
[2] => area3
)

My javascript code (current) is:


<script type="text/javascript">
// create the Data Store
Ext.onReady(function(){
Ext.ux.grid.filter.StringFilter.prototype.icon = 'img/find.png';
var store = new Ext.data.Store({
// load using an HttpProxy
proxy: new Ext.data.HttpProxy({
url: '{{$html->url('/admin/users/getusers')}}'
}),
// create reader that reads the records
reader: new Ext.data.JsonReader({
root: 'rows',
fields: [
{name: 'u_id'},
{name: 'login_name'},
{name: 'first_name'},
{name: 'last_name'},
{name: 'group'},
{name: 'subarea'},
{name: 'report_to'},
{name: 'city'}
]
}),
// turn on remote sorting
sortInfo: {field: 'login_name', direction: 'ASC'},
remoteSort: true
});
var filters = new Ext.ux.grid.GridFilters({
filters:[
{type: 'numeric', dataIndex: 'u_id'},
{type: 'string', dataIndex: 'login_name'},
{type: 'string', dataIndex: 'first_name'},
{type: 'string', dataIndex: 'last_name'},
{type: 'string', dataIndex: 'group'},
{
type: 'list',
dataIndex: 'subarea',
store : new Ext.data.Store({
proxy: new Ext.data.HttpProxy({
url: '{{$html->url('/admin/users/getsubarealist')}}'
}),
reader: new Ext.data.ArrayReader({root: 'subareaarray'})
})
},
{type: 'string', dataIndex: 'report_to'},
{type: 'string', dataIndex: 'city'}
]});

filters.local = true;
// create the Grid
var column_model = new Ext.grid.ColumnModel ([
{id: 'u_id', header: "User ID", width: 100, sortable: true, dataIndex: 'u_id'},
{id: 'login_name', header: "Login Name", width: 150, sortable: true, dataIndex: 'login_name'},
{id: 'first_name', header: "First Name", width: 150, sortable: true, dataIndex: 'first_name'},
{id: 'last_name', header: "Last Name", width: 150, sortable: true, dataIndex: 'last_name'},
{id: 'group_name', header: "Group", width: 150, sortable: true, dataIndex: 'group'},
{id: 'subarea', header: "Subarea", width: 150, sortable: true, dataIndex: 'subarea'},
{id: 'report_to', header: "Report To", width: 150, sortable: true, dataIndex: 'report_to'},
{id: 'city', header: "City", width: 150, sortable: true, dataIndex: 'city'}
]);
var grid = new Ext.grid.GridPanel({
el: 'audit-data-grid',
autoFitColumns: true,
loadMask: true,
store: store,
cm: column_model,
plugins: filters,
stripeRows: true,
height:350,
width:1100,
title:'Users Data'
});
grid.render();
store.load();
});
</script>
<link rel="stylesheet" type="text/css" href="/css/extcss/auditgrids.css" />
<!-- Common Styles for the examples -->
<div id="audit-data-grid"></div>
<br>

hendricd
25 Jun 2008, 11:50 AM
/:)

How about a fragment OF THE JSON RESPONSE.

I'm not clairvoyant, yet.

businessman332211
25 Jun 2008, 11:53 AM
I took out the JSON response and changed it back to an array when you said I needed to "Redo" the store if I wanted JSON. Here is what "was" and "can if needed" come out as JSON.
When I change it to JSON it looks like this...
Here is a small example of what is returned. I took off about 150 of the names and replaced the ones that were left with fake names behind of the NDA's I signed for the project.
But this'll give you an idea of what is being returned "When" I change it to output JSON.


{"subareaarray":["Subarea1","Subarea2","Subarea3","Subarea4"]}

hendricd
25 Jun 2008, 12:05 PM
Class Ext.data.JsonStore
Package: Ext.data
Defined In: JsonStore.js
Class: JsonStore
Extends: Store
Small helper class to make creating Stores for JSON data easier.

var store = new Ext.data.JsonStore({
url: 'get-your-cake.php',
root: 'subareaarray',
fields: ['id', 'text']
});

This would consume a returned object of the form:
{
subareaarray: [
{id: 1, text: 'option 1' },
{id: 2, text: 'option 2' }
]
}
Give that store to the filter config, make your Cake provide that output and educate yourself more with just how data.Stores work.

You can make it happen. Just stop changing your mind every 4 posts.

Good Luck.

Efex
25 Jun 2008, 1:36 PM
Hi, I've read all the help you're giving to bussinessman and wanted to boher you with two questions:

1) I am getting a 'undefined' result when I try to create a dynamic list filter. Here's the code I'm using:



var catFilterStore = new Ext.data.GroupingStore({
proxy: new Ext.data.PagingMemoryProxy(filteredRecords),
reader: new Ext.data.JsonReader({}, [{name: 'Categoria', type: 'string', mapping: 'categoria'}]) ,
sortInfo:{field: 'Categoria', direction: "ASC"}
});

var filters = new Ext.ux.grid.GridFilters({local: true, filters:[
{type: 'string', dataIndex: 'Articulo'},
{
type: 'list',
dataIndex: 'Categoria', where's this index from?? Is it form the store I'm using for the grid and the other filters or from this filter's new store?
store: catFilterStore
},
{type: 'string', dataIndex: 'Subpartida'},
{type: 'string', dataIndex: 'Unidad'},
{type: 'date', dataIndex: 'Ultima_mod'}
]});

I get the correct number of fields from store but just doesn't show the names. (I'm attaching an image of the result I'm getting)
What am I doing wrong??? :-?:-?


2) How do I make this work for the entire Store and not only for the records being paged on a paging toolbar grid??
I mean, the other filters work only for the records on the current page, but I would like to work on the entire Store and show all values matching the filter (paged also according to my paging config)
My page and filter is local because I have my Json array received as a param from another function :-?:-?

hendricd
25 Jun 2008, 2:53 PM
@Efex --

RE: #1: the labelField property (default is 'text') determines what store:record:element is displayed:



{
type: 'list',
dataIndex: 'Categoria', where's this index from?? Is it form the store I'm using for the grid and the other filters or from this filter's new store?
labelField : '[c/C]ategoria', //might be yours ??
store: catFilterStore
},
RE: #2
Using local:true only filters what's currently in the store (whether paging or not). If you want to filter the entire result set (and use paging) you must filter server-side first (local:false).

Efex
25 Jun 2008, 3:10 PM
#1
thank you very much!!
It's working now finally :) :)=D>=D>

EDIT: It's working on showing the labels correctlly but it's not filtering properly :(
When I select any option it clears the grid not showing anything althought the option is valid. What could this be?

#2
Ok. But my store has all the records including the ones not showing because of paging correct? but it's not presenting the filters for those records but only for the ones presented on paging.
Am I missing something?

EDIT : What I guess the filter should do is, undo the paging, then filter the store and rebuild grid, paging if results filtered are more than the pageSize option of paging toolbar.
But that's not what's doing. It only filters the records already paged and mantining the paging structure :(

LeonardoAP
27 Jun 2008, 8:02 AM
Heya.

I'm in a singular situation, i have a grid with a combox column, that transforms the above select


<select name="organization" id="comboOrg" style="display: none;">
<option value="1335456348">Microsoft</option>
<option value="1341631222">Google</option>
<option value="1355901893">Yahoo</option>
</select>


This column filter is configured as 'string'

ok, when i load the grid and apply a filter, it returns nothing
When i change some value of the combo, and apply the filter, it returns! but only if i put the value number of the option in the filter input.

How, to filter by the option text?

nunziofiore
3 Jul 2008, 5:21 AM
Hi Ambience,
i made a video about ext for an important italian web tv and i spoke about your plugin :) I wrote also techinacal article and next week we'll start a zone in our site icTV with videos about coding with framework like ext.. I don't know where i can write this information, but , i think you appreciate seeing your avatar i this first video...

http://www.ictv.it/file/vedi/757/realizzare-web-application-ext-js/

ambience
3 Jul 2008, 9:24 AM
Ha, thanks. I don't speak Italian so I can't understand the video. But I appreciate you mentioning me =)

mystix
3 Jul 2008, 10:06 AM
and he does look a little like the scrubs guy in his avatar... B)

tobiu
5 Jul 2008, 10:30 AM
hi ambience,

i really love this plugin!

i am not sure if anyone has asked this already, since the post got really long.

when working with grids, i use several columns containing times (like in mysql -> time) in a format like H:i:s or just H:i.

what would be really cool is a filter for the datatyp time.
i would make it look like the date-filter, containg <, >, =, !=. but instead of using calendars, using Ext.form.TimeFields.

if anyone has already coded this, please let me know!
i might do it by myself, but i am really short in time till august.


kind regards, tobiu

eliasp
8 Jul 2008, 7:15 AM
I'm using GridFilter for my project too, but still face the same problem as some people before in this thread:
When I reset a filter (remove all data from the inputfield or uncheck the filter), the previous value is still sent to the server.
zhiliang suggested to add


this.value=[];


I added it to the onLoad() function in ux/grid/filter/ListFilter.js but it didn't change anything?

Does anyone know how to work around this problem?

Best regards,

Elias P.

hendricd
8 Jul 2008, 7:45 AM
Are there any overrides involved with any of the following:

onBeforeLoad,
cleanParams, or
buildQuery

eliasp
9 Jul 2008, 6:23 AM
Are there any overrides involved with any of the following:

onBeforeLoad,
cleanParams, or
buildQuery

I'm using the LiveGrid (http://extjs.com/forum/showthread.php?t=17791) ux too and this includes an onBeforeLoad function. Seems this causes it:


onBeforeLoad : function(store, options)
{
if (!options.params) {
options.params = {start : 0, limit : this.ds.bufferSize};
} else {
options.params.start = 0;
options.params.limit = this.ds.bufferSize;
}
options.scope = this;
options.callback = function(){this.reset(false);};
return true;
},


Has anyone ever combined both? How did you do that?

hendricd
9 Jul 2008, 7:11 AM
GridFilters uses the EventManager to trap beforeload so that the filters can be added to the request params (along with all other beforeload consumers).

Could it be that LiveGrid does not raise (fireEvent) beforeload, thus GridFilters never gets the chance to update the params?

johnsbrn
11 Jul 2008, 2:40 PM
I can't type a left paren ( into a StringFilter box and I can't for the life on me figure out why. I've looked through the code and tried everything I can think of, and still no left paren. Any ideas?? I am allowing users to do things like bob AND (smith or johnson) so I really need to be able to use that key. Also, arrow keys don't work.

johnsbrn
11 Jul 2008, 2:42 PM
just an update, this appears to be an issue related to Firefox only. I am using version 3, but may apply to others as well.

johnsbrn
12 Jul 2008, 7:57 AM
Arrow keys also don't work on Safari (OS X) and I still can't figure out why. Other TextFields work fine.

johnsbrn
12 Jul 2008, 10:28 AM
I think I found a fix in EditableItem.js



onRender: function(container){
var s = container.createChild({
cls: this.itemCls,
html: '<img src="' + (this.icon||Ext.BLANK_IMAGE_URL)+ '" class="x-menu-item-icon'+(this.iconCls?' '+this.iconCls:'')+'" style="margin: 3px 7px 2px 2px;" />'});;

Ext.apply(this.config, {width: 125});
this.editor.render(s);

this.el = s;
this.relayEvents(this.editor.el, ["keyup"]);
this.editor.el.swallowEvent(['keypress','keydown']);

if(Ext.isGecko)
s.setStyle('overflow', 'auto');

Ext.ux.menu.EditableItem.superclass.onRender.apply(this, arguments);
},


this.editor.el.swallowEvent(['keypress','keydown'] appears to fix the problem

sami_user
16 Jul 2008, 7:31 AM
Hi,

I implemented a grid which reads from an Array and has a paging toolbar at the bottom. This is working fine. After this, I tried to include the feature of grid filtering (filtering on columns) and the filtering is not working.
I used "Ext.ux.data.PagingMemoryProxy.js" as the proxy for the store, and ArrayReader as the reader. I am pasting my code below for reference. It will be great if anyone can look and tell me where I am going wrong in implementing the filtering feature.

Does filters work only for JsonStore? I am not able to figure out, where I am going wrong in the below code. I will be really thankful if someone can guide me here.


<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf8">
<link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />
<link rel="stylesheet" type="text/css" href="../shared/examples.css" />
<script type="text/javascript" src="../../adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="../../ext-all.js"></script>
<script src="Ext.ux.data.PagingMemoryProxy.js" type="text/javascript"></script>
<script type="text/javascript" src="../grid-filtering/menu/EditableItem.js"></script>
<script type="text/javascript" src="../grid-filtering/menu/RangeMenu.js"></script>
<script type="text/javascript" src="../grid-filtering/grid/GridFilters.js"></script>
<script type="text/javascript" src="../grid-filtering/grid/filter/Filter.js"></script>
<script type="text/javascript" src="../grid-filtering/grid/filter/StringFilter.js"></script>
<script type="text/javascript" src="../grid-filtering/grid/filter/DateFilter.js"></script>
<script type="text/javascript" src="../grid-filtering/grid/filter/ListFilter.js"></script>
<script type="text/javascript" src="../grid-filtering/grid/filter/NumericFilter.js"></script>
<script type="text/javascript" src="../grid-filtering/grid/filter/BooleanFilter.js"></script>
<script type="text/javascript">
Ext.onReady(function(){
// shorthand alias
var fm = Ext.form;
// the column model has information about grid columns
// dataIndex maps the column to the specific data field in
// the data store (created below)
var cm = new Ext.grid.ColumnModel([
{
header: "Short Name",
dataIndex: 'abbr',
width: 100
},
{
header: "Long Name",
dataIndex: 'state',
width: 200
},
{
header: "Description",
dataIndex: 'desc',
width: 200
}
]);
// by default columns are sortable
cm.defaultSortable = true;
var myarray =[
['AL', 'Alabama', 'The Heart of Dixie'],
['AK', 'Alaska', 'The Land of the Midnight Sun'],
['AZ', 'Arizona', 'The Grand Canyon State'],
['AR', 'Arkansas', 'The Natural State'],
['CA', 'California', 'The Golden State'],
['CO', 'Colorado', 'The Mountain State'],
];
// create the Data Store
var ds = new Ext.data.Store({
proxy: new Ext.ux.data.PagingMemoryProxy(myarray),
reader: new Ext.data.ArrayReader({}, [
{name: 'abbr'},
{name: 'state'},
{name: 'desc'}
]),
remoteSort: true
});

/* filtering starts*/
var filters = new Ext.grid.GridFilters({
filters:[
{type: 'string', dataIndex: 'abbr'}
]});
/************************/

var grid = new Ext.grid.GridPanel({
el:'grid',
width: 500,
height: 203,
title:'Month Browser',
store: ds,
cm: cm,
plugins: filters,
sm: new Ext.grid.RowSelectionModel({selectRow:Ext.emptyFn} ),
bbar: new Ext.PagingToolbar({
pageSize: 6,
store: ds,
plugins: filters,
displayInfo: true
})
})
grid.render();
// trigger the data store load
ds.load({params:{start:0, limit:6}});
});
</script>
</head>
<body class="x-gray">
<h2>Grid</h2>
<br/>
<div id="grid"></div>
</body>
</html>

Regards,
Sam

mjlecomte
16 Jul 2008, 8:27 AM
Sam: did you try this post
http://extjs.com/forum/showthread.php?p=124392#post124392

sami_user
16 Jul 2008, 9:56 AM
Had a look at that post now...i am also using filters in the same way, but still its not working. Can someone please help me here

Sam

sami_user
16 Jul 2008, 12:38 PM
I found the missing link. There is a propery called "local:true" which needs to be set. I guess may be because I am not getting the data from the server and have it locally.




var filters = new Ext.grid.GridFilters({
local: true,
filters:[
{type: 'string', dataIndex: 'abbr'}
]});


Now I have another problem. When I display the paged grid for the first time there are 9 pages of data. After filtering I have only one result and ideally would expect the pagingtoolbar to show that there is only 1 page at the bottom. But it still shows that the there are 9 pages. When I navigate to the rest of the pages they are all blank (good !!). Now how do we need to modify the pagingtoolbar to refresh and show the correct number of pages after the filtering is done?


Regards,
Sam

mjlecomte
16 Jul 2008, 12:47 PM
sami: I think you'll need to do some modifying to the paging toolbar, I recall having such issues some time back where the total wouldn't get updated. I believe the paging toolbar is monitoring reloads of the store and looking for a totalproperty, nothing more. If you change the total then you need to update the paging toolbar manually.

hendricd
16 Jul 2008, 1:02 PM
Ext.grid.GridFilters is plugin aware. Ensure you've also plugin-registered your GF instance with the PagingToolBar when you create the grid:



,bbar: new Ext.PagingToolbar({
pageSize: this.options.pageSize, //make this a global option (for all who need it)
store: this.store,
id:'pager',
plugins: filters,
displayInfo: true,
displayMsg: 'Displaying messages {0} - {1} of {2}',
emptyMsg: "No messages to display"
})


Then, the GridFilter ensures the PagingToolbar is notified of important changes.

sami_user
17 Jul 2008, 6:12 AM
Ext.grid.GridFilters is plugin aware. Ensure you've also plugin-registered your GF instance with the PagingToolBar when you create the grid:



,bbar: new Ext.PagingToolbar({
pageSize: this.options.pageSize, //make this a global option (for all who need it)
store: this.store,
id:'pager',
plugins: filters,
displayInfo: true,
displayMsg: 'Displaying messages {0} - {1} of {2}',
emptyMsg: "No messages to display"
})


Then, the GridFilter ensures the PagingToolbar is notified of important changes.

I am taking care to register the GF with the PagingToolBar as you can see in the code that i posted earlier. Even then this is hapenning.

Regards,
Sam

hendricd
17 Jul 2008, 6:16 AM
@sami -- Also, If you are using PagingMemoryProxy, it acts as your server, so GF:local should be false, if you want that proxy to handle filtering (otherwise, the store handles the filtering -- but, only what's currently loaded in it at the time).

sami_user
17 Jul 2008, 6:19 AM
@sami -- Also, If you are using PagingMemoryProxy, it acts as your server, so GF:local should be false, if you want that proxy to handle filtering (otherwise, the store handles the filtering -- but, only what's currently loaded in it at the time).

I changed GF:local to false as suggested by you. Now its not filtering at all :(

Regards,
Sam

ajaxE
19 Jul 2008, 7:15 PM
It seems this filter grid doesn't work for checkBoxSelectionModel.

e.g.


var sm = new Ext.grid.CheckboxSelectionModel();
var grid = new Ext.grid.EditorGridPanel({
sm: sm,
cm: cm,
plugins: filters,
...
});
The checkbox didn't showup at all. Am I missing anything?

Thanks for your help!

mystix
19 Jul 2008, 11:37 PM
It seems this filter grid doesn't work for checkBoxSelectionModel.

e.g.


var sm = new Ext.grid.CheckboxSelectionModel();
var grid = new Ext.grid.EditorGridPanel({
sm: sm,
cm: cm,
plugins: filters,
...
});
The checkbox didn't showup at all. Am I missing anything?

Thanks for your help!
make sure the CheckboxSelectionModel is part of your ColumnModel definition (cm) also.

sidaliextjs
20 Jul 2008, 1:59 PM
Great work ambience, it's very nice plugin.

keckeroo
20 Jul 2008, 8:59 PM
Is it me - or is the sort in the GridFilter example not working ? I can sort only once and then not again in any column. Try sorting the company names - i cannot get them to sort in descending order.

Kev

Steffen Hiller
22 Jul 2008, 1:47 PM
Hey,

I have a frustrating problem, which I couldn't solve so far.

To reproduce my problem, just go to the example (http://extjs.com/deploy/dev/examples/grid-filtering/grid-filter.html), type in a word in the company filter field and try the following three things in Firefox 2 or 3:


Select the word via double click
Select the word by holding the mouse button down
Set the cursor within the word


Neither of these points work. You only can delete a filter value by clicking into the field (which sets the cursor at the end of your value) and hitting the backspace key.

I've searched the forum and the web for quiet some time, I also tried different things with the ext js code, but neither helped.

I've found one thread (http://extjs.com/forum/showthread.php?p=121738#post121738), which addresses this issue. An Ext Support Team member said: "FF has problems with edits in elements that have a mouseover event attached." Well, the header menu has a mouseover event attached, but after removing it, it didn't change a thing.

Can anybody help me here? I think it's a confusing and frustating bug in the gridfilter plugin, though it's a great plugin of course.

Thanks a lot!
Steffen

Michael Reach
24 Jul 2008, 8:29 AM
Hi! Is there an API available for the grid filters, similar to the online Ext 2.1 - API for the standard features?
Also, is there an example of how to use the filters in local=true mode, instead of having to go off to a .php routine?

Canard64
25 Jul 2008, 1:34 AM
Hello I'm french sorry for my english :p

I've got a problem with the plugin grid filter.

It's possible to use a xmlReader because in all exemples they use JsonReader.




[code]

var Schemageneral = Ext.data.Record.create([
{name: 'idgab', type: 'string'},
{name: 'numerogab', type: 'string'},
{name: 'indispo', type: 'int'},
{name: 'indispop', type: 'int'},
{name: 'indispot', type: 'int'},
{name: 'indispoa', type: 'int'}

]);

var filters = new Ext.grid.GridFilters({
filters:[

{type: 'string', dataIndex: 'idgab'},
{type: 'string', dataIndex: 'numerogab'},
{type: 'numeric', dataIndex: 'indispo'},
{type: 'numeric', dataIndex: 'indispop'},
{type: 'numeric', dataIndex: 'indispot'},
{type: 'numeric', dataIndex: 'indispoa'}

]});



var storeGeneral = new Ext.data.GroupingStore({

//on d

xp743
28 Jul 2008, 11:42 PM
I have 2 grids and work as master/detail relationship with php/backend. But I don't know how to implement the filter for child grid on MasterGrid listeners:function

Assume :
Grid 1 (MasterGrid) have table fields :
-PersonID
-PersonName
-PersonAddress

Grid2 (Child/DetailGrid) have table fields :
-DetailID
-PersonID
-PersonJob
Both Grid linked by 'PersonID'

Case (one 2 many) : 1 personID can be have 1 or more detail Data
wishes :
-Child/DetailGrid load by filter 'rowselect' (sm, index, record)

anyone can help me ?


this.gsm = this.grid.getSelectionModel();
//When a row is selected we need to update/load the DetailGrid filtered
this.gsm.on('rowselect', function(sm, index, record) {
this.dtGrid = Ext.getCmp("detail-grid");
this.dtGrid.store.setValue('');
this.dtGrid.store.filter('PersonID', record.getValue());
this.dtGrid.store.load();
Ext.getCmp("form-prev").getForm().loadRecord(record);
var items = this.preview.topToolbar.items;
items.get('tab').enable();},
this, {buffer: 250});
this.grid.store.on('beforeload', this.dtGrid.clear, this.dtGrid);
this.grid.store.on('beforeload', this.preview.clear, this.preview);
this.grid.store.on('load', this.gsm.selectFirstRow, this.gsm);
Screenshot : http://extjs.com/forum/attachment.php?attachmentid=8379&stc=1&d=1217317168

SoreGums
29 Jul 2008, 8:34 PM
Ok finally read all 57 pages (this took a while)

What I found out is that to set an initial filter on the grid at load you can use

filter.setValue()
filter.setActive()

However doing this loads my grid twice...

So my question is how do I load a grid with a "default" filter set? That can be modified later and the filter is visible

Thanks :)

jelt
31 Jul 2008, 12:08 AM
So my question is how do I load a grid with a "default" filter set? That can be modified later and the filter is visible

use the option "defaultValue" and "active"

example :


gridfilter = new Ext.ux.grid.GridFilters({
filters:[{type: "boolean", defaultValue:true, active:true, dataIndex: "LANGDEP" }]

...

});

crackrock
31 Jul 2008, 7:29 AM
I changed GF:local to false as suggested by you. Now its not filtering at all :(

Regards,
Sam

I got the exact same problem. Using local to true, the filtering works but the paging toolbar does not update. Using local to false, there is no filtering.

SoreGums
31 Jul 2008, 4:44 PM
use the option "defaultValue" and "active"

example :


gridfilter = new Ext.ux.grid.GridFilters({
filters:[{type: "boolean", defaultValue:true, active:true, dataIndex: "LANGDEP" }]

...

});

Ok this kind of works. I am unable to edit the value with this setting.
The error is "this.value.getValue() has no properties"

So I've done this:


var filters = new Ext.ux.grid.GridFilters({
filters:[
...
,{type: 'string', dataIndex: DBMap.Name, active: true }
]
});

openGrid : function(text) {
if(Ext.getCmp('cmp_Grid2') == null) {
mainPanel.add({id: 'cmp_Grid2',xtype: 'Grid2'});
}
var cmp = Ext.getCmp('cmp_Grid2');

mainPanel.getLayout().setActiveItem(cmp);
mainPanel.doLayout();

// Set default filter of the logged in person
var filter = cmp.filters.getFilter(DBMap.Name);
filter.setValue(User.Name);

var limit = cmp.store.lastOptions ? cmp.store.lastOptions.params.limit : 20;
cmp.store.load({params:{start: 0,limit: limit}});
}


Thanks for the pointer :)

SoreGums
31 Jul 2008, 9:58 PM
Ok this kind of works. I am unable to edit the value with this setting.
The error is "this.value.getValue() has no properties"

So I've done this:


var filters = new Ext.ux.grid.GridFilters({
filters:[
...
,{type: 'string', dataIndex: DBMap.Name, active: true }
]
});

openGrid : function(text) {
if(Ext.getCmp('cmp_Grid2') == null) {
mainPanel.add({id: 'cmp_Grid2',xtype: 'Grid2'});
}
var cmp = Ext.getCmp('cmp_Grid2');

mainPanel.getLayout().setActiveItem(cmp);
mainPanel.doLayout();

// Set default filter of the logged in person
var filter = cmp.filters.getFilter(DBMap.Name);
filter.setValue(User.Name);

var limit = cmp.store.lastOptions ? cmp.store.lastOptions.params.limit : 20;
cmp.store.load({params:{start: 0,limit: limit}});
}
Thanks for the pointer :)

Actually this doesn't work - it results in a double grid load as well....

ambience
4 Aug 2008, 8:54 AM
Hey,

I have a frustrating problem, which I couldn't solve so far.

To reproduce my problem, just go to the example (http://extjs.com/deploy/dev/examples/grid-filtering/grid-filter.html), type in a word in the company filter field and try the following three things in Firefox 2 or 3:


Select the word via double click
Select the word by holding the mouse button down
Set the cursor within the word


Neither of these points work. You only can delete a filter value by clicking into the field (which sets the cursor at the end of your value) and hitting the backspace key.

I've searched the forum and the web for quiet some time, I also tried different things with the ext js code, but neither helped.

I've found one thread (http://extjs.com/forum/showthread.php?p=121738#post121738), which addresses this issue. An Ext Support Team member said: "FF has problems with edits in elements that have a mouseover event attached." Well, the header menu has a mouseover event attached, but after removing it, it didn't change a thing.

Can anybody help me here? I think it's a confusing and frustating bug in the gridfilter plugin, though it's a great plugin of course.

Thanks a lot!
Steffen

I am a bit perplexed by this one as well (as far as I know it's a new bug). I suspect something is catching mouse down and calling .preventDefault(), but I cannot seem to locate it.

Steffen Hiller
4 Aug 2008, 9:15 AM
I am a bit perplexed by this one as well (as far as I know it's a new bug). I suspect something is catching mouse down and calling .preventDefault(), but I cannot seem to locate it.

Hey ambiance,

thanks for your reply. This is really a tricky one.
I actually made an extra thread which is moved to the bugs by saki, see here (http://extjs.com/forum/showthread.php?t=42331).

I also made a support request to the ext js team, they replied last tuesday that they will look into it, but that they/he assumes that it's a firefox bug.

Well, so far no solution yet.

I just looked into the ext js code again.

This methods in the BaseItem class looks suspicious:


onClick : function(e){
if(!this.disabled && this.fireEvent("click", this, e) !== false
&& this.parentMenu.fireEvent("itemclick", this, e) !== false){
this.handleClick(e);
}else{
e.stopEvent();
}
},


But as far as I remember, in the tests this onClick method isn't actually called when clicked on the input field. But a stopEvent call somewhere could cause that, too, I guess. But I'm not so much into event handling.

I really would appreciate it if you have any more ideas or suggestions!

Thanks,
Steffen

ambience
4 Aug 2008, 9:31 AM
I checked the thread you linked earlier and put the following code in the onRender method of Ext.ux.menu.EditableItem to remove the mouseover events on the menu:


this.parentMenu.getEl().child('.x-menu-list').un("mouseover", this.parentMenu.onMouseOver, this.parentMenu);
this.parentMenu.getEl().child('.x-menu-list').un("mouseout", this.parentMenu.onMouseOut, this.parentMenu);

no dice =\ I also tried attaching a "mousedown" listener to the field directly and stopping the event bubble. Still nothing, I am at a bit of a loss.

Steffen Hiller
4 Aug 2008, 10:13 AM
Well, I tried pretty much the same by commenting the following 3 lines in the render method of Menu class:



// ul.on("click", this.onClick, this);
// ul.on("mouseover", this.onMouseOver, this);
// ul.on("mouseout", this.onMouseOut, this);


Still doesn't work.

Another observation I just made is, that when you click in the input field, and hit CTRL+A and hit delete (or CTRL+C,) the text is deleted (or copied). The text only isn't highlighted.
After that observation I tried to set "-moz-user-select: normal" on the input field, with no luck. :-/



I checked the thread you linked earlier and put the following code in the onRender method of Ext.ux.menu.EditableItem to remove the mouseover events on the menu:


this.parentMenu.getEl().child('.x-menu-list').un("mouseover", this.parentMenu.onMouseOver, this.parentMenu);
this.parentMenu.getEl().child('.x-menu-list').un("mouseout", this.parentMenu.onMouseOut, this.parentMenu);

no dice =\ I also tried attaching a "mousedown" listener to the field directly and stopping the event bubble. Still nothing, I am at a bit of a loss.

imnphd
5 Aug 2008, 5:17 AM
The sort in the grid filtering example is not working with Ext 2.2

jrh
5 Aug 2008, 5:30 AM
Also, If you are using PagingMemoryProxy, it acts as your server, so GF:local should be false, if you want that proxy to handle filtering (otherwise, the store handles the filtering -- but, only what's currently loaded in it at the time).

I'm trying the same thing, GridFilter with PagingMemoryProxy and local:false. I know I must be missing something, but I haven't been able to figure out what.

Setting local:true works fine, but then the filters are applied one page at a time. Since the entire data set is stored in the proxy, I'd rather get the proxy to apply the filters and return the filtered data back to the store.

Thanks in advance,
James


var filters = new Ext.ux.grid.GridFilters({
filters : [{
type : 'string',
dataIndex : 'abbr'
}, {
type : 'string',
dataIndex : 'state'
}],
local : false
});

var cm = new Ext.grid.ColumnModel([{
header : "Short Name",
dataIndex : 'abbr',
width : 100
}, {
header : "Long Name",
dataIndex : 'state',
width : 200
}]);

cm.defaultSortable = true;

var ds = new Ext.data.Store({
proxy : new Ext.ux.data.PagingMemoryProxy(Ext.exampledata.states),
reader : new Ext.data.ArrayReader({}, [{
name : 'abbr'
}, {
name : 'state'
}]),
remoteSort : true
});

var ex1 = new Ext.grid.GridPanel({
renderTo : 'example1',
store : ds,
cm : cm,
stripeRows : true,
height : 250,
width : 400,
plugins : filters,
viewConfig : {
forceFit : true
},
title : 'PagingMemoryProxy grid',
bbar : new Ext.PagingToolbar({
pageSize : 6,
store : ds,
displayInfo : true,
plugins : filters
})
});

ds.load({
params : {
start : 0,
limit : 6
}
});http://farm4.static.flickr.com/3193/2735588372_582e211d75_o.gif

Ant1105
7 Aug 2008, 6:47 AM
Awesome job on this plugin ambience, it works great! Not sure if someone did this already, but I added a few lines of code to give the filtered columns some coloring. Found it useful for a current project.



Ext.override(Ext.grid.GridFilters, {
updateColumnHeadings: function(view) {
if (!view || !view.mainHd) return;

var hds = view.mainHd.select('td').removeClass(this.filterCls);
for (var i = 0, len = view.cm.config.length; i < len; i++) {
var filter = this.getFilter(view.cm.config[i].dataIndex);
if (filter && filter.active) {
hds.item(i).addClass(this.filterCls);

// Do column highlighting too for filtered columns
var cells = view.mainBody.select('.x-grid3-td-c' + i).elements;
var x = cells.length; while(x--) {
x % 2 == 0 ? cells[x].className = 'yourClass' : cells[x].className = 'yourClass-alt';
}
}
}
}
});


Here is the CSS to add for the alternate colors:



td.yourClass {
background-color: #f3ffec;
}

td.yourClass-alt {
background-color: #e7f2e0;
}

div.x-grid3-row-over td.yourClass,
div.x-grid3-row-over td.yourClass-alt {
background-color: #efefef;
}

div.x-grid3-row-selected td.yourClass,
div.x-grid3-row-selected td.yourClass-alt {
background-color: #dfe8f6;
}

Steffen Hiller
10 Aug 2008, 6:30 AM
Hey ambience,

regarding the "can't select text in ff" problem, Brian from the core team found a fix (http://extjs.com/forum/showthread.php?p=207132#post207132).
I'll look into it the coming days for fix the keynav problem, too.

Regards,
Steffen

Steffen Hiller
10 Aug 2008, 10:39 AM
So here is my code based on brian's fix (http://extjs.com/forum/showthread.php?p=207132#post207132) which fixes the selecting text problem in firefox and also fixes the use of the cursor keys inside the filter field. Warning: I didn't/couldn't test it in IE nor Safari, only Firefox 3.

The code goes into the EditableItem.js file (of the gridfilters extension) and should replace if(Ext.isGecko) s.setOverflow('auto');.



["keydown", "keypress"].each(function (eventName) {
this.el.on(eventName, function (e) {
if (e.isNavKeyPress()) {
e.stopPropagation();
}
}, this);
}, this);

if(Ext.isGecko) {
s.setOverflow('auto');
var containerSize = container.getSize();
this.editor.getEl().setStyle('position', 'fixed');
container.setSize(containerSize);
}


Regards,
Steffen

gfernandez
13 Aug 2008, 5:12 AM
hi ambience, thanks for this great plugin

Can I set up a listfilter with single selection (like a radiobutton)?

regards
gf

ambience
13 Aug 2008, 8:33 AM
gfernandez: Yes, there should be a 'single: true' option on the list filter type.
Steffen: Great! Thanks for solving that, I'll post your fix and credit you in the next week or so.

gfernandez
13 Aug 2008, 9:56 AM
thanks ambience, the single option works as expected
how difficult would be to add a combo filter?

regards

chrisevans123
14 Aug 2008, 3:25 AM
Hi Guys,

Great plugin by the way, much appreciated!

I'm adding a list filter and unfortunately there's loads of items in the list. The context menu created just extends passed the screen bounds so I can only click on the first few (well a fair few) items, but can't scroll to any other items offscreen. I'm fairly new to Ext so i'm not sure whether this is a bug in the plugin or a feature (or lack of) in Ext. Any suggestions?

I appreciate most people will never need so many options, although how about setting a flag to output a combobox instead of a menu?

Anyway, great work, if anyone can help me out i'd be eternally greatful :)

Cheers and keep it up!

Chris

mjlecomte
14 Aug 2008, 6:21 AM
@chrisevans123

Maybe even use something like lovcombo (http://extjs.com/forum/showthread.php?p=154101#post154101)

I don't know how to override to plug that in off the top of my head though.

robertp42
15 Aug 2008, 9:29 AM
Hi all,

Quick Q. Is it possible to define a separate store to retrieve the values for a list filter rather than use the one attached to the current grid? I'm trying to integrate to legacy server side code and want to know if I need to request that the backend be refactored.

If anyone has an example to hand would you mind pasting it in?

Many thanks,
Robert

robertp42
15 Aug 2008, 2:25 PM
Answering my own post: yes it is.



var filters = new Ext.ux.grid.GridFilters({filters:[
<c:forEach items="${prefs.columns}" var="columnPref" varStatus="loop">
<c:set var="columnDesc" value="${queueDesc.columns[columnPref.columnId]}"/>
{
type: 'list',
dataIndex: '<c:out value="${columnDesc.id}"/>',
store: new Ext.data.Store({
proxy: new Ext.data.HttpProxy({
url: 'controller?e=queue_values&q=Outgoing.Unallocated&columnId=<c:out value="${columnDesc.id}"/>'
}),
reader: new Ext.data.XmlReader(
{ record: 'value' },
new Ext.data.Record.create(
[{
name: 'text',
mapping: 'value'
}])
)
})
}<c:if test="${!loop.last}">,</c:if>
</c:forEach>
]});

Although the above is a complete hack job... don't look at me like that, it's only a proof of concept!

nicola_java
17 Aug 2008, 5:04 AM
It is cool.:DThanks a lot.

rednix
17 Aug 2008, 1:20 PM
Nice Plugin - and here comes a tiny visual enhancement for the green tinted column header for filtered columns introduced in version 0.2.7:

To match the header column behaviour of normal columns when moving the mouse above filtered columns I added the following css and images:

resources/style.css:
.x-grid3-hd-row .ux-filtered-column.x-grid3-hd-over .x-grid3-hd-inner, .x-grid3-hd-row .ux-filtered-column.x-grid3-hd-menu-open .x-grid3-hd-inner {
background-image: url(header_bg-over.gif);
}
.x-grid3-hd-row .ux-filtered-column.x-grid3-hd-over .x-grid3-hd-inner .x-grid3-hd-btn, .x-grid3-hd-row .ux-filtered-column.x-grid3-hd-menu-open .x-grid3-hd-inner .x-grid3-hd-btn {
background:#c3daf9 url(grid3-hd-btn.gif) no-repeat left center;
}
.x-grid3-hd-row .ux-filtered-column.x-grid3-hd-over .x-grid3-hd-inner a.x-grid3-hd-btn:hover {
background-position:-14px center;
}

For the new 2 images see the attachements on this post.

Additionally I want to note that I have tested this only in Firefox3 (using Ext 2.0.2). And I know that it's not working correctly on IE6 because it doesn't interprete the ".ux-filtered-column.x-grid3-hd-over" css selector as desired; I've read that IE7 does this right.

kristalgic
18 Aug 2008, 1:06 AM
First of all, great plugin!

However, I do have a couple quick question since I am new to it:

1 - Must all the columns in the grid have a filter defined? If so, is there a way to disable a filter?

Reason: I am using the Search plugin on my "string" fields and therefore do not want to have to define a string filter for these columns; the reason being that the search plugin does not run locally and I am running the filter plugin locally. Furthermore, do not necessarily need two search methods.. :)

2 - For the list filter, if I do not specify options, it looks for a store. Do I define the store in the filter as .. {dataIndex: 'herewego', type: list, store: mystore}..

Gracias!

shahram
19 Aug 2008, 2:55 PM
Hi,
I am sort of new in this,
I have included this plugin in my scripts and it's workinf perfectly,

but there is one thing I need to do which I couldnt find it here anywhere with any search terms,
I need the filters to fire another custom function of mine with the value of the filter,
that is after filtering the grid, then it would run the custom script eg alert(filter);

what I am trying to do is to construct a link (to the grid pages) which changes according to the filter values,
so when somebody enters something in the filter, that link on the page would be updated with appropriate values.

mjlecomte
19 Aug 2008, 3:30 PM
Looks like you could add an event listener to the grid. The event is called filterupdate. You could also probably listen to beforeload, but then you'd have to use one of the extension's functions to get access to the filters, whereas it appears the filterupdate event passes the filters as an argument.

shahram
19 Aug 2008, 10:48 PM
Looks like you could add an event listener to the grid. The event is called filterupdate. You could also probably listen to beforeload, but then you'd have to use one of the extension's functions to get access to the filters, whereas it appears the filterupdate event passes the filters as an argument.


thanx, that seems to have worked,
then used getvalue to get the value :)

mjlecomte
20 Aug 2008, 6:06 AM
depends what you want to get at, but this also worked for me.

this.on({
'filterupdate':{
fn: function(){
console.info('filter update');
console.info(arguments);
console.dir(this);
console.info(this.filters.getFilterData());//returns object with data, field properties
}
}
});
The data property had the type, value, and comparison.

mcantrell
21 Aug 2008, 7:33 PM
While playing around with ExtJS and the Grid Filter extension and Grails, I documented my initial code here:

http://mcantrell.wordpress.com/2008/08/22/extjs-grids-and-grails/

It needs to handle comparisons and dates but that's pretty easy to add.

efiebba
22 Aug 2008, 12:48 AM
Hello

Sorry, but i haven't found anything about this in the whole thread . Is ist possible to filter images or icons with this plugin? In this example the different traffic lights or the fillstate?

Is there an extension or anything else?

Thanks

Bastian

Huuuze
29 Aug 2008, 9:27 AM
Sanity check -- has this been added to Ext or is it still a user extension?

ambience
2 Sep 2008, 5:32 AM
It has, to my knowledge, been included as an example I think. I am not 100% on what exactly is going on with the bundled user extensions. To my knowledge no one is actively working on it from the Ext team, so I am posting fixes here until told otherwise =)

mjlecomte
2 Sep 2008, 5:44 AM
It has, to my knowledge, been included as an example I think. I am not 100% on what exactly is going on with the bundled user extensions. To my knowledge no one is actively working on it from the Ext team, so I am posting fixes here until told otherwise =)

Ambience, FYI there's a UX repository should you wish to list this there.

ambience
2 Sep 2008, 3:19 PM
mjlecomte: does your site provide automatic packaging of the current version? Something like github?

Identified and fixed an issue where a statefull grids state would get blanked on the second restoration. Fix below, I will post a new bundle soon.

GridFilters.js


applyState: function(grid, state){
this.applyingState = true;
this.clearFilters();
if(state.filters)
for(var key in state.filters){
var filter = this.filters.get(key);
if(filter){
filter.setValue(state.filters[key]);
filter.setActive(true);
}
}

this.deferredUpdate.cancel();
if(this.local)
this.reload();

delete this.applyingState;
},

onStateChange: function(event, filter){
if(event == "serialize") return;

if(filter == this.getMenuFilter())
this.menu.setChecked(filter.active, false);

if((this.autoReload || this.local) && !this.applyingState)
this.deferredUpdate.delay(this.updateBuffer);

var view = this.grid.getView();
this.updateColumnHeadings(view);

if(!this.applyingState)
this.grid.saveState();

this.grid.fireEvent('filterupdate', this, filter);
},

mjlecomte
2 Sep 2008, 5:25 PM
Ambience: you should post questions like that to the repository admin (I'm just promoting it because it seems like a good idea). I think there was some github discussion in the past but it never went anywhere to my knowledge. This repo is in it's infancy and is basically a more convenient central location to browse ux's. I gather the roadmap may strive to enable collaboration on ux's. The repo is not meant to fork Ext in any way, it's just a repository for ux's (extensions, plugins, overrides, demos, examples?).

skaue
9 Sep 2008, 9:20 AM
I don't get my dateformat to work. Can someone please lay out how I can get this format to work: dateFormat: 'Y-m-d\\TH:i:s'

The JSON data returned to the grid works as expected and the dates have this form:
2008-04-04T11:17:31 (example)

I've tried to apply the filter like this:

var filters = new xg.GridFilters({
filters: [
{ type: 'string', dataIndex: 'name' },
{ type: 'date', dataIndex: 'created', dateFormat: 'Y-m-d\\TH:i:s' },
{ type: 'date', dataIndex: 'modified', dateFormat: 'Y-m-d\\TH:i:s' }
]
});

skaue
10 Sep 2008, 11:23 AM
Can someone please verify that this extension does not work with custom dateformats?
Or perhaps enlighten me on how to configure it to work with custom dateformats... ~o)

Here is some code:


/******
DATASTORE
****/
var store = new xd.JsonStore({
url: '/ReferenceArchive/GetFilesJson/',
root: 'rows',
fields: [
'name', 'icon', 'guid',
{ name: 'created', type: 'date', dateFormat: 'Y-m-d\\TH:i:s' },
{ name: 'modified', type: 'date', dateFormat: 'Y-m-d\\TH:i:s' }
],
sortInfo: { field: 'name', direction: 'ASC' }
});

/******
GRID
****/
var filters = new xg.GridFilters({
filters:
[
{ type: 'string', dataIndex: 'name', store: store, phpMode: true },
{ type: 'date', dataIndex: 'created', dateFormat: 'Y-m-d\\TH:i:s', store: store, phpMode: true },
{ type: 'date', dataIndex: 'modified', dateFormat: 'Y-m-d\\TH:i:s', store: store, phpMode: true }
]
});



And here is the postdata Firebug reports when I try to add some datefiltering:

filter[0][data][comparison] lt
filter[0][data][type] date
filter[0][data][value] Y-m-d\TH:i:s
filter[0][field] created

skaue
10 Sep 2008, 12:40 PM
Got it to work... I followed the "businessman332211 and hendricd"-dialog and learned a lot. Thanks guys!! Set things to filter it locally and now it works like charm!! yay! I can finally get some sleep.... I-|

cesarwbr
11 Sep 2008, 10:14 AM
I'm using the DWRProxy:


Ext.data.DWRProxy = function(dwrCall, pagingAndSort){
Ext.data.DWRProxy.superclass.constructor.call(this);
this.dwrCall = dwrCall;
//this.args = args;
this.pagingAndSort = (pagingAndSort!=undefined ? pagingAndSort : true);
};

Ext.extend(Ext.data.DWRProxy, Ext.data.DataProxy, {
load : function(params, reader, callback, scope, arg) {
if(this.fireEvent("beforeload", this, params) !== false) {
var sort;
if(params.sort && params.dir) sort = params.sort + ' ' + params.dir;
else sort = '';
var delegate = this.loadResponse.createDelegate(this, [reader, callback, scope, arg], 1);
var callParams = new Array();
if(arg.arg) {
callParams = arg.arg.slice();
}

if(this.pagingAndSort) {
callParams.push(params.start);
callParams.push(params.limit);
callParams.push(sort);
}

callParams.push(delegate);
this.dwrCall.apply(this, callParams);
} else {
callback.call(scope || this, null, arg, false);
}
},

loadResponse : function(listRange, reader, callback, scope, arg) {
var result;
try {
result = reader.read(listRange);
} catch(e) {
this.fireEvent("loadexception", this, null, response, e);
callback.call(scope, null, arg, false);
return;
}
callback.call(scope, result, arg, true);
},

update : function(dataSet){},

updateResponse : function(dataSet)
{}
});

Ext.data.ListRangeReader = function(meta, recordType){
Ext.data.ListRangeReader.superclass.constructor.call(this, meta, recordType);
this.recordType = recordType;
};
Ext.extend(Ext.data.ListRangeReader, Ext.data.DataReader, {
getJsonAccessor: function(){
var re = /[\[\.]/;
return function(expr) {
try {
return(re.test(expr))
? new Function("obj", "return obj." + expr)
: function(obj){
return obj[expr];
};
} catch(e){}
return Ext.emptyFn;
};
}(),

read : function(o){
var recordType = this.recordType, fields = recordType.prototype.fields;

//Generate extraction functions for the totalProperty, the root, the id, and for each field
if (!this.ef) {
if(this.meta.totalProperty) {
this.getTotal = this.getJsonAccessor(this.meta.totalProperty);
}

if(this.meta.successProperty) {
this.getSuccess = this.getJsonAccessor(this.meta.successProperty);
}

if (this.meta.id) {
var g = this.getJsonAccessor(this.meta.id);
this.getId = function(rec) {
var r = g(rec);
return (r === undefined || r === "") ? null : r;
};
} else {
this.getId = function(){return null;};
}
this.ef = [];
for(var i = 0; i < fields.length; i++){
f = fields.items[i];
var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
this.ef[i] = this.getJsonAccessor(map);
}
}

var records = [];
var root = o.data, c = root.length, totalRecords = c, success = true;

if(this.meta.totalProperty){
var v = parseInt(this.getTotal(o), 10);
if(!isNaN(v)){
totalRecords = v;
}
}

if(this.meta.successProperty){
var v = this.getSuccess(o);
if(v === false || v === 'false'){
success = false;
}
}

for(var i = 0; i < c; i++){
var n = root[i];
var values = {};
var id = this.getId(n);
for(var j = 0; j < fields.length; j++){
f = fields.items[j];
var v = this.ef[j](n);
values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue);
}
var record = new recordType(values, id);
records[i] = record;
}

return {
success : success,
records : records,
totalRecords : totalRecords
};
}
});


but on load the "params.filter" is undefined. why? how can I can the filter param?

dearsina
13 Sep 2008, 12:06 PM
I am mighty impressed by the grid filter and it works smoothly in my setup, so thank you to the creators. There is one thing I don't understand though, and this might very well be my lack of JS knowledge. How do I override the filter, as in, if I want to load a new filter, how would I go about doing that?

To illustrate further, say I have an address book, and currently I have it sorted by Firstname ASC. And say I have a menu of some sort on the left side of the screen that would act as filter loaders. I press the "sort by Lastname DESC" button, and the grid reloads the data with the new filter. How would this function look like?

Apologies if this has been asked before, I couldn't find it anywhere.

mjlecomte
13 Sep 2008, 12:11 PM
Your example has nothing to do with filtering, just loading new data.

dearsina
13 Sep 2008, 7:39 PM
no the data is the same. as in, yes there will be another call to the store, but with a different filter array.

Bodom78
15 Sep 2008, 11:16 PM
Is there a way reset all the filters at once as I would like to add a button and call this function?

Filters are great by the way, worked out of the box with little to no fuss and are a very powerful feature.

mjlecomte
16 Sep 2008, 8:52 AM
Is there a way reset all the filters at once as I would like to add a button and call this function?

Filters are great by the way, worked out of the box with little to no fuss and are a very powerful feature.

Try calling your instance of Ext.ux.grid.GridFilters.clearFilters() to turn all filters off. This does not clear the configuration information according to the source.

jjshoe
16 Sep 2008, 8:06 PM
Does anyone have a version of GridFilters.js where buildQuery returns json?

-Joel

jjshoe
16 Sep 2008, 8:37 PM
buildQuery: function(filters) {
var p = {};
var len = filters.length;
for(var i=0; i<len; i++)
{
var f = filters[i];
p[f.field] = f.data.value;
}
var tmp = {};
tmp["encoded"] = Ext.util.JSON.encode(p)
return tmp;
},

jjshoe
17 Sep 2008, 9:26 AM
My solution might require a smidge more work, when filtering with dates you only ever get a single date, instead of the range. I'm going to look into this and post a solution.

-Joel

jjshoe
17 Sep 2008, 9:47 AM
buildQuery: function(filters) {

var p = {};
var len = filters.length;
for(var i=0; i<len; i++)
{
var f = filters[i];
var q = { };
q["value"] = f.data.value;
q["comparison"] = f.data.comparison;
p[f.field] = q;
}
var tmp = {};
tmp["extjs_filter_encoded"] = Ext.util.JSON.encode(p)
return tmp;
},

jjshoe
17 Sep 2008, 10:37 AM
*sigh* ok, I swear I'll stop spamming this thread all by my lonesome self, but this should be the last post from me. I've now tested all combos in my grid, and this seems to safely cover my basis



buildQuery: function(filters) {

var p = {};
var len = filters.length;
for(var i=0; i<len; i++)
{
var f = filters[i];
if (f.data.comparison)
{
if (typeof(p[f.field]) != 'object')
{
p[f.field] = new Object();
}
p[f.field][f.data.comparison] = f.data.value;
}
else
{
p[f.field] = f.data.value;
}
}
var tmp = {};
tmp["extjs_filter_encoded"] = Ext.util.JSON.encode(p)
return tmp;
},

Bodom78
19 Sep 2008, 7:34 PM
Try calling your instance of Ext.ux.grid.GridFilters.clearFilters() to turn all filters off. This does not clear the configuration information according to the source.

Thanks mjlecomte,

That did the trick.

I have stumbled on to the UX Repository, I always assumed everything was in the docs that ship with ext :">

mjlecomte
19 Sep 2008, 7:50 PM
Unfortunately that's not the case. You might also be surprised to learn that there are more examples in the delivered examples than the examples index page ...indexes.

Bodom78
20 Sep 2008, 1:24 AM
Unfortunately that's not the case. You might also be surprised to learn that there are more examples in the delivered examples than the examples index page ...indexes.

Interesting, Looks like I'll manually be going through the examples folder to see what gems I may have missed. :D

dearsina
24 Sep 2008, 8:49 AM
I'm trying to load filters to the grid from a DB, but I'm running into all sorts of issues. How does one use addFilter() successfully? I've tried and tried to find some information, but to no avail. A quick code snippet would be great.

I'm also interested in how the JSON looks like (pulling filter information from a server). Hope that's not too much to ask!

mjlecomte
24 Sep 2008, 9:50 AM
Feel free to post some code, but just looking at the docs looks like something like this?



var filters = new Ext.ux.grid.GridFilters({
autoReload: false, //don't reload automatically
local: true, //only filter locally
filters: [{
type: 'numeric',
dataIndex: 'id'
}, {
type: 'string',
dataIndex: 'name'
}, {
type: 'numeric',
dataIndex: 'price'
}, {
type: 'date',
dataIndex: 'dateAdded'
}, {
type: 'list',
dataIndex: 'size',
options: ['extra small', 'small', 'medium', 'large', 'extra large'],
phpMode: true
}, {
type: 'boolean',
dataIndex: 'visible'
}]
});

then:


//make ajax request...
//send back something like:
{
type: 'boolean',
dataIndex: 'someDataIndex'
}

//decode response
o = Ext.decode(response.responseText);
//get filter from response:
var filterFromServer = o.filters;

var newFilter = filterFromServer;
filters.add(newFilter);

dearsina
26 Sep 2008, 5:27 AM
After about 4 days of faffing about, taking bits and pieces from this very long thread (including the above hint from MJ), and a plethora of other grid filter related threads, I've created what I want, a server side filtered grid where i can save and load filters. I'll put a post up for others soon, because it is by no means straightforward, and the documentation is, shall we say, sparse. The plug-in is bloody brilliant though, hats off to the developers, and now that it works, it's a real treat for the end user.

There is one final thing that I still haven't been able to crack. When I load a filter using a comparison clause (see below), the the filter isn't fed to the buildQuery(). So for instance, when my JSON query looks like this, it fails to load the correct data (ie. the POST sent to the server doesn't include the filter at all):

[{"dataIndex":"age","type":"numeric","comparison":"eq","value":"27"}]
If my filter was a straight up type: string, value: somevalue, it would work wonders.

What do I need to change? Do I nee to build a custom addFilter(), or do I need to reformat my JSON string?

mjlecomte
26 Sep 2008, 5:43 AM
Is this problem only related to dynamically added filters? Or can you not get it working with a filter defined when your instanciate the filter class?

dearsina
26 Sep 2008, 6:57 AM
Yes, the problem only occurs when I add a filter dynamically. If I were to click on the "age" header and select "=" and "27" as value, it would filter it correctly. I'm using the following script to load filters:


tree.on({
'dblclick' : {
fn: function(item){
Ext.Ajax.request({
url: 'browse.php?ajax=filter_read_one',
method: 'POST',
params: { filterID: item.id },
success: function(result, request){
o = Ext.decode(result.responseText);
var filterFromServer = o;
var newFilter = filterFromServer;
filters.clearFilters();
for(i=0;i < newFilter.length;i++){
filters.addFilter(newFilter[i]);
}
grid.getStore().load({
params: {
start: 0,
limit: 50
}
});
}
});

},
scope: this
}
});

jjshoe
26 Sep 2008, 4:36 PM
Quick question, I have a button that clears all active grid filters. However, I would only like this button to be enabled if there are indeed active grid filters.

I'm thinking I should somehow have gridfilters keep track of how many active filters, and have it disable/enable the button.

Any hints would be appreciated.

-Joel

mjlecomte
26 Sep 2008, 7:19 PM
Not sure, untested, but maybe something like:



var btn = new Ext.Button({

});

var filterPlugin = new Ext.ux.grid.GridFilters({

});

filterPlugin.on({
filterupdate: {
/**
* Handler for when filters change
* @param {Object} o this plugin
* @param {Object} f filter
*/
fn: function (o, f) {
//get current filters (returns an array)
var curFilters = o.getFilterData();
//enable the button if there are active filters
if (curFilters.length) {
btn.enable();
} else {
btn.disable();
}
}
}
});

dearsina
27 Sep 2008, 2:39 AM
I don't mean to harp on about this issue, but can anybody think of a reason why a dynamically loaded filter with a comparison won't work, when the same comparison works fine when created on the grid itself? I'm posting some snippets below, maybe it can help jog someone's memory...

dynamically loaded filter:

[{"dataIndex":"age","type":"numeric","comparison":"eq","value":"27"}]

filter that was set up initially:


var filters = new Ext.ux.grid.GridFilters({
filters:[
{type:'numeric', dataIndex: 'regID'},
{type:'numeric', dataIndex: 'userID'},
{type:'numeric', dataIndex: 'priceID'},
{type:'numeric', dataIndex: 'waitinglistID'},
{type:'string', dataIndex: 'firstname'},
{type:'string', dataIndex: 'lastname'},
{type:'string', dataIndex: 'email'},
[the list goes on for a while...]
]
});


The script that loads the dynamically loaded string into the filters.


Ext.Ajax.request({
url: 'browse.php?ajax=filter_read_one',
method: 'POST',
params: { filterID: item.id },
success: function(result, request){
o = Ext.decode(result.responseText);
var filterFromServer = o;
var newFilter = filterFromServer;
filters.clearFilters();
for(i=0;i < newFilter.length;i++){
filters.addFilter(newFilter[i]);
}
grid.getStore().load({
params: {
start: 0,
limit: 50
} //if we don't include these params, we will get NaN errors
});
}
});


If the following string is passed, everything works fine:

[{"dataIndex":"firstname","type":"string","value":"hel"}]

Thanks in advance, I've been scratching my head over this for days now, and I'm about to go mad... I'm sure it's something small that I've missed, hopefully you can spot it!

jjshoe
28 Sep 2008, 9:49 PM
thanks so much, I actually needed to do do the on event on the grid, but still, all credit to you!!



Not sure, untested, but maybe something like:



var btn = new Ext.Button({

});

var filterPlugin = new Ext.ux.grid.GridFilters({

});

filterPlugin.on({
filterupdate: {
/**
* Handler for when filters change
* @param {Object} o this plugin
* @param {Object} f filter
*/
fn: function (o, f) {
//get current filters (returns an array)
var curFilters = o.getFilterData();
//enable the button if there are active filters
if (curFilters.length) {
btn.enable();
} else {
btn.disable();
}
}
}
});

irwanex
1 Oct 2008, 5:33 AM
Hi.. im start using this plugin and using java (Struts 2) in server side. What data type can i use in filter param? i'm trying to use array of object and it doesn't work. any one can help me?


package xproject.action;

import java.lang.reflect.Array;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

package xproject.action;

import java.lang.reflect.Array;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import net.sf.json.filters.MappingPropertyFilter;

import org.apache.struts2.ServletActionContext;

import flexjson.JSONSerializer;

import atg.taglib.json.util.JSONArray;

import xproject.base.HibernateSessionFactory;
import xproject.base.XActionSupport;
import xproject.business.MenuItemBO;
import xproject.entity.Menuitems;
import xproject.json.object.GridRecord;
import xproject.util.StaticOb;

public class MenuItemAction extends XActionSupport {

private String action;

private MenuItemBO mibo;

private Object [][][] filter;

@Override
protected void close() throws Exception {
HibernateSessionFactory.closeSession();
mibo = null;
}

@Override
protected String doExecute() throws Exception {
String response = "";
if("init".equals(action)) {
return "init.page";
}else if ("getData".equals(action)) {
List menuitems = mibo.getListMenuItem(start, limit);
JSONArray jArray = new JSONArray();
if(menuitems != null && menuitems.size() > 0) {
Iterator it = menuitems.iterator();
while(it.hasNext()) {
jArray.add((Menuitems)it.next());
}
}
GridRecord gr = new GridRecord();
gr.setRecords(jArray);
gr.setTotal(menuitems.size());
response = new JSONSerializer().include("records").serialize(gr);
}
HttpServletRequest request = ServletActionContext.getRequest();
request.setAttribute("jsonObject", response);
return StaticOb.JSON_RESULT;
}

@Override
protected void doValidate() throws Exception {
// TODO Auto-generated method stub

}

@Override
protected void init() throws Exception {
mibo = new MenuItemBO();

}

public String getAction() {
return action;
}

public void setAction(String action) {
this.action = action;
}

public Object[][][] getFilter() {
return filter;
}

public void setFilter(Object[][][] filter) {
this.filter = filter;
}
}

notjoshing
3 Oct 2008, 5:38 AM
It might be worth adding wild cards to the local text string filtering by altering the validation method:

validateRecord: function(record){
var val = record.get(this.dataIndex),
values = this.menu.getValue();
//Equal comparison
if(values.eq != undefined ) {
var compVal = values.eq;
//Regular expression match
var aCompVal = compVal.split('*');
if( aCompVal.length > 1 ) {//wildcards
compVal = '^'+aCompVal.join('.*')+'$';
var re = new RegExp(compVal,'i');
if( !re.test(val) ) {//no match
return false
}
//Equivalence match
} else if (val.toLowerCase()!=compVal.toLowerCase()) {//no wildcards, no match
return false;
}
}
//Not equal comparison
if(values.ne != undefined ) {
var compVal = values.ne;
//Regular expression match
var aCompVal = compVal.split('*');
if( aCompVal.length > 1 ) {//wildcards
compVal = '^'+aCompVal.join('.*')+'$';
var re = new RegExp(compVal,'i');
if( re.test(val) ) {//match
return false
}
//Equivalence match
} else if (val.toLowerCase()==compVal.toLowerCase()) {//no wildcards, no match
return false;
}
}
return true;
}

Server-side handling of this should be relatively straightforward.

Josh

vmorale4
6 Oct 2008, 10:23 AM
Is it possible to override the default text for the booleanfilter menu? It defaults to 'Yes' and 'No'.

For example, we would like to have a column where the checkItems read: "Warnings" "No Warnings"
*and* another colum with a different text, i.e. "Red" "Blue"

vmorale4
6 Oct 2008, 10:56 AM
OK, fixed it myself, modified the init method in BooleanFilter.js:


init: function(){
var gId = Ext.id();
var trueLabel=this.trueLabel || "Yes";
var falseLabel=this.falseLabel || "No";
this.options = [
new Ext.menu.CheckItem({text: trueLabel, group: gId, checked: this.defaultValue === true}),
new Ext.menu.CheckItem({text: falseLabel, group: gId, checked: this.defaultValue === false})];

this.menu.add(this.options[0], this.options[1]);

for(var i=0; i<this.options.length; i++){
this.options[i].on('click', this.fireUpdate, this);
this.options[i].on('checkchange', this.fireUpdate, this);
}
},

Remy
19 Oct 2008, 10:41 AM
Awesome component, managed to get in running in no time!

Anyone worked on list values (numeric lookups to other table items) which are large? I've got some in my grids which could return hundreds. If anyone has managed to come up with a neat solution any pointers will be welcome. As it is I'm going to treat them like strings and build the DB statement in Classic ASP.

Thanks for sharing, it really is appreciated.

Remy
20 Oct 2008, 3:22 AM
Try calling your instance of Ext.ux.grid.GridFilters.clearFilters() to turn all filters off. This does not clear the configuration information according to the source. Hope this isn't Off Topic but I am trying to achieve the same but I am instantiating my GridFilter Plugin via another plugin (RemoteComponent), this works fine but because I am creating the GridFilter plugin via a JSON response its instantiated like the following:


plugins: new Ext.ux.grid.GridFilters({autoReload:true,local:false,filters:....

According to the documentations, there isn't a way to specify the Component ID which means I can't find it using getCmp() or can I?

I am creating multiple grids with this as a plugin so I can't find it by using the object type (if that's even possible). I know the container so can I search the container for a child object type? I need this functionality for clearing the filters but also associating the pagingToolbar with the gridFilter to reset the pagingToolbar to page 1 on a filter event.

Sorry if this shouldn't be posted here

Remy

mjlecomte
20 Oct 2008, 4:39 AM
I had posted something here:
http://extjs.com/forum/showthread.php?p=238189#post238189
where I'm using GridFilters. I send back filters along with the other column data.

I'm not sure if I get your difficulty here. In your grid class can you just have


initComponent: function () {
this.filters = new Ext.ux.grid.GridFilters({
autoReload:true,
local:false,
filters: []
});
...
}

and then use

this.filters.clearFilters();

Perhaps you can make your own thread and link it to the two other threads (this one and remoteComponent). And there show your complete code to more fully understand, help, etc.

Remy
20 Oct 2008, 7:55 AM
The code is quite large at this point as I have a tabpanel with multiple grids created on the fly with associated plugins create on the fly. I guess I am just trying to figure out how you identify a registered component when you don't know its id but you know its object type and its parent container.

mjlecomte
20 Oct 2008, 9:10 AM
Well, I would still have the class track that for you, or use one of the several "find..." methods in the API. In my experience, when people are asked to post code and they have to trim it down to a small demonstration case, many times the OP will discover the fix on their own. It's even easier to get help if you post a link to a url someone could check a la firebug.

Remy
20 Oct 2008, 10:03 AM
Having had another look around, I think your option of tracking within the class makes sense, does this mean I would have to extend the grid class or can I add a function to the grid class' initComponent event? I need to use xtype for lazy instantiation, does this affect my appraoch? Sorry if those questions appear stupid, i've been using Ext for 4 weeks only as a consumer of widgets and will consider myself a newb for quite some time.

mjlecomte
20 Oct 2008, 10:13 AM
Well, as long as you create your own extension and then register your xtype then you can easily proceed as you have been, you'll just specify your custom xtype that you registered.

This presumes that you've loaded the necessary js files that created this xtype though. If you want to dynamically load the extension class as well than you have a little more work to get that done, but there's some extensions around for that as well. Let me know if you need further description on this point.

So far I'm using an extended class xtype and just sending back configs via the autoGrid philosophy. I have yet to remotely configure any plugins for the grid though (those are preconfigured in the class already).

Are you dynamically specifying the plugins for the component as well?

Remy
20 Oct 2008, 10:33 AM
Thanks MJ, I've been looking around and its about time I got my hands dirty and extend a class! I will register and use xtype as this should be a cleaner way than doing it remotely and also means its available to instantiate locally too.

Yes, I'm creating a chain of remoteComponents using plugins, thanks to Ext I have rewritten half of a client/server app (with far better functionality) in just over a week and the source is frighteningly small. I've been able to re-use my server side code and use plugins to consume the server data. This is a seriously fantastic framework and community.

ddouden
20 Oct 2008, 11:18 AM
I've posted a problem earlier on in another thread.

I'm trying to get the listfilter options to be loaded via a (json) datastore.

See: http://www.extjs.com/forum/showthread.php?t=50188

Could anybody help me.
Thanks

Ddouden

HarryC
24 Oct 2008, 7:29 AM
Hi,

I've just tried this and I'm getting:

Ext.ux.menu.ListMenu is not a constructor
file:///S:/Includes/extUX/GridFilter/ux/grid/filter/ListFilter.js
Line 7

What is ListMenu? I can't find any reference to it anywhere.

Also how does the current version differ from that include in the official Ext 2.2 package?

Thanks.

mjlecomte
24 Oct 2008, 7:55 AM
Hi,

I've just tried this and I'm getting:

Ext.ux.menu.ListMenu is not a constructor
file:///S:/Includes/extUX/GridFilter/ux/grid/filter/ListFilter.js
Line 7

What is ListMenu? I can't find any reference to it anywhere.

Also how does the current version differ from that include in the official Ext 2.2 package?

Thanks.

Have you looked at http://extjs-ux.org/docs/ under GridFilters, ListFilter, ListMenu? There's some discussion of the features under GridFilters heading.

Clever Cutter
24 Oct 2008, 9:31 AM
I'm having an issue with the less_then,greater_then,find, and equals PNGs showing up in the grid filter drop down. I am using extjs desktop along with Zend Framework so my directory structure is quite complex.

Can someone tell me where the paths for these 4 PNGs originates? If I know this I can determine the correct path. I just need the starting point. I've tried all sorts of paths and nothing seems to work.



Ext.ux.menu.RangeMenu.prototype.icons = {
gt: '../../../images/ext_filters/greater_then.png',
lt: '../../../images/ext_filters/less_then.png',
eq: '../../../images/ext_filters/equals.png'
};
Ext.ux.grid.filter.StringFilter.prototype.icon = '../../../images/ext_filters/find.png';

Remy
24 Oct 2008, 9:34 AM
On extraction the filter creates a grid, menu and resources structure. The images should be in the resources directory.

Clever Cutter
24 Oct 2008, 9:42 AM
Thanks I have the images on my server in a public folder. That is not the issue. The code from my post resides in a view file many directories away from where the images are stored. What I need to know is from what point to I reference the images. I've tried simply starting from my docroot like "images/ext_filters/find.png" and have also tried using relative paths from the EditableItem.js location. Nothing seems to work.

Remy
24 Oct 2008, 9:49 AM
Don't know if this helps or not but the icons are defined in styles in the stylesheet, which is located in the same directory as the icons, if you can link to the stylesheet in your remote directory, the icon classes will be relative to the stylesheet.

mjlecomte
24 Oct 2008, 10:21 AM
I think Remy has it right. Check the last bullet on GridFilters description here
http://extjs-ux.org/docs/

The code was refactored to do away with having to configure the prototype.

I don't use Zend, but use another similar (I think) framework, and I don't think using relative urls is typically recommended. You'd want to use some sort of base_url variable to aid with the uri.

If you have Ext's css working you should be able to resolve this issue similarly?

Clever Cutter
24 Oct 2008, 11:56 AM
Thanks to both of you. I was downloading from the UX Repository and it did not include the resources folder. I grabbed the latest from the OP (0.2.8), got the CSS and it's all working. Great plugin, it makes my client VERY happy.

mjlecomte
24 Oct 2008, 12:03 PM
Hmmm. yeah, I guess the repo would need to have a zip as well for the resources, it only gets the js files.

Also note I believe all those resources are already in the ext zip package.

paulwang727
27 Oct 2008, 11:16 AM
When I uncheck a listFilter it still passes the checked value to the back end. Did anyone solve this problem? I saw a previous post where someone put
this.value=[]; in the onLoad function but I was unable to get that to work.

Also, there is a isActivatable function in ListFilter that is never used. Could that possibly be the issue because it never calls setActive?

Treefrog
28 Oct 2008, 11:45 AM
So here is my code based on brian's fix (http://extjs.com/forum/showthread.php?p=207132#post207132) which fixes the selecting text problem in firefox and also fixes the use of the cursor keys inside the filter field. Warning: I didn't/couldn't test it in IE nor Safari, only Firefox 3.

The code goes into the EditableItem.js file (of the gridfilters extension) and should replace if(Ext.isGecko) s.setOverflow('auto');.



["keydown", "keypress"].each(function (eventName) {
this.el.on(eventName, function (e) {
if (e.isNavKeyPress()) {
e.stopPropagation();
}
}, this);
}, this);

if(Ext.isGecko) {
s.setOverflow('auto');
var containerSize = container.getSize();
this.editor.getEl().setStyle('position', 'fixed');
container.setSize(containerSize);
}


Regards,
Steffen

Unfortunately setting the position to 'fixed' on scrollable pages causes the grid and menu to move with page scroll, but not the input text field which stays firmly put.

Setting the position to 'absolute' instead seems to work as expected in FF3.03, the text field stays with the menu, is properly mouse selectable, etc. In FF2 it works in all regards except the infamous FF MIA cursor carat bug appears, which in our opinion beats the floating input box hands down, YMMV.

johnsbrn
28 Oct 2008, 12:00 PM
Here is the fix I used for keyboard arrows. I believe this has the same effect but with less code.

this.el = s;
this.relayEvents(this.editor.el, ["keyup"]);
this.editor.el.swallowEvent(['keypress','keydown']);

I tried the same thing for mouse events, but it didn't seem to work for some reason.


Unfortunately setting the position to 'fixed' on scrollable pages causes the grid and menu to move with page scroll, but not the input text field which stays firmly put.

Setting the position to 'absolute' instead seems to work as expected in FF3.03, the text field stays with the menu, is properly mouse selectable, etc. In FF2 it works in all regards except the infamous FF MIA cursor carat bug appears, which in our opinion beats the floating input box hands down, YMMV.

plima
3 Nov 2008, 12:32 PM
many thanks ambience, really nice plugin!

ralfhammer
7 Nov 2008, 4:58 AM
I have not found anything concerning gridfilter in combination with pagingmemoryproxy:

I've tried combining gridfilter with pagingmemoryproxy (from another user extension). But the filtering is not working when using it with paging memory proxy. Filtering is not done when I enable a String filter. All rows still shown.

Basically I'm using the example "from markup" which uses an XMLReader to extract the data from a markup table. Pagination is working fine with the paginationmemoryproxy.

In Gridfilter I've local set to false, as i want pagingmemoryproxy to do the filtering. Is there any chance to get these extension work together? Anyone had the same problem on this and got it to work?

tfrugia
2 Dec 2008, 5:03 PM
I found the missing link. There is a propery called "local:true" which needs to be set. I guess may be because I am not getting the data from the server and have it locally.




var filters = new Ext.grid.GridFilters({
local: true,
filters:[
{type: 'string', dataIndex: 'abbr'}
]});


Now I have another problem. When I display the paged grid for the first time there are 9 pages of data. After filtering I have only one result and ideally would expect the pagingtoolbar to show that there is only 1 page at the bottom. But it still shows that the there are 9 pages. When I navigate to the rest of the pages they are all blank (good !!). Now how do we need to modify the pagingtoolbar to refresh and show the correct number of pages after the filtering is done?


Regards,
Sam



I have the same issue. Has anyone successfully used the PagingMemoryProxy with GridFilters? I have it working, but when I filter it filters each individual page. If I start with 9 pages of 100 and set a filter, it filters each individual page (so I may have 3 rows on page 1, 10 on page 2, etc).

I know why this is so, but I'm not sure how to fix.



....
reload: function(){
if(this.local){
this.grid.store.clearFilter(true);
this.grid.store.filterBy(this.getRecordFilter());
....


That has to be the issue since the store is paged at that point. Does anyone have a solution for this?

tfrugia
3 Dec 2008, 7:52 PM
I was able to solve the GridFilter + PagingMemoryProxy issue. I'll post my solution once I get it cleaned up, but in the meantime if anyone else runs into this contact me and I'll try and help.

Finity
4 Dec 2008, 6:50 AM
Pet-peeve (probably already mentioned): In your resources folder, you have greater_then.png and less_then.png. These should probably be named greater_than.png and less_than.png.

;-)

Just my two cents.

dmolesky
4 Dec 2008, 7:59 AM
I do not know how to map the parameters being sent to my server. For example, if i was sending a parameter called 'limit' on the client side, my server side c# parameter would be
'string limit'. And it would map to that. But with these filter parameters, the parameter being passed is....filter[0][data][type]string...filter[0][data][value]adf...filter[0][field]project. What would my parameters be to my c# function? What is that data!?!?! Any help would be greatly appreciated! Thanks

VinylFox
4 Dec 2008, 11:49 AM
Im no C# expert, but your just dealing with an array.

http://msdn.microsoft.com/en-us/library/aa288453(VS.71).aspx

nizarsm
5 Dec 2008, 12:02 AM
Can you give me an exemple of server side with C# ?

When I request "filter" what is the type of this var ?

What is the equivalent of this expression : "$filter[$i]['data']['value']" ?

Thanks.

phola
5 Dec 2008, 3:48 AM
Hi,

this bit of C# may get you started (not tested) - we use a modified version of it and it works for us! (credit due here: http://extjs.com/forum/showthread.php?t=37577)


StringBuilder where = new StringBuilder();
{
int filterIndex = 0;
do
{
string filterPrefix = string.Format("filter[{0}]", filterIndex);
string filterField = Request[filterPrefix + "[field]"];
if (string.IsNullOrEmpty(filterField)) break; // TODO: might not be correct. Was : Exit Do


string filterType = Request[filterPrefix + "[data][type]"];
string filterValue = Request[filterPrefix + "[data][value]"];
string comparison = Request[filterPrefix + "[data][comparison]"];
string compareOperator = "=";
if (!string.IsNullOrEmpty(comparison))
{
switch (comparison)
{
case "lt":
compareOperator = "<";
break;
case "gt":
compareOperator = ">";
break;
case "eq":
compareOperator = "=";
break;
}
}
else
{
if (filterType == "string")
{
compareOperator = "Like";
filterValue = "'%" + filterValue + "%'";
}
}

if (filterType == "boolean")
{
filterValue = filterValue == "true" ? "1" : "0";
}

if (filterType == "date")
{
//may need to format to be sql friendly
}

if (where.Length > 0)
{
where.Append(" AND");
}

where.Append(" " + filterField + " " + compareOperator + " " + filterValue);

filterIndex += 1;
}
while (true);
}

nizarsm
5 Dec 2008, 7:02 AM
Thank you very much.. I will try it.

drieraf
5 Dec 2008, 7:39 AM
This filter was perfect but I you can not filter by blank value.

For example in Dates, you can filter before, after, between, but you can't filter by "no date" or "blank date".

In the strings case, I used a * to indicate blank, but in dates, how I can made somthing similar ?

drieraf
19 Dec 2008, 4:15 AM
nobody can help me ?

Thx


This filter was perfect but I you can not filter by blank value.

For example in Dates, you can filter before, after, between, but you can't filter by "no date" or "blank date".

In the strings case, I used a * to indicate blank, but in dates, how I can made somthing similar ?

inptisto
26 Dec 2008, 7:15 AM
Hi tfrugia
I'am using the gridfilterplugin with local paging in gwt-ext.
I wonder if you tell me how you got both of them working appropriately.

thanks

Clever Cutter
29 Dec 2008, 9:47 AM
I searched through this thread but did not find an answer to my question. I have a grid with a column for username. I want to user to be able to search for that username. However, when passing this filter back to the server I want to send the userid instead of the string username. The userid is part of my store and record but not displayed on the grid. Could someone point me in the right direction for solving this issue? I don't want to reinvent the wheel if someone has already solved this. Thanks!

phola
29 Dec 2008, 10:14 AM
This filter was perfect but I you can not filter by blank value.

For example in Dates, you can filter before, after, between, but you can't filter by "no date" or "blank date".

In the strings case, I used a * to indicate blank, but in dates, how I can made somthing similar ?

Hi

I had the same requirement and came up with this (probably needs tidying and more testing....;)

Ext.ux.grid.filter.DateFilterWithBlank = Ext.extend(Ext.ux.grid.filter.Filter, {
dateFormat: 'd/m/Y',
pickerOpts: {},

beforeText: 'Before',
afterText: 'After',
onText: 'On',
blankDateText: 'Blank Date',

init: function(){
var opts = Ext.apply(this.pickerOpts, {
minDate: this.minDate,
maxDate: this.maxDate,
format: this.dateFormat
});
var dates = this.dates = {
'before': new Ext.menu.CheckItem({text: this.beforeText, menu: new Ext.menu.DateMenu(opts)}),
'after': new Ext.menu.CheckItem({text: this.afterText, menu: new Ext.menu.DateMenu(opts)}),
'on': new Ext.menu.CheckItem({text: this.onText, menu: new Ext.menu.DateMenu(opts)}),
'blankdate': new Ext.menu.CheckItem({text: this.blankDateText})};

this.menu.add(dates.before, dates.after, "-", dates.on, "-", dates.blankdate);

for(var key in dates){
var date = dates[key];
if (key!='blankdate')
{
date.menu.on('select', function(date, menuItem, value, picker){
date.setChecked(true);
dates.blankdate.setChecked(false, true);
if(date == dates.on){
dates.before.setChecked(false, true);
dates.after.setChecked(false, true);
} else {
dates.on.setChecked(false, true);

if(date == dates.after && dates.before.menu.picker.value < value)
dates.before.setChecked(false, true);
else if (date == dates.before && dates.after.menu.picker.value > value)
dates.after.setChecked(false, true);
}

this.fireEvent("update", this);
}.createDelegate(this, [date], 0));
}
else //blank dates!!!
{
date.on('checkchange', function(o,c){
date.setChecked(c);
if(date == dates.blankdate){
dates.before.setChecked(false, true);
dates.after.setChecked(false, true);
dates.on.setChecked(false, true);
}
this.fireEvent("update", this);
}, this)
}
date.on('checkchange', function(){
this.setActive(this.isActivatable());
}, this);
};
},

getFieldValue: function(field){
return this.dates[field].menu.picker.getValue();
},

getPicker: function(field){
return this.dates[field].menu.picker;
},

isActivatable: function(){
return this.dates.on.checked || this.dates.after.checked || this.dates.before.checked || this.dates.blankdate.checked;
},

setValue: function(value){
for(var key in this.dates)
if(value[key]){
if (key!='blankdate') this.dates[key].menu.picker.setValue(value[key]);
this.dates[key].setChecked(true);
} else {
this.dates[key].setChecked(false);
}
},

getValue: function(){
var result = {};
for(var key in this.dates)
if(this.dates[key].checked)
if (key!='blankdate')
{result[key] = this.dates[key].menu.picker.getValue();}
else
{result[key] = 'Blank Date';}

return result;
},

serialize: function(){
var args = [];
if(this.dates.before.checked)
args = [{type: 'date', comparison: 'lt', value: this.getFieldValue('before').format(this.dateFormat)}];
if(this.dates.after.checked)
args.push({type: 'date', comparison: 'gt', value: this.getFieldValue('after').format(this.dateFormat)});
if(this.dates.on.checked)
args = {type: 'date', comparison: 'eq', value: this.getFieldValue('on').format(this.dateFormat)};
if(this.dates.blankdate.checked)
args = {type: 'date', comparison: 'eq', value: 'Blank Date'};

this.fireEvent('serialize', args, this);
return args;
},

validateRecord: function(record){
var val = record.get(this.dataIndex).clearTime(true).getTime();

if(this.dates.on.checked && val != this.getFieldValue('on').clearTime(true).getTime())
return false;

if(this.dates.before.checked && val >= this.getFieldValue('before').clearTime(true).getTime())
return false;

if(this.dates.after.checked && val <= this.getFieldValue('after').clearTime(true).getTime())
return false;

return true;
}
});

enterco
1 Jan 2009, 12:17 PM
Hi all!

First I would like to thank you for sharing such useful code. It's nice to see it working into other languages too, and below it's the code needed to localize strings, and a small fix-up for styles/images. Please adapt it to your needs

[PHP]
if (Ext.grid.filter.DateFilter) {
Ext.apply(Ext.grid.filter.DateFilter.prototype, {
dateFormat: 'd.m.Y'
,beforeText: '

mjlecomte
1 Jan 2009, 12:22 PM
I thought you just had to correct the css, not the prototype any longer when dealing with the icons. See discussion here:
http://extjs-ux.org/docs/index.html?class=Ext.ux.grid.GridFilters

enterco
1 Jan 2009, 1:29 PM
I thought you just had to correct the css, not the prototype any longer when dealing with the icons. See discussion here:
http://extjs-ux.org/docs/index.html?class=Ext.ux.grid.GridFilters

I forgot to mention that I've tested with version 0.2.8, available at this thread's first post (http://extjs.com/forum/showthread.php?p=70377#post70377). I see at the link you posted (http://extjs-ux.org/docs/index.html?class=Ext.ux.grid.GridFilters) a newer version. I'll let you know after I'll make a test with 0.2.9.

ScottLoney
6 Jan 2009, 6:15 AM
I am experiencing a problem with the ext-js GridFilters tool. I maintain a website which is multi-lingual, containing both French and English languages. Because of this, my French users periodically have special characters in their names, addresses, etc. I have added a few ext-js GridPanel charts to the site. They work great, but when I use the filter option to search on a special character like

renoye
13 Jan 2009, 12:35 AM
I have read all 68 pages. Several people have pointed the problem out. If you set local: true, remoteSort: true, it only filters one page not the whole record sets. Which part should I change? or should I use BufferedPagingMemoryProxy? Can some on post a solution ? Tfrugia? Please. thx


I have the same issue. Has anyone successfully used the PagingMemoryProxy with GridFilters? I have it working, but when I filter it filters each individual page. If I start with 9 pages of 100 and set a filter, it filters each individual page (so I may have 3 rows on page 1, 10 on page 2, etc).

I know why this is so, but I'm not sure how to fix.



....
reload: function(){
if(this.local){
this.grid.store.clearFilter(true);
this.grid.store.filterBy(this.getRecordFilter());
....


That has to be the issue since the store is paged at that point. Does anyone have a solution for this?

rondinos
13 Jan 2009, 4:44 PM
I really like this plugin but I am just having a little issue. I was wondering if somebody can help me out and give me some suggestions.

I have posted it here:

http://extjs.com/forum/showthread.php?p=273180

renoye
13 Jan 2009, 10:25 PM
ok let me post one solution.
it is very hacking. I am sure others may have better solution; however, since no one has posted any solution here is mine.

I modified Gridfilter.js
on line 69
if(this.local){
this.store.on('load', function(store) {
store.filterBy(this.getRecordFilter());
}, this);
}
it becomes
if(this.local){
/*this.store.on('load', function(store) {
store.filterBy(this.getRecordFilter());
}, this);*/
}
on line 229
if(this.local){
this.grid.store.clearFilter(true);
this.grid.store.filterBy(this.getRecordFilter());
} else {

it becomes
if(this.local){
var store = this.grid.store
store.clearFilter(true);
store.proxy.customFilter = this.getRecordFilter();
store.load({params:{start: 0, limit: 10}});
} else {

basically, it does not allow filtering on the records of current page. Instead, it passes the filter to proxyMemory and use proxyMenory to filter.

It should work.


I have read all 68 pages. Several people have pointed the problem out. If you set local: true, remoteSort: true, it only filters one page not the whole record sets. Which part should I change? or should I use BufferedPagingMemoryProxy? Can some on post a solution ? Tfrugia? Please. thx

schturdark
19 Jan 2009, 7:10 PM
Hi everyone,

I am interested to know how to get the list of activated filters in GridFilters plugin. Some posts suggested to use GridFilters.getState() or grid.filters.getState(). I am not sure how to implement this because when I tried it with this:


var active_filters = grid.filters.getState();

my grid just keep showing the loading box although it has been loaded. I put this line inside
ds.on('datachanged',function(){
var active_filters = grid.filters.getState();
});

in which ds is the datastore. I just want to see the content first.

Could anyone help to enlighten me? Thanks a lot :)

Regards,

Schturdark

basshcm
21 Jan 2009, 9:59 PM
I was curious if you would add a filtersize to the paramaters that are being passed back to the server. Not all server side languages see the filter[].. as an array coming in. I currently override the buildQuery to include it on mine but I am afraid at some point it will come back to bite me.

It would be an easy implementation.



buildQuery: function(filters){
var p = {};
for(var i=0, len=filters.length; i < len; i++){
var f = filters[i];
var root = [this.paramPrefix, '[', i, ']'].join('');
p[root + '[field]'] = f.field;
var dataPrefix = root + '[data]';
for(var key in f.data)
p[[dataPrefix, '[', key, ']'].join('')] = f.data[key];
}
p['FilterSize'] = filters.length;
return p;
},

calavera
24 Jan 2009, 3:57 AM
Hello. I'm having a little problem with the filter plugin: Sometime, the input fields from the filter grid are not in their place. Please see the attached screenshot. I don't know why this is happening. After a page refresh, the fields are in place. But after a while, the scramble again. Anyone, any ideas ?

Thank you very much.

radustefan
1 Feb 2009, 4:23 PM
I forgot to mention that I've tested with version 0.2.8, available at this thread's first post (http://extjs.com/forum/showthread.php?p=70377#post70377). I see at the link you posted (http://extjs-ux.org/docs/index.html?class=Ext.ux.grid.GridFilters) a newer version. I'll let you know after I'll make a test with 0.2.9.

Also 0.2.8 works with css like this:



.x-grid3-hd-row .ux-filtered-column {
font-weight: bold;
border-bottom: 1px solid red;
}

.x-grid3-hd-row .ux-filtered-column .x-grid3-hd-inner {
background-image: url(img/header_bg.gif);
}

.ux-filtered-column .x-grid3-hd-btn {
background-image: url(img/hd-btn.gif);
}

.ux-filtered-column.sort-asc .x-grid3-sort-icon {
background-image: url(img/sort_filtered_asc.gif);
}

.ux-filtered-column.sort-desc .x-grid3-sort-icon {
background-image: url(img/sort_filtered_desc.gif);
}

.ux-gridfilter-text-icon {
background-image: url(img/find.png);
}

/**
* RangeMenu.js Styles
**/
.ux-rangemenu-gt {
background-image: url(img/greater_then.png);
}

.ux-rangemenu-lt {
background-image: url(img/less_then.png);
}

.ux-rangemenu-eq {
background-image: url(img/equals.png);
}

crxtech
3 Feb 2009, 7:53 AM
Has anyone used the filter with two grids on the same page? The filter works great, but if I try to add it to another grid on the same page it doesn't work.

I get the error "hmenu is undefined"...

oliverseitz
4 Feb 2009, 2:55 AM
Hi!

Does anyone have an adaption for oracle database as json return?

my problem is to adapt paging to my oracle request:
I managed it to return json data with limitation for paging, but when showing it I get a wrong count of pages. (for example I have 22 rows to show, want to show 15 records per page, I get a grid with ONE result set of 15 and no paging to show next 7...)

paging is set to 15 and also parameter limit is set to 15.

any ideas?

calavera
4 Feb 2009, 4:01 AM
Hello. I'm having a little problem with the filter plugin: Sometime, the input fields from the filter grid are not in their place. Please see the attached screenshot. I don't know why this is happening. After a page refresh, the fields are in place. But after a while, the scramble again. Anyone, any ideas ?

Thank you very much.

So I guess nobody has this issue. I have inspected the "misplaced" input field with Firebug when it occurred and noticed a style attribute: position: fixed; . If I use the Firebug CSS simulator/editor and I change the element style from position fixed to position absolute, guess what ? It jumps back into its place. So I might be wrong but this could be the solution. The problem is that the input element doesn't take its position:fixed property from any of the CSS file. Instead, it has a property: style="position:fixed;" attached to it. So I need to go deep into the field generation and edit the property there or something. Any ideas for how could I modify there as it doesn't take the position attribute from any of the CSS files ?

I have attached a screenshot. Maybe someone can help. Thank you!

crxtech
4 Feb 2009, 11:25 AM
nevermind

markshih
4 Feb 2009, 2:33 PM
I have a filter grid set to pull data via a JSON store. I wanted to add a button to the toolbar on top that would access the same script that produces the JSON data to output a csv file instead of JSON. So I wanted to know if there was a way to access the current filter state of the grid and just pass it as a dynamically generated url.

Thanks,
Mark

mjlecomte
4 Feb 2009, 2:38 PM
Did you review the API here?
http://extjs-ux.org/docs/index.html?class=Ext.ux.grid.GridFilters

Looks like getFilterData might be what you want.

hendricd
5 Feb 2009, 3:39 PM
Looks like the new menu-item style rules introduced in 2.2.1 might have an impact (at least on version 0.2.8)

Anyone found a solution yet ?

From the 2.2.1 /examples:

mjlecomte
5 Feb 2009, 4:20 PM
http://extjs.com/deploy/dev/examples/grid-filtering/grid-filter.html
This one looks ok for me on IE7.

calavera
5 Feb 2009, 4:23 PM
Well, it looks not right on FF 3.0.6 and absolutely ugly on IE 6. For me. I mean the filter part only.

hendricd
5 Feb 2009, 4:24 PM
Ha, same site on IE7 (for me) yields this:

mjlecomte
5 Feb 2009, 4:29 PM
Ha, same site on IE7 (for me) yields this:

Condor posted a patch for that problem, but I don't understand why it would be different. Let's both hard clear the cache, k?

mjlecomte
5 Feb 2009, 4:30 PM
How about we keep the discussion in this thread?
http://extjs.com/forum/showthread.php?p=284045#post284045

hendricd
5 Feb 2009, 4:34 PM
Condor posted a patch for that problem, but I don't understand why it would be different. Let's both hard clear the cache, k?

Already cleared cache. On 2.2.1, its doing this on both this ux and the Ext flavor :(

hendricd
6 Feb 2009, 7:35 AM
OK, I came up with a replacement for Ext.[ux.]menu.EditableItem that handles layout seperately since the superclass x-menu-item-* styling is so different.

Hello: "x-editable-menu-item"

It is compatible with both flavors (Ext 2.2+ and ux.2.x) of GridFilter and adds tooltip support to its menu items as well. It also maintains the recent enhancements made to the ux.0.2.x version that fixes past keyboard/specialkey handling problems. It also supports the older style icon and/or the newer iconCls config options.


New CSS:


.x-menu .x-editable-menu-item { padding: 1px; overflow:hidden; }

.x-menu .x-editable-menu-item-editor {
display:inline;
padding-left:12px;
}

.x-editable-menu-item-icon {
border: 0 none;
height: 16px;
padding: 0;
vertical-align: top;
width: 16px;
margin: 3px 0 0 0 ;
background-position:center;
}

The styles might need to be tweeked a bit, but now you can, safely. ;)


Ext.ux.menu.EditableItem = Ext.extend(Ext.menu.BaseItem, {
itemCls : "x-editable-menu-item",
hideOnClick: false,

initComponent: function(){

Ext.ux.menu.EditableItem.superclass.initComponent.call(this);
this.addEvents({keyup: true});
this.editor = this.editor || new Ext.form.TextField();
if(this.text)
this.editor.setValue(this.text);
},

onRender: function(container){
this.el = container.createChild( Ext.apply({
cls: this.itemCls,
cn:[{ tag:'img',
src: this.icon||Ext.BLANK_IMAGE_URL,
cls: this.itemCls+'-icon'+(this.iconCls?' '+this.iconCls:'')
},
{tag : 'div' , cls: this.itemCls+'-editor x-form-field'}
]
},!!this.tooltip ? {qtip: this.tooltip} : false ));

Ext.apply(this.config, {width: 125});

Ext.ux.menu.EditableItem.superclass.onRender.apply(this, arguments);

this.editor.render(this.el.child('.'+ this.itemCls+'-editor'));
this.relayEvents(this.editor.el, ["keyup"]);

this.el.swallowEvent(['keydown','keypress']);
Ext.each(["keydown", "keypress"], function (eventName) {
this.el.on(eventName, function (e) {
if (e.isNavKeyPress())
e.stopPropagation();
}, this);
}, this);

},

getValue: function(){
return this.editor.getValue();
},

setValue: function(value){
this.editor.setValue(value);
},

isValid: function(preventMark){
return this.editor.isValid(preventMark);
}
});Tested on FF2/2, IE7 (all strict/non-strict )

mjlecomte
6 Feb 2009, 7:42 AM
@Doug
Shall I post that to the ux repo?
http://extjs-ux.org/docs/index.html?class=Ext.ux.menu.EditableItem

hendricd
6 Feb 2009, 7:46 AM
Probably should after a few more people try it out ;)

extjs_new
9 Feb 2009, 9:04 PM
Hi, I am creating a simple print preview of my editorgrid. I used filtering from the sample ext-2.2/examples/grid-filtering/grid-filter.html.
I was able to retrieve which column is visible. My question is, how can I retrieve the applied filtered on it so that I can send it as params in my Ajax request



var filters = new Ext.grid.GridFilters({
filters:[
{type: 'numeric', dataIndex: 'MembersID'},
{type: 'string', dataIndex: 'FirstName'},
{type: 'string', dataIndex: 'LastName'},
{type: 'numeric', dataIndex: 'genderID'},
{type: 'date', dataIndex: 'Birthday'},
{type: 'boolean', dataIndex: 'active'}
]});//end filters setup


var params = myDataStore.lastOptions.params;

var visibleCols = [];
var columns = myListingEditorGrid.getColumnModel().getColumnsBy(
function (columnConfig, index) {
if (!columnConfig.hidden && columnConfig.dataIndex) visibleCols.push(columnConfig.dataIndex);
});

Ext.Ajax.request({
waitMsg: 'Please Wait...',
url: 'database.php',
params: {
task: "PRINT",
start: params.start,
limit: paging.pageSize, //I wanted to add params that list all the filter applied
dir : params.dir,
sort:params.sort,
columns:Ext.encode(visibleCols),
currentlisting: myDataStore.baseParams.task
})


I wanted to add this params (applied filter)... to my ajax request, considering that the filter is an array


filter[0][data][type] string
filter[0][data][value] John
filter[0][field] FirstName
filter[1][data][comparison] eq
filter[1][data][type] numeric
filter[1][data][value] 1
filter[1][field] genderID
filter[2][data][comparison] eq
filter[2][data][type] date
filter[2][data][value] 02/09/1978
filter[2][field] Birthday


How can I retreive what filters applied in my grid? Thanks

calavera
10 Feb 2009, 4:36 AM
This is just my way of doing it:


var gs=grid.store,sorts={};

if(gs.sortInfo && gs.remoteSort){
var pn = gs.paramNames;
sorts[pn["sort"]] = gs.sortInfo.field;
sorts[pn["dir"]] = gs.sortInfo.direction;
}

var filters_encoded =
Ext.urlEncode(
Ext.apply(grid.filters.buildQuery(grid.filters.getFilterData() ))
);
var sorts_encoded = Ext.urlEncode(
Ext.apply(sorts)
);

This should work for you.

vmorale4
10 Feb 2009, 10:40 AM
Right now I'm very confused between the difference in the ux version and the Ext version in examples :-/:-/

Which is the most current version? (i.e. has the latest bug fixes)

ux: 0.2.9 (Dated September 2008)
Ext 2.2.1 (Which was released February 2009, I'm not aware if the example was updated)

Are they mantained separately?
i.e. if a bug fix is implemented in the ux version, would it also be included in SVN and the next Ext release?

Most importantly, which should I use?

mjlecomte
10 Feb 2009, 12:23 PM
There's probably 3 versions.

One in the ux repo, one posted in first post this thread, and one distributed with Ext SDK.

First post was 0.2.8 I think. I recall making an update for something and updated the ux repo version to 0.2.9. I suspect the Ext SDK is using <= 0.2.8.

If you're using repo you should be able to see the repo history for those files via your svn client I would think.

smartlit
18 Feb 2009, 2:57 AM
When I upgraded my application to new version of Ext, it broke the filter. I read previous discussions, in particular http://extjs.com/forum/showthread.php?t=58854&page=2 where some workarounds are suggested.

My questions is: since I'm still building my application and it will go live in 30/45 days, is a new version of the filter going to be released that solves this issue? If so, I can wait to apply any workaround.

Thanks,

Paul

mjlecomte
18 Feb 2009, 5:34 AM
Probably should after a few more people try it out ;)


There's probably 3 versions.

One in the ux repo, one posted in first post this thread, and one distributed with Ext SDK.

First post was 0.2.8 I think. I recall making an update for something and updated the ux repo version to 0.2.9. I suspect the Ext SDK is using <= 0.2.8.

If you're using repo you should be able to see the repo history for those files via your svn client I would think.

Based on these two posts, my opinion is that the only version currently actively maintained is that in the ux repo. I haven't committed Doug's changes to ux repo because no one else has confirmed the fix works.

cgs1999
20 Feb 2009, 1:19 AM
nice work!thanks for sharing:)

tobiu
21 Feb 2009, 2:32 PM
hi hendricd,

i just tried out your modification of Ext.ux.menu.EditableItem and it looks nice in ff3.


thanks for the update!

kind regards, tobiu

wm003
24 Feb 2009, 6:31 AM
i can also confirm hendricd's modification works great.B)
i tested it under FF3, IE6/7/8, Opera9/10, Chrome/Iron, Safari 3

hendricd
24 Feb 2009, 6:53 AM
The menus used in GridFilters will likely need refactoring again once Ext 3.0 comes out, as Menus are moving to Container-based classes...

cmschick
24 Feb 2009, 12:59 PM
I noticed others throughout the forum having trouble with this and dates in general when using Ext along with MS Ajax so hopefully this saves someone some time.

// Define your grid filter like this. Notice the dateFormat property being set to 'd'
// default is 'm/d/Y'

filters = new Ext.ux.grid.GridFilters({filters:[
{type: 'numeric', dataIndex: 'ID'},
{type: 'date', dateFormat: 'd', dataIndex: 'dateadded'},
{type: 'string', dataIndex: 'filename'},
{type: 'string', dataIndex: 'title'},
{type: 'string', dataIndex: 'updated'},
{type: 'string', dataIndex: 'description'}
]});

:-?

mystix
24 Feb 2009, 6:04 PM
I noticed others throughout the forum having trouble with this and dates in general when using Ext along with MS Ajax so hopefully this saves someone some time.

// Define your grid filter like this. Notice the dateFormat property being set to 'd'
// default is 'm/d/Y'

filters = new Ext.ux.grid.GridFilters({filters:[
{type: 'numeric', dataIndex: 'ID'},
{type: 'date', dateFormat: 'd', dataIndex: 'dateadded'},
{type: 'string', dataIndex: 'filename'},
{type: 'string', dataIndex: 'title'},
{type: 'string', dataIndex: 'updated'},
{type: 'string', dataIndex: 'description'}
]});

:-?


you're kidding? :-?

m$-ajax sends only the day of the month in its date string? :-/
what's the actual date string that gets sent?

cmschick
25 Feb 2009, 12:22 AM
The lower case d indicates the 'ShortDatePattern' in .NET. See. http://authors.aspalliance.com/aspxtreme/aspnet/types/datetimeformatstrings.aspx for reference.

mystix
25 Feb 2009, 12:29 AM
The lower case d indicates the 'ShortDatePattern' in .NET. See. http://authors.aspalliance.com/aspxtreme/aspnet/types/datetimeformatstrings.aspx for reference.

i see... thanks for the link. :)

disclaimer: i'm a java guy. ;)

cmschick
25 Feb 2009, 12:54 AM
Actually this is a much better reference.

http://blogs.msdn.com/kathykam/archive/2006/09/29/.NET-Format-String-102_3A00_-DateTime-Format-String.aspx

I believe there is one caveat to this whole thing. I am using MS Ajax and by doing so the Asp.Net Ajax framework calls are ALWAYS the last items rendered within the page. Because of this MS Ajax's 'dateFormat' function is overriding the Ext function.
Here is the pertinent MS Ajax that may help you glean into the problem.


Date.__typeName = 'Date';
Date.__class = true;
Date._appendPreOrPostMatch = function Date$_appendPreOrPostMatch(preMatch, strBuilder) {
var quoteCount = 0;
var escaped = false;
for (var i = 0, il = preMatch.length; i < il; i++) {
var c = preMatch.charAt(i);
switch(c) {
case '\'':
if (escaped) strBuilder.append("'"); else quoteCount++;
escaped = false;
break;
case '\\':
if (escaped) strBuilder.append("\\");
escaped = !escaped;
break;
default:
strBuilder.append(c);
escaped = false;
break;
}
}
return quoteCount;
}
Date._expandFormat = function Date$_expandFormat(dtf, format) {
if (!format) {
format = "F";
}
if (format.length === 1) {
switch(format) {
case "d":
return dtf.ShortDatePattern;
case "D":
return dtf.LongDatePattern;
case "t":
return dtf.ShortTimePattern;
case "T":
return dtf.LongTimePattern;
case "F":
return dtf.FullDateTimePattern;
case "M": case "m":
return dtf.MonthDayPattern;
case "s":
return dtf.SortableDateTimePattern;
case "Y": case "y":
return dtf.YearMonthPattern;
default:
throw Error.format(Sys.Res.formatInvalidString);
}
}
return format;
}
Date._expandYear = function Date$_expandYear(dtf, year) {
if (year < 100) {
var curr = new Date().getFullYear();
year += curr - (curr % 100);
if (year > dtf.Calendar.TwoDigitYearMax) {
return year - 100;
}
}
return year;
}
Date._getParseRegExp = function Date$_getParseRegExp(dtf, format) {
if (!dtf._parseRegExp) {
dtf._parseRegExp = {};
} else if (dtf._parseRegExp[format]) {
return dtf._parseRegExp[format];
}
var expFormat = Date._expandFormat(dtf, format);
expFormat = expFormat.replace(/([\^\$\.\*\+\?\|\[\]\(\)\{\}])/g, "\\\\$1");
var regexp = new Sys.StringBuilder("^");
var groups = [];
var index = 0;
var quoteCount = 0;
var tokenRegExp = Date._getTokenRegExp();
var match;
while ((match = tokenRegExp.exec(expFormat)) !== null) {
var preMatch = expFormat.slice(index, match.index);
index = tokenRegExp.lastIndex;
quoteCount += Date._appendPreOrPostMatch(preMatch, regexp);
if ((quoteCount % 2) === 1) {
regexp.append(match[0]);
continue;
}
switch(match[0]) {
case 'dddd': case 'ddd':
case 'MMMM': case 'MMM':
regexp.append("(\\D+)");
break;
case 'tt': case 't':
regexp.append("(\\D*)");
break;
case 'yyyy':
regexp.append("(\\d{4})");
break;
case 'fff':
regexp.append("(\\d{3})");
break;
case 'ff':
regexp.append("(\\d{2})");
break;
case 'f':
regexp.append("(\\d)");
break;
case 'dd': case 'd':
case 'MM': case 'M':
case 'yy': case 'y':
case 'HH': case 'H':
case 'hh': case 'h':
case 'mm': case 'm':
case 'ss': case 's':
regexp.append("(\\d\\d?)");
break;
case 'zzz':
regexp.append("([+-]?\\d\\d?:\\d{2})");
break;
case 'zz': case 'z':
regexp.append("([+-]?\\d\\d?)");
break;
}
Array.add(groups, match[0]);
}
Date._appendPreOrPostMatch(expFormat.slice(index), regexp);
regexp.append("$");
var regexpStr = regexp.toString().replace(/\s+/g, "\\s+");
var parseRegExp = {'regExp': regexpStr, 'groups': groups};
dtf._parseRegExp[format] = parseRegExp;
return parseRegExp;
}
Date._getTokenRegExp = function Date$_getTokenRegExp() {
return /dddd|ddd|dd|d|MMMM|MMM|MM|M|yyyy|yy|y|hh|h|HH|H|mm|m|ss|s|tt|t|fff|ff|f|zzz|zz|z/g;
}
Date.parseLocale = function Date$parseLocale(value, formats) {
/// <param name="value" type="String"></param>
/// <param name="formats" parameterArray="true" optional="true" mayBeNull="true"></param>
/// <returns type="Date"></returns>
var e = Function._validateParams(arguments, [
{name: "value", type: String},
{name: "formats", mayBeNull: true, optional: true, parameterArray: true}
]);
if (e) throw e;
return Date._parse(value, Sys.CultureInfo.CurrentCulture, arguments);
}
Date.parseInvariant = function Date$parseInvariant(value, formats) {
/// <param name="value" type="String"></param>
/// <param name="formats" parameterArray="true" optional="true" mayBeNull="true"></param>
/// <returns type="Date"></returns>
var e = Function._validateParams(arguments, [
{name: "value", type: String},
{name: "formats", mayBeNull: true, optional: true, parameterArray: true}
]);
if (e) throw e;
return Date._parse(value, Sys.CultureInfo.InvariantCulture, arguments);
}
Date._parse = function Date$_parse(value, cultureInfo, args) {
var custom = false;
for (var i = 1, il = args.length; i < il; i++) {
var format = args[i];
if (format) {
custom = true;
var date = Date._parseExact(value, format, cultureInfo);
if (date) return date;
}
}
if (! custom) {
var formats = cultureInfo._getDateTimeFormats();
for (var i = 0, il = formats.length; i < il; i++) {
var date = Date._parseExact(value, formats[i], cultureInfo);
if (date) return date;
}
}
return null;
}
Date._parseExact = function Date$_parseExact(value, format, cultureInfo) {
value = value.trim();
var dtf = cultureInfo.dateTimeFormat;
var parseInfo = Date._getParseRegExp(dtf, format);
var match = new RegExp(parseInfo.regExp).exec(value);
if (match !== null) {
var groups = parseInfo.groups;
var year = null, month = null, date = null, weekDay = null;
var hour = 0, min = 0, sec = 0, msec = 0, tzMinOffset = null;
var pmHour = false;
for (var j = 0, jl = groups.length; j < jl; j++) {
var matchGroup = match[j + 1];
if (matchGroup) {
switch(groups[j]) {
case 'dd': case 'd':
date = Date._parseInt(matchGroup);
if ((date < 1) || (date > 31)) return null;
break;
case 'MMMM':
month = cultureInfo._getMonthIndex(matchGroup);
if ((month < 0) || (month > 11)) return null;
break;
case 'MMM':
month = cultureInfo._getAbbrMonthIndex(matchGroup);
if ((month < 0) || (month > 11)) return null;
break;
case 'M': case 'MM':
var month = Date._parseInt(matchGroup) - 1;
if ((month < 0) || (month > 11)) return null;
break;
case 'y': case 'yy':
year = Date._expandYear(dtf, Date._parseInt(matchGroup));
if ((year < 0) || (year > 9999)) return null;
break;
case 'yyyy':
year = Date._parseInt(matchGroup);
if ((year < 0) || (year > 9999)) return null;
break;
case 'h': case 'hh':
hour = Date._parseInt(matchGroup);
if (hour === 12) hour = 0;
if ((hour < 0) || (hour > 11)) return null;
break;
case 'H': case 'HH':
hour = Date._parseInt(matchGroup);
if ((hour < 0) || (hour > 23)) return null;
break;
case 'm': case 'mm':
min = Date._parseInt(matchGroup);
if ((min < 0) || (min > 59)) return null;
break;
case 's': case 'ss':
sec = Date._parseInt(matchGroup);
if ((sec < 0) || (sec > 59)) return null;
break;
case 'tt': case 't':
var upperToken = matchGroup.toUpperCase();
pmHour = (upperToken === dtf.PMDesignator.toUpperCase());
if (!pmHour && (upperToken !== dtf.AMDesignator.toUpperCase())) return null;
break;
case 'f':
msec = Date._parseInt(matchGroup) * 100;
if ((msec < 0) || (msec > 999)) return null;
break;
case 'ff':
msec = Date._parseInt(matchGroup) * 10;
if ((msec < 0) || (msec > 999)) return null;
break;
case 'fff':
msec = Date._parseInt(matchGroup);
if ((msec < 0) || (msec > 999)) return null;
break;
case 'dddd':
weekDay = cultureInfo._getDayIndex(matchGroup);
if ((weekDay < 0) || (weekDay > 6)) return null;
break;
case 'ddd':
weekDay = cultureInfo._getAbbrDayIndex(matchGroup);
if ((weekDay < 0) || (weekDay > 6)) return null;
break;
case 'zzz':
var offsets = matchGroup.split(/:/);
if (offsets.length !== 2) return null;
var hourOffset = Date._parseInt(offsets[0]);
if ((hourOffset < -12) || (hourOffset > 13)) return null;
var minOffset = Date._parseInt(offsets[1]);
if ((minOffset < 0) || (minOffset > 59)) return null;
tzMinOffset = (hourOffset * 60) + (matchGroup.startsWith('-')? -minOffset : minOffset);
break;
case 'z': case 'zz':
var hourOffset = Date._parseInt(matchGroup);
if ((hourOffset < -12) || (hourOffset > 13)) return null;
tzMinOffset = hourOffset * 60;
break;
}
}
}
var result = new Date();
if (year === null) {
year = result.getFullYear();
}
if (month === null) {
month = result.getMonth();
}
if (date === null) {
date = result.getDate();
}
result.setFullYear(year, month, date);
if (result.getDate() !== date) return null;
if ((weekDay !== null) && (result.getDay() !== weekDay)) {
return null;
}
if (pmHour && (hour < 12)) {
hour += 12;
}
result.setHours(hour, min, sec, msec);
if (tzMinOffset !== null) {
var adjustedMin = result.getMinutes() - (tzMinOffset + result.getTimezoneOffset());
result.setHours(result.getHours() + parseInt(adjustedMin / 60), adjustedMin % 60);
}
return result;
}
}
Date._parseInt = function Date$_parseInt(value) {
return parseInt(value.replace(/^[\s0]+(\d+)$/, "$1"));
}
Date.prototype.format = function Date$format(format) {
/// <param name="format" type="String"></param>
/// <returns type="String"></returns>
var e = Function._validateParams(arguments, [
{name: "format", type: String}
]);
if (e) throw e;
return this._toFormattedString(format, Sys.CultureInfo.InvariantCulture);
}
Date.prototype.localeFormat = function Date$localeFormat(format) {
/// <param name="format" type="String"></param>
/// <returns type="String"></returns>
var e = Function._validateParams(arguments, [
{name: "format", type: String}
]);
if (e) throw e;
return this._toFormattedString(format, Sys.CultureInfo.CurrentCulture);
}
Date.prototype._toFormattedString = function Date$_toFormattedString(format, cultureInfo) {
if (!format || (format.length === 0) || (format === 'i')) {
if (cultureInfo && (cultureInfo.name.length > 0)) {
return this.toLocaleString();
} else {
return this.toString();
}
}
var dtf = cultureInfo.dateTimeFormat;
format = Date._expandFormat(dtf, format);
var ret = new Sys.StringBuilder();
var hour;
function addLeadingZero(num) {
if (num < 10) {
return '0' + num;
}
return num.toString();
}
function addLeadingZeros(num) {
if (num < 10) {
return '00' + num;
}
if (num < 100) {
return '0' + num;
}
return num.toString();
}
var quoteCount = 0;
var tokenRegExp = Date._getTokenRegExp();
for (; ;) {
var index = tokenRegExp.lastIndex;
var ar = tokenRegExp.exec(format);
var preMatch = format.slice(index, ar? ar.index : format.length);
quoteCount += Date._appendPreOrPostMatch(preMatch, ret);
if (!ar) break;
if ((quoteCount % 2) === 1) {
ret.append(ar[0]);
continue;
}
switch(ar[0]) {
case "dddd":
ret.append(dtf.DayNames[this.getDay()]);
break;
case "ddd":
ret.append(dtf.AbbreviatedDayNames[this.getDay()]);
break;
case "dd":
ret.append(addLeadingZero(this.getDate()));
break;
case "d":
ret.append(this.getDate());
break;
case "MMMM":
ret.append(dtf.MonthNames[this.getMonth()]);
break;
case "MMM":
ret.append(dtf.AbbreviatedMonthNames[this.getMonth()]);
break;
case "MM":
ret.append(addLeadingZero(this.getMonth() + 1));
break;
case "M":
ret.append(this.getMonth() + 1);
break;
case "yyyy":
ret.append(this.getFullYear());
break;
case "yy":
ret.append(addLeadingZero(this.getFullYear() % 100));
break;
case "y":
ret.append(this.getFullYear() % 100);
break;
case "hh":
hour = this.getHours() % 12;
if (hour === 0) hour = 12;
ret.append(addLeadingZero(hour));
break;
case "h":
hour = this.getHours() % 12;
if (hour === 0) hour = 12;
ret.append(hour);
break;
case "HH":
ret.append(addLeadingZero(this.getHours()));
break;
case "H":
ret.append(this.getHours());
break;
case "mm":
ret.append(addLeadingZero(this.getMinutes()));
break;
case "m":
ret.append(this.getMinutes());
break;
case "ss":
ret.append(addLeadingZero(this.getSeconds()));
break;
case "s":
ret.append(this.getSeconds());
break;
case "tt":
ret.append((this.getHours() < 12)? dtf.AMDesignator : dtf.PMDesignator);
break;
case "t":
ret.append(((this.getHours() < 12)? dtf.AMDesignator : dtf.PMDesignator).charAt(0));
break;
case "f":
ret.append(addLeadingZeros(this.getMilliseconds()).charAt(0));
break;
case "ff":
ret.append(addLeadingZeros(this.getMilliseconds()).substr(0, 2));
break;
case "fff":
ret.append(addLeadingZeros(this.getMilliseconds()));
break;
case "z":
hour = this.getTimezoneOffset() / 60;
ret.append(((hour >= 0)? '+' : '-') + Math.floor(Math.abs(hour)));
break;
case "zz":
hour = this.getTimezoneOffset() / 60;
ret.append(((hour >= 0)? '+' : '-') + addLeadingZero(Math.floor(Math.abs(hour))));
break;
case "zzz":
hour = this.getTimezoneOffset() / 60;
ret.append(((hour >= 0)? '+' : '-') + addLeadingZero(Math.floor(Math.abs(hour))) + dtf.TimeSeparator + addLeadingZero(Math.abs(this.getTimezoneOffset() % 60)));
break;
}
}
return ret.toString();
}

ostghost
28 Feb 2009, 9:11 AM
hi,

have such column definition



, {
id: 'card_type',
header: 'Kategorie',
width: 80,
dataIndex: 'card_type',
renderer: function(data){
record = storeProductType.getById(data);
if (record) {
return record.data.label_text;
}
else {
return '[nepřeloženo] ' + data;
}
},
hidden: true,
hideable: false
}


filter definition



, {
type: 'list',
dataIndex: 'card_type',
labelField: 'label_text',
store: storeProductType,
phpMode: true
}


store definiton



storeProductType = new Ext.data.Store({
storeId: 'storeEvidenceProductType',
proxy: new Ext.data.HttpProxy({
url: baseUrl + '/administration/index/get-status/'
}),
reader: new Ext.data.JsonReader({
root: 'data',
id: 'status_id'
}, [{
name: 'status_id'
}, {
name: 'label_text'
}]),
baseParams: {
status: 'product_types',
sort: 'label_text'
},
listeners: {
load: function(){
storeProductType.filter('status_id', /10/)
console.log('done');
}
}
});


rows in grid are translated with data from store. such data are on store load filtered till yet ok. but i want also to have panel in list filter cutted off some items.

this is for grid done by storeProductType.filter('status_id', /10/)
but list filter doesn´t reflect this operation even console log isn´t fired


tried to set filter properties loaded true, loadOnShow false but it seems that filter is using store without any changes.

some ideas?

thanks

gxt
3 Mar 2009, 1:36 PM
Hi,

Sorry if this has been answered already but I searched the forum and couldn't find a solution. How does one set the filters via javascript?

I was hoping for something like filter.setFilter(dataIndex,'filterByThis');

Thanks

mjlecomte
3 Mar 2009, 1:54 PM
What about addFilter (http://extjs-ux.org/docs/index.html?class=Ext.ux.grid.GridFilters&member=addFilter)?

gxt
3 Mar 2009, 2:16 PM
Thanks that works but is there a way to update the value only instead of updating the entire config?

So right now this is what I have but there's a lot of copy and paste involved and if I want to change something in the config (say add an option) I have to add it in multiple places



39 var completed = new Ext.Action({
40 text: 'Completed',
41 handler: function(){
42 filters.clearFilter();
43 filters.addFilter({
44 type: 'list',
45 dataIndex: 'status',
46 phpMode: true,
47 options: ['Submitted', 'Completed', 'Picked Up','Uploaded'],
48 value: 'Completed'
49 });
50 store.sort('submitted_date','DESC');
51 store.reload();
52 },
53 });
54
55 var submitted = new Ext.Action({
56 text: 'Uploaded',
57 handler: function(){
58 filters.clearFilter();
59 filters.addFilter({
60 type: 'list',
61 dataIndex: 'status',
62 phpMode: true,
63 options: ['Submitted', 'Completed', 'Picked Up','Uploaded'],
64 value: 'submitted'
65 });
66 store.sort('submitted_date','DESC');
67 store.reload();
68 },
69 });

alconeijr
4 Mar 2009, 3:20 PM
Will be discontinued Grid Filters from Extjs?
The last Ext release are not working fine.
http://www.extjs.com/deploy/dev/examples/grid-filtering/grid-filter.html

mjlecomte
4 Mar 2009, 6:13 PM
I don't know if anyone knows what "not work fine" means specifically. But at any rate, this is an user extension, it's not part of the ext base code (albeit it has been included with the delivered examples).

alconeijr
5 Mar 2009, 4:10 AM
I don't know if anyone knows what "not work fine" means specifically. But at any rate, this is an user extension, it's not part of the ext base code (albeit it has been included with the delivered examples).

mjlecomte,

Excuse me for my poor english. I thought that the filters would become part of Extjs because of the examples. Please disregard my comment then.
What I'm trying to say is that there is a bug from the new release of Extjs and GridFilters.
Accessing the example it is apparent that the properties of the filter icons are messy. This is the problem that I call.

Thank you,

Alcionei

mjlecomte
5 Mar 2009, 8:59 AM
please scan backwards through this thread, there are posts about this already.

alconeijr
6 Mar 2009, 1:43 PM
please scan backwards through this thread, there are posts about this already.

Ok. Thank you!

rickystra
10 Mar 2009, 10:23 AM
i have a problem with filter type: list.

layout.js



var listReading = new Ext.data.Store({
id: 'idid',
proxy: new Ext.data.HttpProxy({
url: 'ext-js/grid-filtering/filter-list.php', // File to connect to
method: 'POST'
}),
baseParams:{task: "LISTING"}, // this parameter asks for listing
reader: new Ext.data.JsonReader({
// we tell the datastore where to get his data from
root: 'data',
totalProperty: 'total',
id: 'id',
fields:[
{name: 'es_2'},
]
}),

});
var filters = new Ext.grid.GridFilters({
filters:[
{type: 'numeric', dataIndex: 'RATA'},
{type: 'date', dataIndex: 'DAL'},
{type: 'date', dataIndex: 'AL'},
{type: 'string', dataIndex: 'SCHEDA'},
{
type: 'list',
dataIndex: 'CODICE_UBICAZIONE',
store: listReading,
labelField:'es_2',

phpMode: true
}
]});


this is the response (firebug) onMouseOver (filter)

{"total":"1","data":[{"0":"GB212168357I","es_2":"GB212168357I"}]}

but if i selected an option, this is the POST for filtering the grid:

dir ASC

filter[0][data][type] list

filter[0][data][value] 1004 // THIS IS THE PROBLEM, WHY VALUE IS 1004 AND NOT GB212168357I ??:-/:-/:-/

filter[0][field] CODICE_UBICAZIONE

limit 40

sort RATA

start 0

rickystra
11 Mar 2009, 12:58 PM
up

elDub
12 Mar 2009, 7:43 AM
My grids have an id set on them so that column positioning and sizing is kept. I'd like to use GridFilters without saving the state so that every time I return to the page the filters are clear, however it seems that if the grid has an id (and therefore a stateId), this isn't working. Is there a way to do this?

leopku
17 Mar 2009, 11:28 PM
i wanna filter data in grid by clicking a button, as same as user click 'date before ...' and 'date after ...'
codes like below.
the problem is: after store reload, a default filter string 'q []' was posted to the server, it override the result of first post( there are two post after clicking).


var weekmenu = new Ext.menu.DateMenu({
handler: function(dp, date){
var weekFilters = [];
var weeknum = date.format('W');
var firstDayOfWeek = null;
var lastDayOfWeek = null;
for (var i=0; i<6; i++){
if (weeknum == date.add(Date.DAY, -i). getWeekOfYear()){
firstDayOfWeek = date.add(Date.DAY, -i);
}
if (weeknum == date.add(Date.DAY, i).getWeekOfYear()){
lastDayOfWeek = date.add(Date.DAY, i);
}
}
var firstDayFilter = {};
firstDayFilter['field'] = 'date';
firstDayFilter['data'] = {};
firstDayFilter['data']['comparison'] = 'gt';
firstDayFilter['data']['value'] = firstDayOfWeek.format('m/d/Y');
weekFilters.push(firstDayFilter);

var lastDayFilter = {};
lastDayFilter['field'] = 'date';
lastDayFilter['data'] = {}
lastDayFilter['data']['comparison'] = 'lt';
lastDayFilter['data']['value'] = lastDayOfWeek.format('m/d/Y');
weekFilters.push(lastDayFilter);

Ext.apply(grid.filters.buildQuery(weekFilters));

Ext.Ajax.request({
url: '/tracks/json',
method: 'POST',
success: function(result, request) {
if (grid.toolbar){}
gStore.reload();
},
params: {
q: Ext.encode(weekFilters)
}
})

watrboy00
25 Mar 2009, 11:35 PM
Ext JS v2.2.1 CSS seems to break the editor's (Ext.form.TextField) width for Ext.ux.menu.EditableItem. In trying to narrow down the cause I tried v2.1 resources with v2.2.1 code base and the issue is somewhat fixed so I would assume it would be a styling issue in the CSS somewhere. Looking in FireBug I cannot for the life of me (as of now) figure out what is causing it.

You can see the differences viewing http://www.extjs.com/deploy/dev/examples/grid-filtering/grid-filter.html (uses v2.2.1) and http://ccinct.com/lab/filter-grid/ (uses v2.1)

See my next post.

watrboy00
25 Mar 2009, 11:50 PM
Needs this override...


.x-menu-item-icon {
left:0;
margin:1px 8px 0 0;
position:relative;
}

mjlecomte
26 Mar 2009, 4:30 AM
Needs this override...


.x-menu-item-icon {
left:0;
margin:1px 8px 0 0;
position:relative;
}

http://extjs.com/forum/showthread.php?p=284046#post284046 ... and afterwards...

quen567
30 Mar 2009, 5:10 AM
Hi
I got a problem in combination with the Summary and Filter Plugin.
When both are active I get the NaN in the Paging Bar as described earlier in this thread.
If only one plugin is active the Paging Bar works fine.

Anyone got an Idea?

calavera
30 Mar 2009, 2:01 PM
Hi
I got a problem in combination with the Summary and Filter Plugin.
When both are active I get the NaN in the Paging Bar as described earlier in this thread.
If only one plugin is active the Paging Bar works fine.

Anyone got an Idea?
Hello. How do you set up your plugins ?

quen567
30 Mar 2009, 10:33 PM
Ext.onReady(function(){
Ext.menu.RangeMenu.prototype.icons = {
gt: '/html/js/ext-2.2/gridfilter/img/greater_then.png',
lt: '/html/js/ext-2.2/gridfilter/img/less_then.png',
eq: '/html/js/ext-2.2/gridfilter/img/equals.png'
};
Ext.grid.filter.StringFilter.prototype.icon = '/html/js/ext-2.2/gridfilter/img/find.png';
});


ZahlungszielGrid = Ext.extend(Ext.grid.GridPanel,{

moduleName: "Zahlungsziel",
loadMask:true,
stripeRows: true,

initComponent: function(){

var sm = new Ext.grid.RowSelectionModel();
var summary = new Ext.ux.grid.GridSummary();
var filters = new Ext.grid.GridFilters({
filters:[
//{type: 'string', dataIndex: 'ID'},
{type: 'date', dataIndex: 'Zieldatum'},
{type: 'boolean', dataIndex: 'Einzugsermaechtigung'},
{type: 'boolean', dataIndex: 'Bezahlt'},
{
type: 'list',
dataIndex: 'Mahnungsstufe',
options: ['1', '2', '3', '4'],
phpMode: true
},
{type: 'date', dataIndex: 'DatumFrist'}
]});

Ext.applyIf(this,
{

viewConfig: {
forceFit: true
},
store: app.getModule(this.moduleName).getStore(),
columns: [
{ header: "ID", dataIndex:'ID', sortable: true, width: 65},
{ header: "fällig am", dataIndex: 'Zieldatum', sortable: true, width: 80,
renderer: function(v){
return app.util.date.formatToGerman(v);
}
},
{ header: "Teilnehmer", dataIndex: 'PersonID' },
{ header: "Name", dataIndex: 'Name'},
{ header: "Rate", dataIndex: 'Rate' , sortable: true, summaryType:'sum'},
{ header: "Restbetrag", dataIndex: 'Restbetrag', sortable: true, summaryType:'sum' },
{ header: "Mahnung Rest", dataIndex: 'MArest', sortable: true, summaryType:'sum'},
{ header: "Bezahlt", dataIndex: 'Bezahlt' },
{ header: "Mahnstufe", dataIndex: 'Mahnungsstufe'},
{ header: "Mahngebühr", dataIndex: 'mahngebuehr' },
{ header: "Mahnung fällig am", dataIndex: 'DatumFrist', sortable: true, width: 120,
renderer: function(v){
return app.util.date.formatToGerman(v);
}
},
{ header: "Einzugserm.", dataIndex: 'Einzugsermaechtigung' },
{ header: "Kurs", dataIndex: 'coursedateID' }
],
sm: sm,
plugins: [filters, summary]

});


var bbar = new Ext.PagingToolbar({
store: this.store,
emptyMsg: "No topics to display",
pageSize: 40
});
this.bbar = bbar;
}

});
Ext.reg('ZahlungszielGrid', ZahlungszielGrid);This is how I set it up.
I already tryed to load the plugins in the PagingBar. The filters work there but not the summary. If I load the summary right after the sm and the filters in the PagingBar only the summary plugin is loaded.

Bucs
31 Mar 2009, 5:23 AM
Hello, trying to get cool GridFilter plugin to work. Noticing a lot of inconsistencies in code versions btw UX Rep and G.F. Forum thread...have now taken what appears to be latest 2.9 from UX Rep and implemented. I have also grabbed the latest EditableItem, RangeMenu, and ListMenu from the UX Rep as well.

List and String filtering appear to be working fine, but Numeric, Boolean and Date are all producing same error on line 350 of GridFilters.js


this.getFilterClass(config.type) is not a constructor

Not sure what I am missing...my filters are from the 2.8 zip package on the forum thread since that is the only place I have seen them.

Any help appreciated. Thanks...

tobiu
31 Mar 2009, 11:24 AM
hi together,

has anyone tried to code a timeFieldFilter yet?
if ext.menu had TimeItem / TimeMenu, it would be much easier...

i started to modify NumericFilter, but am not satisfied with the results yet.

so, if anyone else is working on it or has some time for this, please let me know.

kind regards,
tobiu

razvanioan
4 Apr 2009, 8:29 AM
First of all, I want to thank for this very nice plugin, good work !

Second, I don't know if it was explained in this long thread or not (I've searched & read almost all this day), I could not find a solution on how to pass gridFilters through an Ext.Ajax.request along with other parameters (for a search & replace form on the filtered data).

I mention that I'm parsing the filters for the gridFiltering & search-replace on filtered data in the same server-side proxy (PHP).

I've discovered myself in GridFilters.js & found out on this thread that I had to use grid.filters.buildQuery(grid.filters.getFilterData()), but I was doing it wrong:



...
params: {
...
,filter: grid.filters.buildQuery(grid.filters.getFilterData())
}
...


Finally, the working solution was:



...
params: Ext.apply({
...
}, grid.filters.buildQuery(grid.filters.getFilterData()))
...


maybe there's somebody else who needs this.

axpa
6 Apr 2009, 3:04 AM
SOLVED: This happends only with the ext-all-debug file, change to production mode and it works... SOLVED


Hi,
First of all, thanx for a great plugin.

I have stumbled upon a weird issue on Safari, I get the result in the attached image, that is the dates/months dont get displayed. I can see Safari complaining about Maximum call stack size exceeded.

The code works on FF3/IE7 but doesnt work on Safari 3.2.1 (b 5525.27.1) on mac or Safari on PC.

Has anyone seen this before? arya009 did you have the same issue?

I'm using Ext 2.2.1.

I have seen threads about Maximum call stack size and Safari when it comes to nesting, but this is not the case, it happends when using the simple example file like the one on supplied as demo. I have attached the gridfilter.txt file, rename to .html and redirect to your source and test with Safari. You should see the bug.

MehdiSZ
6 Apr 2009, 3:29 AM
I have tried searching but have been unable to find any documentation for Grid Filter. Is there any documentation for this Plugin?

Thanks
Mehdi

razvanioan
6 Apr 2009, 10:50 AM
In here (http://extjs-ux.org/docs/) you can find documentation for all user extensions, made exactly like API documentation of ExtJS framework itself.

Direct link to GridFilter (http://extjs-ux.org/docs/index.html?class=Ext.ux.grid.GridFilters).

Happy coding.

MehdiSZ
6 Apr 2009, 11:05 AM
Thank you very much razvanioan. Much appreciated.

mjlecomte
6 Apr 2009, 11:40 AM
In here (http://extjs-ux.org/docs/) you can find documentation for all user extensions, made exactly like API documentation of ExtJS framework itself.

Direct link to GridFilter (http://extjs-ux.org/docs/index.html?class=Ext.ux.grid.GridFilters).

Happy coding.

It is not *all* extensions, just those that people have posted to the repository.

zyon
6 Apr 2009, 11:41 AM
Can someone pls tell me how to reset the filter? I read here in forums and tried
Ext.ux.grid.GridFilters.clearFilters();
but it gives an error(error: is not a function).
Thx.

tobiu
6 Apr 2009, 12:22 PM
hi zyon,

you should not try that method on a class / prototype,
but on your required instance.

example:



myGrid.filters.clearFilters();


kind regards,
tobiu

zyon
7 Apr 2009, 12:31 AM
Yes it works like this.
Thx.

Illiarian
8 Apr 2009, 6:51 AM
Hi. A friend of mine has created a combo filter for the Grid Filter plugin. It's sort of a proof of concept, but it works

Please, give it a try. Suggestions and improvements are more than welcome

ComboFilter.js


Ext.ux.grid.filter.ComboFilter = Ext.extend(Ext.ux.grid.filter.Filter, {
phpMode: false,

init: function(config) {
this.dt = new Ext.util.DelayedTask(this.fireUpdate, this);

this.menu = new Ext.ux.menu.ComboMenu(config, this);
this.menu.on('onCheckChage', this.onCheckChange, this);
},

onCheckChange: function() {
this.dt.delay(this.updateBuffer);
},

setValue: function(value) {
this.menu.setSelected(value);

this.fireEvent("update", this);
},

getValue: function() {
return this.menu.getSelected();
},

serialize: function() {
var args = {type: 'list', value: this.getValue()};
this.fireEvent('serialize', args, this);

return args;
}

});


ComboMenu.js


Ext.namespace("Ext.ux.menu");
Ext.ux.menu.ComboMenu = function(cfg, filter){
this.addEvents('checkchanged');
this.filter = filter;
Ext.ux.menu.ComboMenu.superclass.constructor.call(this, cfg = cfg || {});

if(!cfg.store && cfg.options) {
var options = [];
for(var i=0, len=cfg.options.length; i<len; i++) {
var value = cfg.options[i];
switch(Ext.type(value)){
case 'array': options.push(value); break;
case 'object': options.push([value.id, value[this.displayField]]); break;
case 'string': options.push([value, value]); break;
}
}

this.store = new Ext.data.Store({
reader: new Ext.data.ArrayReader({id: 0}, ['id', this.displayField]),
data: options,
listeners: {
'load': this.onLoad,
scope: this
}
});
this.loaded = true;
} else {
this.add({text: this.loadingText, iconCls: 'loading-indicator'});
this.store.on('load', this.onLoad, this);
}
};

Ext.extend(Ext.ux.menu.ComboMenu, Ext.menu.Menu, {
displayField: 'name',
loadingText: 'Loading...',
loadOnShow: true,
selected: '',
defaultItem: 'no filter', // value 0
emptyText: 'no filter',
valueNotFoundText: 'no filter',

show: function() {
var lastArgs = null;
return function(){
if(arguments.length == 0){
Ext.ux.menu.ComboMenu.superclass.show.apply(this, lastArgs);
} else {
lastArgs = arguments;
if(this.loadOnShow && !this.loaded) this.store.load();
Ext.ux.menu.ComboMenu.superclass.show.apply(this, arguments);
}
};
}(),

onLoad: function(store, records) {
var visible = this.isVisible();
this.hide(false);

this.removeAll();

var storeRecord = Ext.data.Record.create([ { name: 'id' }, { name: this.displayField } ]);
rec = new storeRecord({ id: 0, name: this.defaultItem }); // field name from this.displayField ???
store.add(rec);

item = new Ext.menu.Adapter(
new Ext.form.ComboBox({
store: store,
displayField: this.displayField,
valueField: 'id',
emptyText: 'no filter',
valueNotFoundText: 'no filter',
disableKeyFilter: 'true',
editable: false,
triggerAction: 'all',
selectOnFocus: true,
typeAhead: true,
mode: 'local'
}),
{ hideOnClick: false });

item.component.on('select', this.checkChange, this);
this.combo = this.add(item);

this.loaded = true;

if(visible)
this.show();

this.fireEvent('load', this, records);
},

setSelected: function(value) {
this.combo.component.setValue(value);
},

checkChange: function(item, checked) {
this.selected = this.combo.component.getValue();

this.fireEvent("checkchange", item, checked);

this.filter.dt.delay(this.filter.updateBuffer);
},

getSelected: function() {
return this.combo.component.getValue();
}

});

razvanioan
14 Apr 2009, 4:38 AM
I've changed the field option in getFielterData method from GridFilters.js, just to be able to configure the field name for the filter:



field: f.mapping != undefined ? f.mapping : f.dataIndex,




Ext.override(Ext.ux.grid.GridFilters, {
getFilterData: function(){
var filters = [],
fields = this.grid.getStore().fields;

this.filters.each(function(f){
if(f.active){
var d = [].concat(f.serialize());
for(var i=0, len=d.length; i<len; i++)
filters.push({
field: f.mapping != undefined ? f.mapping : f.dataIndex,
data: d[i]
});
}
});

return filters;
}
});


In this way I can change the field name string to be sent to the server whenever I want (if not passed, it takes the default dataIndex field name), and the server will filter based on that field name instead of the displayed column field:



filters: [
...
,{type: 'list', dataIndex: 'communication_type', phpMode: true, store: commTypeStore, labelField: 'communication_type', mapping: 'h.communication_type_id'}
...
]


It's handy for me also for complex queries where using the simple field name was getting no results because of the ambiguous request, now I can specify exactly what to include in the where clause. Before of this I was comparing field names on the server side (lots of switch / if..then..else).

Maybe somebody finds this useful ...

Sesshomurai
20 Apr 2009, 8:42 PM
Hi. A friend of mine has created a combo filter for the Grid Filter plugin. It's sort of a proof of concept, but it works

Please, give it a try. Suggestions and improvements are more than welcome

ComboFilter.js


Hi,
I was just thinking about this when I see your post. Do you have an example how to use it? I'm kinda new to grid filters, but want to use this filter - just not sure how to initialize it in my grid.

thanks.

Illiarian
20 Apr 2009, 10:19 PM
Hi,
I was just thinking about this when I see your post. Do you have an example how to use it? I'm kinda new to grid filters, but want to use this filter - just not sure how to initialize it in my grid.

thanks.

It's initialized like any other filter — by passing the field name of a column of the grid:




// provided that you have the following fields in your grid: serv_name, supp_name etc.

var filters = new Ext.ux.grid.GridFilters({
filters:[{
type: 'combo',
dataIndex: 'serv_name',
options: services
}, {
type: 'combo',
dataIndex: 'supp_name',
options: suppliers
}, {
type: 'combo',
dataIndex: 'agen_name',
options: agencies
}
]});

Sesshomurai
21 Apr 2009, 6:35 AM
Ok, I see.

But can i use a remote store for the combo? Or is there another way to load dynamic combo data into it?

Thanks for the tips.

cherbert
22 Apr 2009, 12:23 AM
There appears to be a problem getting this plugin working in Ext 3.0 RC1.

Has anyone else tried?


When trying to click a filter checkbox in the drop down menu FireBug reports the following error...

d.itemId is undefined
[Break on this error] Ext.DomHelper=function(){var w=null,l=/^...(Ext.History,new Ext.util.Observable());

gido.carper
24 Apr 2009, 1:58 AM
Hi all,

I am trying to make an extra Datefilter.js called multidatefilter.js I would like to have the posibility to choose multiple Dates from the Datepicker. I chanced the datefilte.js and got it working already, though I dont know how to get ride of the extra CheckItem. For I only want one calendar and not 3 different calenders as in the datefilter.js it would be nicer not having the extra step. Check the screenshot so you can see what I mean.

the code


var dates = this.dates = {
'multi': new Ext.menu.CheckItem(
{text: 'multi', menu: new Ext.menu.DateMenu(opts)}
)
};

this.menu.add(dates.multi);



if I take away the "new Ext.menu.CheckItem" like:


var dates = this.dates = {'multi': new Ext.menu.DateMenu(opts)};


the calendar doesnt work anymore...

Could anyone help me to get ride of the checkitem?

Thanks in adavance!

Gido

LeviOu
27 Apr 2009, 7:47 PM
js file:


var filterstore = new Ext.data.Store
({
proxy: new Ext.data.HttpProxy({ url: "jsonGrid.aspx?Param=filtercompany" }),
reader: new Ext.data.JsonReader
({ totalProperty: "totalPorperty",
root: "result",
fields: [{ name: 'id' }, { name: 'text'}]
})
});
var filters = new Ext.ux.grid.GridFilters({ filters: [
{
type: 'list',
dataIndex: 'Company',
store: filterstore,
labelField: 'text'
}
]
});

server side:


string filterParam = "filter[{0}][field]";
string valueParam = "filter[{0}][data][value]";
string typeParam = "filter[{0}][data][type]";
string compareParam = "filter[{0}][data][comparison]";
int k = 0;
while (true)
{
string filterColumn = HttpContext.Current.Request[string.Format(filterParam, k)];
string value = HttpContext.Current.Request[string.Format(valueParam, k)];
string type = HttpContext.Current.Request[string.Format(typeParam, k)];
string compare = HttpContext.Current.Request[string.Format(compareParam, k)];
if (string.IsNullOrEmpty(filterColumn))
{
break;
}
k++;
}

problems:when getting value of id , return false at server side;
store data :[{"id":1,"text":"you"}]
but when getting id ,it return 1005 ,not wanted id:'1'. why? maybe i configed wrong filter!
thanks for your help!!!!

benmclendon
28 Apr 2009, 12:38 PM
I have an issue with this plug-in on 3.0 RC1 code.

On initial load of the grid the "start" parameter is not sent in the post.

I catch it on the server side, so its not a big deal for me now...

razvanioan
28 Apr 2009, 10:53 PM
@LeviOu: Try adding id option for JsonReader:



reader: new Ext.data.JsonReader({
totalProperty: "totalPorperty",
root: "result",
id: "id",
fields: [
{ name: 'id' },
{ name: 'text'}
]
})


I don't know for sure, but give it a try...

I'm using the following store configuration for my list filters, and are working fine (I've even made an override for changing the name of the filter sent to the server, it's described above on this page):



var domainFilterStore = new Ext.data.JsonStore({
autoLoad: true
,url: 'path/to/proxy.php'
,root: 'data'
,id: 'id'
,fields: [
{name: 'id', type: 'int'}
,{name: 'value', type: 'string'}
]
,baseParams: {
type: 'filterList'
}
});