PDA

View Full Version : Grid Filter (Plugin)



Pages : 1 [2] 3 4

fendrikat
8 Jan 2008, 8:29 AM
Can you post an exmaple of how to use a list type with a datastore for options? Are there plans to have a filter using a combobox?

Hi Robasi,
...I had the same issue as you, 90% of my list data is combo/reference-based, so I needed the same. Maybe you did it already as wll, but I followed JorisA's advise and modified ListFilter.js:



validateRecord: function(record){
if(Ext.type(this.getValue())=='array') {
for(i=0;i<this.getValue().length;i++) {
if(this.getValue()[i] == record.get(this.dataIndex))
return true;
}
return false;
} else {
return this.getValue() == record.get(this.dataIndex);
};
// return this.getValue().indexOf(record.get(this.dataIndex)) > -1; **Original code

}


Maybe not nice, maybe not pretty, but does exactly, what I need: User can select one or more values from list options / combo / ref-data and the validator will receive single value or array. For array, it will check every single selected value if it is equal to the actual record actual field value.

Messes up a bit original ListFilter.js, but to be honest I only need this behavior...

Frank

rfjacobsen
8 Jan 2008, 9:52 AM
First of all, I am just getting started with Ext and so may be asking a question that is an FAQ or has been answered numerous times.

I've done a search for documentation related to this plug-in and have found nothing. Is there any formal user guide or something similar for this plug-in, a tutorial that helps get one started?

Thanks.

RJ

tarnawska
11 Jan 2008, 12:58 PM
This is an awesome plugin; it's working beautifully in my grid.

I just have one question: Is there a way to display the active filters on a grid? Either in a panel or a bar or something? I'm referring to the param that gets passed on the xhr request (yea, I'm using remote sort/filtering), like so:

filters: {"0"=>{"field"=>"cpu", "data"=>{"type"=>"string", "value"=>"Xeon"}}, "1"=>{"field"=>"memory", "data"=>{"type"=>"numeric", "value"=>"2", "comparison"=>"lt"}}}

I'd like to have that data be refreshed in some part of the grid saying, "These are your current active filters."

I just know my users are going to complain, "I can't remember which filters I'm currently using?! Can I has a way to see these?"

Thanks for any feedback and keep up the good work!

hendricd
11 Jan 2008, 1:08 PM
There are a couple of posts (on this thread) on how to gather that. Look for GridFilters.getState.

It returns an object of the form: {filters:filters}

JorisA
13 Jan 2008, 4:30 AM
Hi, I modified the script a bit to allow css icons definition like the orriginal menu's:


.ux-menu-editable-icon {
margin: 3px 3px 2px 2px;
}

.ux-filter-icon-find {
background-image:url(../icons/find.gif) !important;
}

.ux-filter-icon-gt {
background-image:url(../icons/greater_then.gif) !important;
}

.ux-filter-icon-lt {
background-image:url(../icons/less_then.gif) !important;
}

.ux-filter-icon-eq {
background-image:url(../icons/equals.gif) !important;
}


Modifications:
StringFilter.js:

Ext.ux.grid.filter.StringFilter = Ext.extend(Ext.ux.grid.filter.Filter, {
updateBuffer: 500,

init: function(){
var value = this.value = new Ext.ux.menu.EditableItem({iconCls: 'ux-filter-icon-find'});
value.on('keyup', this.onKeyUp, this);
this.menu.add(value);

this.updateTask = new Ext.util.DelayedTask(this.fireUpdate, this);
},

EditableItem.js:

onRender: function(container){
var s = container.createChild({
cls: this.itemCls,
html: String.format(
'<img src="{0}" class="x-menu-item-icon ux-menu-editable-icon {1}" />',
this.icon || Ext.BLANK_IMAGE_URL, this.iconCls || '')});

RangeMenu.js:
Remove the icons {} stuff around line 44 and replace the following

var fields = this.fields = Ext.applyIf(this.fields || {}, {
'gt': new Ext.ux.menu.EditableItem({
iconCls: 'ux-filter-icon-gt',
editor: new cls(typeof cfg == "object" ? cfg.gt || '' : cfg)}),
'lt': new Ext.ux.menu.EditableItem({
iconCls: 'ux-filter-icon-lt',
editor: new cls(typeof cfg == "object" ? cfg.lt || '' : cfg)}),
'eq': new Ext.ux.menu.EditableItem({
iconCls: 'ux-filter-icon-eq',
editor: new cls(typeof cfg == "object" ? cfg.gt || '' : cfg)})
});

tarnawska
14 Jan 2008, 10:54 PM
Hrm, I'm afraid I don't quite understand.

Okay, let's say that I have a grid detailing some servers I have sitting in my datacenters. Here's my grid (fed by an external xml feed that I have):



<script type="text/javascript">
Ext.onReady(function(){
// define the data store and the xml mappings
var store = new Ext.data.GroupingStore({
proxy: new Ext.data.HttpProxy( {url: '/search/servers.xml'} ),
reader: new Ext.data.XmlReader({
record: 'server',
id: 'id',
totalRecords: 'total'
}, [{name: 'hostname', mapping: 'hostname'},
{name: 'url', mapping: 'link'},
{name: 'datacenter', mapping: 'location > datacenter'},
{name: 'location', mapping: 'location > identifier'},
{name: 'serial', mapping: 'serial_number'},
{name: 'cpu', mapping: 'cpu > processor'},
{name: 'cpu_count', mapping: 'cpu > processor@count'},
{name: 'cpu_speed', mapping: 'cpu > speed'},
{name: 'cpu_clock', mapping: 'cpu > speed@unit'},
{name: 'cpu_arch', mapping: 'cpu > arch'},
{name: 'ram', mapping: 'memory'},
{name: 'memory_unit', mapping: 'memory@unit'},
{name: 'os', mapping: 'operating_system > name'},
{name: 'os_version', mapping: 'operating_system > version'},
{name: 'os_arch', mapping: 'operating_system > arch'},
{name: 'status', mapping: 'system_status'},
{name: 'updated', mapping: 'updated'}
]),
remoteSort: true
});
store.setDefaultSort('hostname', 'asc');

// define the filters
var filters = new Ext.ux.grid.GridFilters({filters:[
{type: 'string', dataIndex: 'hostname'},
{type: 'string', dataIndex: 'datacenter'},
{type: 'string', dataIndex: 'location'},
{type: 'string', dataIndex: 'serial'},
{type: 'string', dataIndex: 'cpu'},
{type: 'numeric', dataIndex: 'cpu_speed'},
{type: 'string', dataIndex: 'cpu_arch'},
{type: 'numeric', dataIndex: 'ram'},
{type: 'string', dataIndex: 'os'},
{type: 'string', dataIndex: 'status'},
{type: 'date', dataIndex: 'updated'},
]});

// define the column model
var column_model = new Ext.grid.ColumnModel([
{ id: 'hostname', header: 'Hostname', dataIndex: 'hostname', width: 210, renderer: renderHostname },
{ id: 'datacenter', header: 'Datacenter', dataIndex: 'datacenter', width: 85 },
{ id: 'location', header: 'Location', dataIndex: 'location', width: 95 },
{ id: 'serial', header: 'Serial', dataIndex: 'serial', width: 65 },
{ id: 'cpu', header: 'CPU Type', dataIndex: 'cpu', width: 150, renderer: renderCPU },
{ id: 'cpu_speed', header: 'CPU Speed', dataIndex: 'cpu_speed', width: 75, renderer: renderCPUSpeed },
{ id: 'arch', header: 'Arch', dataIndex: 'cpu_arch', width: 50 },
{ id: 'memory', header: 'Memory', dataIndex: 'ram', width: 60, renderer: renderMemory },
{ id: 'operating_system', header: 'Operating System', dataIndex: 'os', renderer: renderOperatingSystem },
{ id: 'status', header: 'Status', dataIndex: 'status', width: 55 },
{ id: 'updated', header: 'Last Updated', dataIndex: 'updated', width: 120, renderer: Ext.util.Format.dateRenderer('Y-m-d, g:i a'), hidden: true }
]);
column_model.defaultSortable = true;

// define custom column views
function renderHostname(value, p, record) { return String.format('<a href="/servers/detail/{0}">{1}</a>', record.data.hostname, value ); }
function renderOperatingSystem(value, p, record) { return String.format('{0} {1} {2}bit', value, record.data.os_version, record.data.os_arch); }
function renderMemory(value, p, record) { return String.format('{0} {1}', value, record.data.memory_unit); }
function renderCPUSpeed(value, p, record) { return String.format('{0} {1}', value, record.data.cpu_clock); }
function renderCPU(value, p, record) { return String.format('{0} x {1}', record.data.cpu_count, value ); }

// define how the grid is going to be displayed
var grid = new Ext.grid.GridPanel({
el: 'servers-grid',
height: 600, autoFitColumns: true, loadMask: true, store: store, cm: column_model, plugins: filters,
enableColLock: true, view: new Ext.grid.GroupingView({forceFit: true, enableRowBody: true}),
// top link bar
tbar:['Quick Search: ', ' ', new Ext.app.SearchField({ store: store, width: 320 }), ' ', 'Active Filters:'],

// grid footer
bbar: new Ext.PagingToolbar({
pageSize: 100, store: store, displayInfo: true,
emptyMsg: 'No servers matched your search criteria.',
displayMsg: 'Displaying Servers {0} - {1} of {2}',
plugins: [filters, new Ext.ux.grid.PageSizer({
afterText: 'Servers',
sizes: [[25],[50],[100],[500]],
comboCfg: {width: 100}
})],
items:['-', 'Format Options:', {
text: 'XML Feed', cls: 'x-btn-text-icon', icon: '/images/interface/icons/feed.png',
handler: function() { window.location = "<%= formatted_servers_path(:xml) %>";
}
}]
})
});

grid.render();

// trigger the data store load
store.load({params:{start: 0, limit: 100}});
});</script>

<div id="servers-grid"></div>


Where I'd really like to put this output is here (taken from the tbar in my panel):



tbar:['Quick Search: ', ' ', new Ext.app.SearchField({ store: store, width: 320 }), ' ', 'Active Filters:', filters],


but on that level of scope, I'm not sure it can even reference that variable. Are you saying that it should be referencing the variable that holds:



// define the filters
var filters = new Ext.ux.grid.GridFilters({filters:[
{type: 'string', dataIndex: 'hostname'},
{type: 'string', dataIndex: 'datacenter'},
{type: 'string', dataIndex: 'location'},
{type: 'string', dataIndex: 'serial'},
{type: 'string', dataIndex: 'cpu'},
{type: 'numeric', dataIndex: 'cpu_speed'},
{type: 'string', dataIndex: 'cpu_arch'},
{type: 'numeric', dataIndex: 'ram'},
{type: 'string', dataIndex: 'os'},
{type: 'string', dataIndex: 'status'},
{type: 'date', dataIndex: 'updated'},
]});


Am I asking too much, or is someone able to bail me out here?

Thanks!

hendricd
15 Jan 2008, 4:47 AM
@tarnawska -- yourGrid.filters.getState() method (actually used for StateManagement) gives you a hash of currently active filter conditions.

Try it: ;)

console.log (yourGrid.filters.getState()) You would then need to iterate those and decide how to present them (whereever, whenever).

tarnawska
15 Jan 2008, 11:41 AM
Oh dur. I guess I didn't explain it well enough.

I realize that the hash is in
grid.filters.getState(); what I'm asking is that if I were to make a rendering function for that hash (let's call it 'renderFilterList'), and then put it in my panel like so:


tbar:['Quick Search: ', ' ', new Ext.app.SearchField({ store: store, width: 320 }), ' ', 'Active Filters:', renderFilterList],

Is this going to be refreshed every time a new XHR request is being sent/received? Or am I going to have to tie some sort of onSuccess handler in the XML Reader to get that 'tbar' refreshed?

hendricd
15 Jan 2008, 12:22 PM
No, and Yes, you'll need some sort of event to update a visual representation of all those possible filters you may have in effect (gonna be a tight squeeze in a ToolBar, no?).

I use the Grid's filterupdate event to manage that (so they see what the active filters are before the make a redundant refresh request again).

hb562100
15 Jan 2008, 6:07 PM
Thank u.
That's a nice work.

dmhost
16 Jan 2008, 2:10 AM
Hi Troy,

I just wanted to follow up about this...




When I select "Group By This Field" or "Show in Groups" for any column, I get this error:


B[D].firstChild.style has no properties
http://myserver/ext-all.js
Line 142


It looks like it is a bug that was recently discovered in how the GroupingView (meaning it has nothing to do with the filter plugin). Hopefully it will be fixed in future updates. As of right now Ext version 2.0 the grid will choke if the column you are "grouping by" contains data with HTML and double quotes in it such as:
<span style="color: green">My Company</span> Maybe by now you don't care any more, but for anyone else who has the same problem, I think this will really help.

References to this bug: http://extjs.com/forum/showthread.php?t=22923
And also: http://extjs.com/forum/showthread.php?t=22928

DM

LeonardoAP
16 Jan 2008, 4:25 AM
Hi!

I'm getting an http error when seting a filter. The page atempts to POST to an XML file, but the status of http is ended in 405 (method not allowed).
Its possible to be the XML file the cause of the error?

hendricd
16 Jan 2008, 4:22 PM
That usually means the site you configured does not permit POST.
Change your store's Proxy method to GET to get started.

LeonardoAP
17 Jan 2008, 3:27 AM
how i do that?
this is my store:


var store = new Ext.data.Store({
url: 'xmlData.xml',
reader: new Ext.data.XmlReader({
record: 'record',
id: 'id',
}, record),
});

hendricd
17 Jan 2008, 3:57 AM
how i do that?
this is my store:

Either set a listener:


var store = new Ext.data.Store({
url: 'xmlData.xml',
reader: new Ext.data.XmlReader({
record: 'record',
id: 'id',
}, record),
listeners:{beforeload : function(store,options){options.method="GET"}}
});
or do it when you load:

store.load({method:'GET',.....});

dandfra
18 Jan 2008, 5:05 AM
Hi, I saw that the arrows keys don't work inside the text field in your extension.
Since I had the same problem I link here the relative thread (http://extjs.com/forum/showthread.php?p=111184#post111184) (with a solution...)

Ciao

edweb
19 Jan 2008, 12:39 PM
How I do can filter by 'name_table.column' in a JOIN QUERY ?!!!

eg:

SELECT tb_user.name, tb_job.name LEFT tb_user ON tb_user.id = tb_job.user


If I to use querystring 'filter[0][field]=name', generate MySql error: Column 'name' in where clause is ambiguous

Help me, please !!!!!!!!:((

ps: Sorry my bad english

ybshyz
19 Jan 2008, 4:57 PM
Thanks to share this great plugin.
very good,but i can't use 'ext-lang-zh_CN.js' change it to chinese,why?

julienp
21 Jan 2008, 3:04 AM
Hello,

i add a date filter in my grid, when i choose 1 january 2007, i have:

filter[0][data][value] 0/1/Y (in the post parameters)

and when i choose the 1 january 2008, i have:

filter[0][data][value] 0/1/Y

I can retreive the day, the month but how to retreive the year?

thanks for help

vertigoMX
22 Jan 2008, 11:37 AM
Great Code! but I also have another customized filters outside the grid, and in order to make my life easier, I would like to add filters dinamically from javascript outside the ExtJs code zone... something like:


<input type="button" onclick="addFilter('color','red');">
<script>
function addFilter(index, value)
{
Ext.ux.grid.GridFilters.AddFilter(index, value);
// then trigger the grid.reload event
}
</script>


Is this possible? cause Ext.ux.grid.GridFilters doesnt exists outside ext.ready(){}

any ideas?

vertigoMX
22 Jan 2008, 12:51 PM
Analizing the classes for the actual filtering, I came up with something like this:


function addQuickFilter(filterType, dataIndex, value)
{
if(value == "All") return;
var oGrid = Ext.getCmp('myGrid');
var filter = oGrid.filters.getFilter(dataIndex);
filter.setValue(value);
filter.setActive(true);
}


it works!

cheers

Wolfgang
24 Jan 2008, 2:38 AM
Pls note that in your function you have to hardcode the gridid.

mfrancey
25 Jan 2008, 2:26 AM
First of all, congratulations for this very nice plugin :):):)


I copied "Ext 2.0.1" on my webserver (SSL)
I copied "Grid Filter" plugin on my webserver using the provided "source.zip"

Everything works fine, exept the filter action

Here's my code


<html>
<head>
<script type="text/javascript" src="../../_extJS/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="../../_extJS/ext-all.js"></script>
<script type="text/javascript" src="./ux/menu/EditableItem.js"></script>
<script type="text/javascript" src="./ux/menu/RangeMenu.js"></script>
<script type="text/javascript" src="./ux/grid/GridFilters.js"></script>
<script type="text/javascript" src="./ux/grid/filter/Filter.js"></script>
<script type="text/javascript" src="./ux/grid/filter/StringFilter.js"></script>
<script type="text/javascript" src="./ux/grid/filter/DateFilter.js"></script>
<script type="text/javascript" src="./ux/grid/filter/ListFilter.js"></script>
<script type="text/javascript" src="./ux/grid/filter/NumericFilter.js"></script>
<script type="text/javascript" src="./ux/grid/filter/BooleanFilter.js"></script>
<script type="text/javascript">
Ext.BLANK_IMAGE_URL = '/_extJS/resources/images/default/s.gif'; // 2.0
Ext.onReady(function(){
Ext.ux.menu.RangeMenu.prototype.icons = {
gt: 'img/greater_then.png',
lt: 'img/less_then.png',
eq: 'img/equals.png'
};
Ext.ux.grid.filter.StringFilter.prototype.icon = 'img/find.png';
Ext.state.Manager.setProvider(new Ext.state.CookieProvider());

var ds = new Ext.data.GroupingStore({
proxy: new Ext.data.HttpProxy({
url:'action.php'
}),

reader: new Ext.data.JsonReader({
id: 'id',
totalProperty: 'data.total',
root: 'data.results'
}, Ext.data.Record.create([
{name:'id'},
{name:'name'},
{name:'price'},
{name:'dateAdded'},
{name:'visible'},
{name:'size'}])),

groupField: 'size',
sortInfo: {field: 'name', direction: 'ASC'},
remoteSort: true
});

var filters = new Ext.ux.grid.GridFilters({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'}
]});

var cm = new Ext.grid.ColumnModel([{
dataIndex: 'id',
header: 'Id'
}, {
dataIndex: 'name',
header: 'Name'
}, {
dataIndex: 'price',
header: 'Price'
}, {
dataIndex: 'dateAdded',
header: 'Date Added'
}, {
dataIndex: 'size',
header: 'Size'
}, {
dataIndex: 'visible',
header: 'Visible'
}]);
cm.defaultSortable = true;

var grid = new Ext.grid.GridPanel({
id: 'example',
ds: ds,
cm: cm,
enableColLock: false,
loadMask: true,
view: new Ext.grid.GroupingView(),
plugins: filters,
height:400,
width:550,

el: 'grid-example',

bbar: new Ext.PagingToolbar({
store: ds,
pageSize: 15,
plugins: filters
})
});
grid.render();

ds.load({params:{start: 0, limit: 15}});
});
</script>
<style type="text/css" title="currentStyle" media="screen">
@import "/_extJS/resources/css/ext-all.css";

.x-grid3-hd-row td.ux-filtered-column {
font-style: italic;
font-weight: bold;
}
</style>
</head>
<body>
<div id="grid-example" style="margin: 10px;"></div>
</body>
</html>I alos modified the action.php of the given example with static datas for testing


<?php
header ("Pragma: no-cache"); // HTTP/1.0
header("Content-Type: application/json");
echo('{"meta":{"code":1,"exception":[],"success":true,"message":null},"data":{"total":30,"results":[{"id":"1","name":"T-Qualizer Shirt - Cool Glowing T-Shirt","price":"39.99","dateAdded":"1999-12-06","visible":"1","size":"medium"},{"id":"2","name":"Come to the Dark Side","price":"16.99","dateAdded":"2001-11-15","visible":"1","size":"small"},{"id":"3","name":"No, I will not fix your computer","price":"14.99","dateAdded":"2002-06-20","visible":"0","size":"small"},{"id":"4","name":"I void warranties shirt","price":"15.99","dateAdded":"2002-06-21","visible":"1","size":"large"},{"id":"5","name":"meh - When indifference and fashion collide.","price":"12.99","dateAdded":"2005-06-26","visible":"0","size":"medium"},{"id":"6","name":"Pi By Numbers - shirt","price":"14.99","dateAdded":"2006-06-22","visible":"1","size":"extra small"},{"id":"7","name":"IM In UR Blank - shirt","price":"20.99","dateAdded":"2006-06-22","visible":"0","size":"small"},{"id":"8","name":"Obey gravity, It\'s the law!","price":"22.99","dateAdded":"2005-05-16","visible":"0","size":"extra large"},{"id":"9","name":"The ThinkGeek Chain Mail T-Shirt","price":"99.99","dateAdded":"2007-08-20","visible":"1","size":"large"},{"id":"10","name":"There\'s no place like 127.0.0.1 shirt","price":"20.99","dateAdded":"2006-01-02","visible":"0","size":"medium"},{"id":"11","name":"Looking for a Japanese Girlfriend Hoodie","price":"39.99","dateAdded":"2007-02-20","visible":"1","size":"medium"},{"id":"12","name":"Looking For A Japanese Girlfriend","price":"18.49","dateAdded":"2006-03-20","visible":"1","size":"small"},{"id":"13","name":"Killer Coding Ninja Monkeys","price":"14.99","dateAdded":"2006-04-25","visible":"0","size":"medium"},{"id":"14","name":"Japanese for Beginners","price":"15.49","dateAdded":"2005-04-24","visible":"1","size":"extra large"},{"id":"15","name":"more beer shirt","price":"12.99","dateAdded":"2002-04-20","visible":"0","size":"extra small"},{"id":"16","name":"got root? T-shirt","price":"16.99","dateAdded":"2006-04-20","visible":"1","size":"small"},{"id":"17","name":"HEAD tag hat","price":"14.99","dateAdded":"2007-04-23","visible":"1","size":"medium"},{"id":"18","name":"Fuse Ladder Necklace","price":"32.99","dateAdded":"2007-03-23","visible":"1","size":"small"},{"id":"19","name":"GEEK Hooded Sweatshirt","price":"36.99","dateAdded":"2005-04-27","visible":"0","size":"extra small"},{"id":"20","name":"Original Ring Thing - A hidden bottle opener","price":"7.99","dateAdded":"2004-04-20","visible":"1","size":"small"},{"id":"21","name":"Geek Work Shirt","price":"14.99","dateAdded":"2005-06-24","visible":"0","size":"medium"},{"id":"22","name":"The ThinkGeek Power Tie","price":"19.99","dateAdded":"2006-05-20","visible":"1","size":"large"},{"id":"23","name":"got root? bucket hat","price":"16.99","dateAdded":"2007-02-23","visible":"1","size":"extra large"},{"id":"24","name":"Meh Hoodie","price":"34.99","dateAdded":"2006-06-26","visible":"1","size":"extra small"},{"id":"25","name":"Geek Belt Buckles","price":"19.99","dateAdded":"2006-05-25","visible":"1","size":"medium"},{"id":"26","name":"\/dev\/pillow","price":"12.99","dateAdded":"2004-05-25","visible":"0","size":"small"},{"id":"27","name":"The ThinkGeek \'Ties Suck\' Tie","price":"24.99","dateAdded":"2005-05-25","visible":"1","size":"medium"},{"id":"28","name":"The ThinkGeek 8-bit Tie","price":"19.99","dateAdded":"2004-04-24","visible":"0","size":"medium"},{"id":"29","name":"TWIT Personal Area Network Hat","price":"19.99","dateAdded":"2007-04-29","visible":"1","size":"small"},{"id":"30","name":"The ThinkGeek White or Black Hacker Hats","price":"16.99","dateAdded":"2007-07-27","visible":"1","size":"large"}]}}');?>Everything works fine, except the filtering functionnality. It seems to run, but there's no filtering action !?

Thanks for your help, I don't understand what's wrong !

LeonardoAP
25 Jan 2008, 4:49 AM
There is no way to filter the grid data without a HttpProxy?

mfrancey
25 Jan 2008, 5:44 AM
Sorry to be a newby in that context...

Does someone have an exemple do start with?

Thanks for your help

hendricd
25 Jan 2008, 5:55 AM
@mfrancey -- are your active filters being sent with the request?

mfrancey
25 Jan 2008, 6:03 AM
Here's what I can see with firebug to be post (I assume this would be answer "yes" to your question?)


dir ASC
filter[0][data][type] list
filter[0][data][value] extra small
filter[0][field] size
limit 15
sort size
start 0But because I'm new with this, I'd appreciate to have the source code of action.php of the given example(by Ambiance). I think the problem should be there ! No ?

I suppose anyway that the problems comes from the action.php script. I'd appreciate to have the source code of the AMBIENCE given example!

julienp
28 Jan 2008, 12:17 AM
Hello,

i add a date filter in my grid, when i choose 1 january 2007, i have:

filter[0][data][value] 0/1/Y (in the post parameters)

and when i choose the 1 january 2008, i have:

filter[0][data][value] 0/1/Y

I can retreive the day, the month but how to retreive the year?

thanks for help


Hello, no idea for my problem? :(

i have this in my js:

{type: 'date', dataIndex: 'IMMATRICULATION_ENTITE'},

Thanks for help me

violinista
28 Jan 2008, 5:57 AM
FEATURE REQUEST::

It would be nice to have QuickTip on column headers, to see parameters of filter. For example, if I choose to filter column "Name" with value "beer", when I hover the column "Name" the QuickTip will show, with filter value "Beer". Got it? I think it'll be more usable than now.

Cheers!

KGL
30 Jan 2008, 9:46 AM
HI @all,
thanks a lot for these great functions. All of my filters work fine except the dateFilter. there I get this error message for DateFilter.js (line 89)

record.get(this.dataIndex).clearTime is not a function

Does anybody has a hint for me?

Thanks a lot

KGL

mattb
30 Jan 2008, 2:55 PM
Has anyone used Livegrid + the Grid Filter plugin? I'm trying this out and the grid and filters work as expected except when I apply a filter and then scroll the grid -- once the grid makes a request for new rows, it doesn't pass the filter to my server-side function so it ends up pulling new rows from an unfiltered dataset...

Any ideas on how to pass the filters through livegrid and back to the server?

thx

Matt

galdaka
31 Jan 2008, 12:06 AM
Hi,

I make simple changes in Filter Grid code to make more compatible with my pourposes..

1) All js in one file.

2) I create the CSS class by code, like this (on init GrildFilter):


Ext.util.CSS.createStyleSheet('.x-grid3-hd-row td.ux-filtered-column{font-style: italic;font-weight: bold;}', 'x-grid3-hd-row td.ux-filtered-column');

3) I pass new parameter to the component, the path of the icons resources:


new Ext.ux.grid.GridFilters({
pathBD: 'http://www.galdaka.es/images',
filters:[
{type: 'numeric', dataIndex: 'codProyecto'},
{type: 'string', dataIndex: 'creadorProyecto'},
{type: 'numeric', dataIndex: 'cliente'},
{type: 'date', dataIndex: 'fecInicioProyecto'},
{type: 'list', dataIndex: 'duracion', options: ['extra small', 'small', 'medium', 'large', 'extra large']},
{type: 'list', subtype: 'string', dataIndex: 'versionActualProyecto', options: ['1.0', '2.0', '3.0']},
{type: 'numeric', dataIndex: 'numeroProyecto'}
]}
)


Now only I have 1 js and 4 images.

4) I overwrite the "buildquery" method to adapt to a Domino FTSEARCH query string:


var p = {};
var sql = [];
for(var i=0, len=filters.length; i<len; i++){
if(filters[i].data.type == 'list' && filters[i].data.value.length > 0){
aux = [];
for(var j=0; j<filters[i].data.value.length; j++){
aux[aux.length] = '[' + filters[i].field + '] ' + ' = ' + "\"" + filters[i].data.value[j] + "\"";
}
sql[sql.length] = '(' + aux.join(' OR ') + ')'
//sql[sql.length] = aux.join(' OR ');
}else{
var quote = filters[i].data.type == 'string' ? "\"" : '';
var comparator = '';
if(filters[i].data.comparison){
switch(filters[i].data.comparison){
case 'gt': comparator = ' > '; break;
case 'lt': comparator = ' < '; break;
case 'eq': comparator = ' = '; break;
}
}else{
comparator = filters[i].data.type == 'string' ? ' CONTAINS ' : ' = '
}
sql[sql.length] = '[' + filters[i].field + '] ' + comparator + quote + filters[i].data.value + quote;
}
}
p['filterQuery'] = escape(sql.join(' AND '));
return p;

All works perfect!! ;)

5) I change the icons (with .gif have transparent background and other minimal changes).

thatcoder
1 Feb 2008, 5:34 PM
@ambience

Great plug-in.

I caught a bug in the DateFilter.js line 89.

Same bug as KGL.

Here is my solution.


Date.patterns = {
ISO8601Long:"Y-m-d H:i:s",
ISO8601Short:"Y-m-d",
ShortDate: "n/j/Y",
LongDate: "l, F d, Y",
FullDateTime: "l, F d, Y g:i:s A",
MonthDay: "F d",
ShortTime: "g:i A",
LongTime: "g:i:s A",
SortableDateTime: "Y-m-d\\TH:i:s",
UniversalSortableDateTime: "Y-m-d H:i:sO",
YearMonth: "F, Y"
};

I recommend creating a file called Date.patterns.js with the Javascript object and include it in head of your document.

Replace this (Line: 89)


var val = record.get(this.dataIndex).clearTime(true).getTime();


With this:


var val = new Date(Date.parseDate(record.get(this.dataIndex),Date.patterns.SortableDateTime)).clearTime(true).getTime();


Rationale
The date from my HTTP Payload returns the date in the format 2008-02-07T09:00:00 which corresponds to SortableDateTime according to the Date.patterns object (see the ExtJS docs)
Since clearTime and getTime are prototype functions of the Date object they need to be called on a Date object, not on a malformed date.



HI @all,
thanks a lot for these great functions. All of my filters work fine except the dateFilter. there I get this error message for DateFilter.js (line 89)


Does anybody has a hint for me?

Thanks a lot

KGL

rafeekphp
2 Feb 2008, 3:22 AM
I was try to run the scirpt which i downloaded from your thread but i cant able to see the result and i was not able to see the "JsonResponseReader.js" file in the zip folder. can you help to find the file.

Thank you

Rafeek

thatcoder
2 Feb 2008, 7:24 AM
@rafeekphp

it doesn't appear that the file is needed.


I was try to run the scirpt which i downloaded from your thread but i cant able to see the result and i was not able to see the "JsonResponseReader.js" file in the zip folder. can you help to find the file.

Thank you

Rafeek

thatcoder
2 Feb 2008, 7:53 AM
@ambience & all?

What would it entail to tie the plugin or some variation of it to a FormPanel? i.e to provide a unified UI to allow for grid filtering?

ajaxE
2 Feb 2008, 9:43 PM
This extension is great. Why the grid data is not shown.

Thanks

ajaxE
2 Feb 2008, 9:52 PM
Nevermind, Sorry that it was my mistake.

Thanks!

ambience
3 Feb 2008, 8:12 AM
@ambience & all?

What would it entail to tie the plugin or some variation of it to a FormPanel? i.e to provide a unified UI to allow for grid filtering?

Sorry for the lack of responsivness. As it seems to be a common request / idea, it would be great if some one put together an implementation. However, as to how it would function / look, I am unsure. Most likely, you would want to make it a pannel that could be imbeded in a dialog or on the same panel as the grid. So you constrcturo would look something like:



Ext.ux.grid.filter.FilterEditorPanel({
fitlers: yourFilterReference.
...
})


Then, by subscribing to the filter collection events you can keep your pannel configuration in synch. As to how to display / edit the filter information, that is up to you =) You could Ext.overwite the default filter prototypes to have a getConfigPanel() function, or store each of the configPanels in a seperate class and 'bind' them to their associated filter types in some way.

durlabh
4 Feb 2008, 1:01 PM
Hi Ambience! First of all, I would like to thank you for such a great plug-in. It is a life-saver in many situations. I just love it as it helps me in rolling the apps quite quickly.

I was thinking if we show a small little icon or change the header color for the columns that are filtered, that'll give a visual clue to the end user.

What do you think?

galdaka
4 Feb 2008, 2:40 PM
Hi Ambience! First of all, I would like to thank you for such a great plug-in. It is a life-saver in many situations. I just love it as it helps me in rolling the apps quite quickly.

I was thinking if we show a small little icon or change the header color for the columns that are filtered, that'll give a visual clue to the end user.

What do you think?

See this css class: .x-grid3-hd-row td.ux-filtered-column

greetings,

Shmoo
4 Feb 2008, 4:36 PM
I'm trying to get this to work with DWR+Spring+Java...

Any ideas where that JsonResponseReader.js is? Or do I have to create my own? Or just use EXT's JsonReader?

Sorry for the noob question... and thanks. :D

ambience
4 Feb 2008, 7:24 PM
I'm trying to get this to work with DWR+Spring+Java...

Any ideas where that JsonResponseReader.js is? Or do I have to create my own? Or just use EXT's JsonReader?

Sorry for the noob question... and thanks. :D

It's just a standard reader, we use a 'custom' reader to facilitate communications with the framework.

Shmoo
5 Feb 2008, 7:20 PM
Alright thanks. Once I get my codes up and working I'll post them here too. :)

arya009
6 Feb 2008, 11:59 PM
I am not able to get this plugin work. when i give any search criteria it is not filtering. In date filter it is not showing calendar

this is my code


/******************************************************************************************************/
var PC = {
init: function(){
var primaryKey = 'id';
var ps = 50;
Ext.QuickTips.init();

var js = new Ext.data.JsonStore({
url: 'ExtGetData.aspx',
baseParams:{task: "PC"},
root: 'data',
id: 'id',
fields: [
{name: 'Submitted', mapping: 'ReimbursementDate', type: 'date'} ,
{name: 'Participant', mapping: 'Name'},
{name: 'GroupAlias', mapping: 'groupalias'},
{name: 'ID', mapping: 'id'},
{name: 'Amount', mapping: 'Amount', type: 'float'},
{name: 'Source', mapping: 'Source'},
{name: 'SourceStatus', mapping: 'SourceStatus'},
{name: 'recordSelect'}
]


});


js.on('load',function()
{
var ds = new Ext.data.Store({
proxy: new Ext.ux.data.PagingMemoryProxy(js.reader.jsonData),
reader: js.reader,
remoteSort: true
});

var sm1 = new Ext.grid.CheckboxSelectionModel({singleSelect:false});
var sm = new Ext.grid.CheckboxSelectionModel({
singleSelect:false //,
// listeners: {
// rowselect: function(sm, row, rec) {
// //alert(rec.data.Participant);
// }
// }
});


/* Grid Filter */
Ext.ux.menu.RangeMenu.prototype.icons = {
gt: '../Images/GridFilter/greater_then.png',
lt: '../Images/GridFilter/less_then.png',
eq: '../Images/GridFilter/equals.png'
};

Ext.ux.grid.filter.StringFilter.prototype.icon = '../Images/GridFilter/find.png';

var filters = new Ext.ux.grid.GridFilters({
filters:
[
{type: 'date', dataIndex: 'Submitted'},
{type: 'string', dataIndex: 'Participant'},
{type: 'string', dataIndex: 'GroupAlias'},
{type: 'String', dataIndex: 'ID'},
{type: 'numeric', dataIndex: 'Amount'}
]
});

/* End Grid Filter */

var menuExport = new Ext.menu.Menu({
id: 'exportMenu',
items: [{
text: 'Excel',
handler: exportExcel
},{
text: 'PDF'
},{
text: 'CSV'
}]
});




// Define Column Model of the Grid
var cm = new Ext.grid.ColumnModel([
{header: 'Submitted', dataIndex: 'Submitted', sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y')},
{header: 'Participant', dataIndex: 'Participant', sortable: true},
{header: 'GroupAlias', dataIndex: 'GroupAlias', sortable: true},
{header: 'ID', dataIndex: 'ID', sortable: true, renderer: renderClaim},
{header: 'Amount ($)', dataIndex: 'Amount', sortable: true, align: 'right', renderer: Ext.util.Format.usMoney },
sm
]);





// Define Paging Toolbar for the Grid
var paging = new Ext.PagingToolbar({
pageSize: ps,
store: ds,
displayInfo: true,
displayMsg: 'Displaying Pending Claims {0} - {1} of {2}',
emptyMsg: "No Pending Claims to display",
plugins: filters
});



var myGrid = new Ext.grid.GridPanel({
el:'pending-grid',
store: ds,
id: 'myGrid',
cm: cm,
title: 'Pending Grid',
width: 990,
height: 600,
loadMask: true,
sm: sm,
stripeRows: true,
viewConfig:
{
forceFit:true,
enableRowBody:false,
showPreview:false
},
plugins: filters,
bbar: paging ,
tbar: mtb = new Ext.Toolbar(
{
height: 25,
items: [
{
text: 'Process',
tooltip: 'Click to Process selected row(s)',
handler: function(){
// Some Action
}
}
}, '-',
{
text: 'Cancel',
tooltip: 'Click to Cancel',
handler: function(){
//
}
}, '-',
{
text: 'Export',
tooltip: 'Export to Excel/PDF/CSV',
menu: menuExport //,
}
]
})
});

myGrid.render();

ds.load({params:{start:0, limit:ps}});
}); // js.on

js.load();

// pluggable renders
function renderClaim(value, p, record){
return String.format('<a href="javascript:ViewClaim(\'{0}\');">{0}</a>',value);
}

function exportExcel(){

}

} // init function end
}; // var PC end

Ext.onReady(PC.init, PC);

Shmoo
7 Feb 2008, 12:03 AM
Okay I managed to get it to work! :D

But I still have to do something with my back-end in order to process the filters sent by the grid. :))

The snippet below is the velocity template where I render the grid.


<!-- Start of HTML code for Simple Table -->

<div id="dataset_grid"></div>

<div id="StudyDataSetTabDelimitedBlockView" style="display: hidden"></div>
<!-- End of HTML code for Simple Table -->

<script type="text/javascript">
function createRecord(record){
record = Ext.data.Record.create([
#foreach($factor_uid in $factor_list)
#if($factor_list.size()==1)
{name: "$factor_name_map.get($factor_uid)", type: 'string'}
#else
{name: "$factor_name_map.get($factor_uid)", type: 'string'},
#end
#end

#set($loopCounter=1)
#foreach($variate_uid in $variate_list)
#if($loopCounter==$variate_list.size())
{name: "$variate_name_map.get($variate_uid)", type: 'string'}
#else
{name: "$variate_name_map.get($variate_uid)", type: 'string'},
#end
#set($loopCounter=$loopCounter+1)
#end
]);
return record;
}

function createDataStore(dataStore, recordType) {
dataStore = new Ext.data.Store({
proxy: new Ext.data.HttpProxy({
url: GET_STUDY_DATASET_URL
}),
reader: new Ext.data.JsonReader(
{
root: 'results',
totalProperty: 'total',
id: 'id'
}, recordType)
});
return dataStore;
}

// dataIndex maybe added later
function createColumnModel(cm) {
cm = new Ext.grid.ColumnModel([
#foreach($factor_uid in $factor_list)
#if($factor_list.size()==1)
{header: "$factor_name_map.get($factor_uid)", dataIndex: '$factor_name_map.get($factor_uid)', sortable:true, width: 100}
#else
{header: "$factor_name_map.get($factor_uid)", dataIndex: '$factor_name_map.get($factor_uid)', sortable:true, width: 100},
#end
#end

#set($loopCounter=1)
#foreach($variate_uid in $variate_list)
#if($loopCounter==$variate_list.size())
{header: "$variate_name_map.get($variate_uid)", dataIndex: '$variate_name_map.get($variate_uid)'}
#else
{header: "$variate_name_map.get($variate_uid)", dataIndex: '$variate_name_map.get($variate_uid)'},
#end
#set($loopCounter=$loopCounter+1)
#end
]);
return cm;
}
Ext.onReady(function(){
Ext.ux.menu.RangeMenu.prototype.icons = {
gt: 'javascript/lib/ext2.0/img/greater_then.png',
lt: 'javascript/lib/ext2.0/img/less_then.png',
eq: 'javascript/lib/ext2.0/img/equals.png'
};
Ext.ux.grid.filter.StringFilter.prototype.icon = 'javascript/lib/ext2.0/img/find.png';

var recordType = createRecord(recordType);
var ds = new Ext.data.Store({
proxy: new Ext.data.HttpProxy({
url: GET_STUDY_DATASET_URL
}),

reader: new Ext.data.JsonReader({
id: 'id',
totalProperty: 'data.total',
root: 'data.results'
}, recordType)
});


var filters = new Ext.ux.grid.GridFilters({filters:[
#foreach($factor_uid in $factor_list)
#if($factor_list.size()==1)
{type: 'string', dataIndex: '$factor_name_map.get($factor_uid)'}
#else
{type: 'string', dataIndex: '$factor_name_map.get($factor_uid)'},
#end
#end

#set($loopCounter=1)
#foreach($variate_uid in $variate_list)
#if($loopCounter==$variate_list.size())
{type: 'string', dataIndex: '$variate_name_map.get($variate_uid)'}
#else
{type: 'string', dataIndex: '$variate_name_map.get($variate_uid)'},
#end
#set($loopCounter=$loopCounter+1)
#end
]});

var cm = createColumnModel(cm);
cm.defaultSortable = true;

var grid = new Ext.grid.GridPanel({
id: 'example',
ds: ds,
cm: cm,
enableColLock: false,
loadMask: true,
view: new Ext.grid.GridView(),
plugins: filters,
height:400,
width:700,
el: 'dataset_grid',

bbar: new Ext.PagingToolbar({
store: ds,
pageSize: 20,
displayInfo: true,
displayMsg: "Displaying {0} - {1} of {2}",
emptyMsg: "No results to display",
plugins: filters
})
});
grid.render();

ds.load({params:{start: 0, limit: 20}});
});

setStatusMessage("dataset_indicator","&nbsp;");
Ext.getCmp('center').getComponent('study-obs-tab').show();

</script>



This one is the how I "layed" out the initial page. Once I get things up I'll try and put it up in a live server.


koioslayout = new Ext.Viewport({
layout:'border',
items:[
new Ext.TabPanel({
region:'center',
id:'center',
deferredRender:false,
activeTab:0,
items:[{
id: 'intro',
contentEl:'introTab',
title: 'Introduction',
closable:true,
autoScroll:true
},{
id: 'study-tab',
contentEl:'studyTab',
title: 'Study Tab',
autoScroll:true
}]
})
]
});


All the basic grid functionalities are working as expected, the filters don't work yet...
Attached are some screenshots.
Anyone have any tips on how to process the filter value(s) sent by the grid? I have some ideas already but any tip is useful.

mjhaston
7 Feb 2008, 6:45 AM
Wondering if anything with my filters jumps out at anyone. They don't appear to be working. It does the reload, but doesn't actually filter!

I'd also like to find an example of passing the filter string or a parm back to the server program to do the filter there, if that's possible. I made my way most of the way through this huge thread and didn't find anything that I thought was what I needed.

TIA.




<html>
<head>
<script type="text/javascript" src="/ajax/ext2/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="/ajax/ext2/ext-all.js"></script>

<script type="text/javascript" src="/ajax/ux/menu/EditableItem.js"></script>
<script type="text/javascript" src="/ajax/ux/menu/RangeMenu.js"></script>

<script type="text/javascript" src="/ajax/ux/grid/GridFilters.js"></script>
<script type="text/javascript" src="/ajax/ux/grid/filter/Filter.js"></script>
<script type="text/javascript" src="/ajax/ux/grid/filter/StringFilter.js"></script>
<script type="text/javascript" src="/ajax/ux/grid/filter/DateFilter.js"></script>
<script type="text/javascript" src="/ajax/ux/grid/filter/ListFilter.js"></script>
<script type="text/javascript" src="/ajax/ux/grid/filter/NumericFilter.js"></script>
<script type="text/javascript" src="/ajax/ux/grid/filter/BooleanFilter.js"></script>
<script type="text/javascript" src="JsonResponseReader.js"></script>

<script type="text/javascript">
Ext.onReady(function(){
Ext.ux.menu.RangeMenu.prototype.icons = {
gt: '/ajax/img/greater_then.png',
lt: '/ajax/img/less_then.png',
eq: '/ajax/img/equals.png'
};
Ext.ux.grid.filter.StringFilter.prototype.icon = '/ajax/img/find.png';

var ds = new Ext.data.GroupingStore({
proxy: new Ext.data.HttpProxy({
url:'/cgidev2p/ajax66c'
}),
reader: new Ext.data.JsonReader({
totalProperty: "results",
root: "rows",
id: "id"
}, Ext.data.Record.create([
{name: 'company'},
{name: 'customer'},
{name: 'season'},
{name: 'style'},
{name: 'whlsale', type: 'float'},
{name: 'msrp', type: 'float'},
{name: 'cost', type: 'float'},
{name: 'retail', type: 'float'},
{name: 'units', type: 'float'}
])),

groupField: 'style',
sortInfo: {field: 'company', direction: 'ASC'},
remoteSort: true
});

var filters = new Ext.ux.grid.GridFilters({filters:[
{type: 'string', dataIndex: 'company'},
{type: 'string', dataIndex: 'customer'},
{type: 'string', dataIndex: 'season'},
{type: 'string', dataIndex: 'style'},
{type: 'numeric', dataIndex: 'whlsale'},
{type: 'numeric', dataIndex: 'msrp'},
{type: 'numeric', dataIndex: 'cost'},
{type: 'numeric', dataIndex: 'retail'},
{type: 'numeric', dataIndex: 'units'}
]});

var cm = new Ext.grid.ColumnModel([

{header: "Company", sortable: true, dataIndex: 'company'},
{header: "Customer", sortable: true, dataIndex: 'customer'},
{header: "Season", sortable: true, dataIndex: 'season'},
{header: "Style", sortable: true, dataIndex: 'style'},
{header: "Wholesale", sortable: true, renderer: Ext.util.Format.usMoney, dataIndex: 'whlsale'},
{header: "MSRP", sortable: true, renderer: Ext.util.Format.usMoney, dataIndex: 'msrp'},
{header: "Cost", sortable: true, dataIndex: 'cost', renderer: Ext.util.Format.usMoney},
{header: "Retail", sortable: true, dataIndex: 'retail', renderer: Ext.util.Format.usMoney},
{header: "Units", sortable: true, dataIndex: 'units'}
]);
cm.defaultSortable = true;

var grid = new Ext.grid.GridPanel({
id: 'example',
ds: ds,
cm: cm,
enableColLock: false,
stripeRows: true,
loadMask: true,
view: new Ext.grid.GroupingView(),
forceFit:true,
plugins: filters,
title:'Product Selling Report',
height:575,
width:900,
el: 'grid-example',
bbar: new Ext.PagingToolbar({
store: ds,
pageSize: 20,
displayInfo: true,
displayMsg: 'Displaying records {0} - {1} of {2}',
emptyMsg: "No records to display",
plugins: filters
})
});
grid.render();

ds.load({params:{start: 0, limit: 20}});
});
</script>

<style type="text/css" title="currentStyle" media="screen">
@import "/ajax/ext2/resources/css/ext-all.css";

.x-grid3-hd-row td.ux-filtered-column {
font-style: italic;
font-weight: bold;
}
</style>
</head>

<body>
<div id="grid-example" style="margin: 10px;"></div>
</body>
</html>

hendricd
7 Feb 2008, 6:54 AM
@mjhaston - grid setup looks good. What about your serverside script/response? That's where the filtering actually takes place (if filters.local === false).

akannu
7 Feb 2008, 7:26 AM
Fantastic job Ambience.
BTW, problems like krycek has noticed, are the reason for what i prefer a separate panel/region/whatever for filtering, instead of rendering it on columns menu.

One of our developers is able to insert form fields into the column headers and we are actively pursuing the possibility of creating a separate filter row at the top. I am sure we will have to deal with some limitations (like clicking to sort may not work since the click event is swallowed for form field focus, however right mouse still works to sort). If anyone else has gone down this path and have success story to share, it would be greatly appreciated.

mjhaston
7 Feb 2008, 8:20 AM
@mjhaston - grid setup looks good. What about your serverside script/response? That's where the filtering actually takes place (if filters.local === false).

My serverside script doesn't handle the filters right now, but easily could. What is the parm that I send over that holds the filter? What does that string look like? Or is that something I need to build myself?

Thank you for the quick reply.

hendricd
7 Feb 2008, 8:29 AM
No, Gridfilters assembles those filter arguments and adds them to the request params. You should see them passed/encoded during your store.load. Use Firebug to see what params are POSTed.

Again, filtering is generally handled by you server.

mjhaston
7 Feb 2008, 8:50 AM
Wow, what a great tool! Never knew I could see the POST. This will come in handy.

Here's what I see. I want to create an SQL statement fro this and I'm assuming that if this was a query string it would look like:

dir="ASC"&limit="20"&sort="company"

I'm not quite sure what the filter is going to come over as? Is that an array?



dir ASC
filter[0][data][type] string
filter[0][data][value] 003
filter[0][field] style
limit 20
sort company
start 0

hendricd
7 Feb 2008, 8:59 AM
Activate a filter, fill in something, and watch the POST params again, you'll see the format.

There are some examples of SQL queries using those params (in this thread I think) search around.

mjhaston
7 Feb 2008, 9:19 AM
That's what I did to get this POST data. I activated the "style" filter.



dir ASC
filter[0][data][type] string
filter[0][data][value] 003
filter[0][field] style
limit 20
sort company
start 0



Is there a way to change my submit to GET to see the query string? I'm sorry if these are very novice questions. I'm going to search around for "params".

Thanks again.

hendricd
7 Feb 2008, 9:24 AM
store.load({params:{}, method:'GET'});

ambience
7 Feb 2008, 9:53 AM
There is no way to filter the grid data without a HttpProxy?

It should not be dependent on the HttpProxy, I am passing the filter information to the store and that information should be provided to any proxy used by the store.

mjhaston
7 Feb 2008, 11:49 AM
store.load({params:{}, method:'GET'});

Ok, not sure if this is the way to go, but since I can't really parse an array in *my world* that I know of ... I resorted to working with what I saw in the post. Which is probably what you were trying to get me to realize!

I bring my parms in like this and it works:



direction = zhbGetVar( 'dir' );
value = zhbGetVar( 'filter[0][data][value]' );


Thank you for putting up with me.

hendricd
7 Feb 2008, 12:10 PM
@mjhaston -- If you'd like to encode the params to suite your needs, shop around this post (http://extjs.com/forum/showthread.php?p=89375#post89375) (on this thread) for some options.

thatcoder
7 Feb 2008, 10:40 PM
With 2.0.1 i'm getting an error
input.match is not a function on 5743 when attempting to filter the grid on the date field. It is chocking on case "d":

arya009
8 Feb 2008, 12:50 AM
any one???? :-/ :-/ :-/


I am not able to get this plugin work. when i give any search criteria it is not filtering. In date filter it is not showing calendar

this is my code


/******************************************************************************************************/
var PC = {
init: function(){
var primaryKey = 'id';
var ps = 50;
Ext.QuickTips.init();

var js = new Ext.data.JsonStore({
url: 'ExtGetData.aspx',
baseParams:{task: "PC"},
root: 'data',
id: 'id',
fields: [
{name: 'Submitted', mapping: 'ReimbursementDate', type: 'date'} ,
{name: 'Participant', mapping: 'Name'},
{name: 'GroupAlias', mapping: 'groupalias'},
{name: 'ID', mapping: 'id'},
{name: 'Amount', mapping: 'Amount', type: 'float'},
{name: 'Source', mapping: 'Source'},
{name: 'SourceStatus', mapping: 'SourceStatus'},
{name: 'recordSelect'}
]


});


js.on('load',function()
{
var ds = new Ext.data.Store({
proxy: new Ext.ux.data.PagingMemoryProxy(js.reader.jsonData),
reader: js.reader,
remoteSort: true
});

var sm1 = new Ext.grid.CheckboxSelectionModel({singleSelect:false});
var sm = new Ext.grid.CheckboxSelectionModel({
singleSelect:false //,
// listeners: {
// rowselect: function(sm, row, rec) {
// //alert(rec.data.Participant);
// }
// }
});


/* Grid Filter */
Ext.ux.menu.RangeMenu.prototype.icons = {
gt: '../Images/GridFilter/greater_then.png',
lt: '../Images/GridFilter/less_then.png',
eq: '../Images/GridFilter/equals.png'
};

Ext.ux.grid.filter.StringFilter.prototype.icon = '../Images/GridFilter/find.png';

var filters = new Ext.ux.grid.GridFilters({
filters:
[
{type: 'date', dataIndex: 'Submitted'},
{type: 'string', dataIndex: 'Participant'},
{type: 'string', dataIndex: 'GroupAlias'},
{type: 'String', dataIndex: 'ID'},
{type: 'numeric', dataIndex: 'Amount'}
]
});

/* End Grid Filter */

var menuExport = new Ext.menu.Menu({
id: 'exportMenu',
items: [{
text: 'Excel',
handler: exportExcel
},{
text: 'PDF'
},{
text: 'CSV'
}]
});




// Define Column Model of the Grid
var cm = new Ext.grid.ColumnModel([
{header: 'Submitted', dataIndex: 'Submitted', sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y')},
{header: 'Participant', dataIndex: 'Participant', sortable: true},
{header: 'GroupAlias', dataIndex: 'GroupAlias', sortable: true},
{header: 'ID', dataIndex: 'ID', sortable: true, renderer: renderClaim},
{header: 'Amount ($)', dataIndex: 'Amount', sortable: true, align: 'right', renderer: Ext.util.Format.usMoney },
sm
]);





// Define Paging Toolbar for the Grid
var paging = new Ext.PagingToolbar({
pageSize: ps,
store: ds,
displayInfo: true,
displayMsg: 'Displaying Pending Claims {0} - {1} of {2}',
emptyMsg: "No Pending Claims to display",
plugins: filters
});



var myGrid = new Ext.grid.GridPanel({
el:'pending-grid',
store: ds,
id: 'myGrid',
cm: cm,
title: 'Pending Grid',
width: 990,
height: 600,
loadMask: true,
sm: sm,
stripeRows: true,
viewConfig:
{
forceFit:true,
enableRowBody:false,
showPreview:false
},
plugins: filters,
bbar: paging ,
tbar: mtb = new Ext.Toolbar(
{
height: 25,
items: [
{
text: 'Process',
tooltip: 'Click to Process selected row(s)',
handler: function(){
// Some Action
}
}
}, '-',
{
text: 'Cancel',
tooltip: 'Click to Cancel',
handler: function(){
//
}
}, '-',
{
text: 'Export',
tooltip: 'Export to Excel/PDF/CSV',
menu: menuExport //,
}
]
})
});

myGrid.render();

ds.load({params:{start:0, limit:ps}});
}); // js.on

js.load();

// pluggable renders
function renderClaim(value, p, record){
return String.format('<a href="javascript:ViewClaim(\'{0}\');">{0}</a>',value);
}

function exportExcel(){

}

} // init function end
}; // var PC end

Ext.onReady(PC.init, PC);

mjhaston
8 Feb 2008, 6:38 AM
@mjhaston -- If you'd like to encode the params to suite your needs, shop around this post (http://extjs.com/forum/showthread.php?p=89375#post89375) (on this thread) for some options.


Thanks for the direction. I'll be checking into that because I do want to do it the correct way and be able to accept multiple filters.

I've got this working in Firefox, but now it's not working in IE. I have a feeling the POST in IE looks a little different than it does in Firefox. The filters aren't working in IE, but they are in Firefox. Currently I'm only handling one filter.

mjhaston
8 Feb 2008, 7:49 AM
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;
}

window.open('get_pdf?'+
Ext.urlEncode(
Ext.apply(
grid.filters.buildQuery(grid.filters.getFilterData() )
,sorts)
) );



hendricd, I'm not sure where to place this? Is this what you were pointing out?

hendricd
8 Feb 2008, 8:23 AM
No, someone wanted to encode the current filters in effect and request a PDF file with them, that's all.

What I was driving at with the post (#154) I referred was another way of encoding filters that makes use on server-side more intuitive:

key-datatype-fieldname[-operand]: value

The param name format is broken down as:

key (usually 'filter', but matches the definable GF.paramPrefix) -
datatype (of the field eg, date, etc..) -
fieldname (the SQL fieldname usually: customerName ) -
operand ( optional for certain datatypes eg: 'before', 'after', 'dateTime' )
: value (the filter value )

like:
filter-string-customerName :'ABC'

Then, serverside, you would simply parse out the param name to get any details you needed for the query.

mjhaston
8 Feb 2008, 10:17 AM
Ok. Using Firefox I was able to get the first filter this way:



direction = zhbGetVar( 'dir' );
value = zhbGetVar( 'filter[0][data][value]' );


zhbGetVar in the CGIDEV2 toolkit I'm using does the parsing of the variable for me. I have a feeling that IE is naming this field differently. I just can't see it!

I'll check this out: key-datatype-fieldname[-operand]: value

zonereseau
8 Feb 2008, 1:23 PM
Hi, I've been working on a multiple grid filter too.

I'm having a little problem with it in firefox, I think the way I'm using it could be a good improvement...

Could someone help me to correct my bug ?

I post information here :
http://extjs.com/forum/showthread.php?t=24260&highlight=zonereseau

Tanks

hendricd
8 Feb 2008, 1:29 PM
@zonereseau -- What does your filter have to do with GridFilters (this thread)?

6epcepk
9 Feb 2008, 10:50 AM
Can anybody share latest backend server filter class?
Thanks.

techwolf
9 Feb 2008, 2:37 PM
This filter is really fantastic. Is there any way to determine which version you have? Perhaps add a comment at the top of Filter.js or GridFilter.js indicating version number?

mjhaston
11 Feb 2008, 6:44 AM
No, someone wanted to encode the current filters in effect and request a PDF file with them, that's all.

What I was driving at with the post (#154) I referred was another way of encoding filters that makes use on server-side more intuitive:

key-datatype-fieldname[-operand]: value

The param name format is broken down as:

key (usually 'filter', but matches the definable GF.paramPrefix) -
datatype (of the field eg, date, etc..) -
fieldname (the SQL fieldname usually: customerName ) -
operand ( optional for certain datatypes eg: 'before', 'after', 'dateTime' )
: value (the filter value )

like:
filter-string-customerName :'ABC'

Then, serverside, you would simply parse out the param name to get any details you needed for the query.



This is good stuff. I can work with this no problem on the serverside. Thanks again for helping a newbie out. Hopefully someday I'll be able to contibute to some of the answers in this forum instead of just asking questions!

Shmoo
11 Feb 2008, 7:18 PM
Can you share the server-side filter-processing codes? It would be nice for the community as well. :D

mjhaston
12 Feb 2008, 9:04 AM
Can you share the server-side filter-processing codes? It would be nice for the community as well. :D

Me? I'm not sure it would help too many as I'm writing code on an IBM iSeries (AS/400) to do the processing. I'm just using SQL to build a dynamic statement, the same way you would on other systems, but the way I parse out and grab my variables is different.

Here is one thing that stumped me, but is easy. I'm just not the greatest SQL programmer just yet! This is my SQL code to get the total record count for my view. Someone wrote in a thread that they'd need to roll through their file twice to get this and didn't want to. You can get the count this way (obviously use your own file and field names):



select
count(*) from
(
select
PR01S,
PR01C,
PR01D,
PR01CUS,
PR01IP,
PR01I1,
PR01I2

from *libl/pr0100

where
pr01qtyt <> 'QU' and pr01cus <> ' '

group by
PR01S,
PR01C,
PR01D,
PR01CUS,
PR01IP,
PR01I1,
PR01I2

having PR01I1 = '00378'

) as count

mjhaston
12 Feb 2008, 9:19 AM
@hendricd - Hopefully one final question. I can't seem to "clear" my filters. I can uncheck and clear out the filter box, but when I check Firebug it still has the filter-string-customerName :'ABC' being sent in the POST.

hendricd
12 Feb 2008, 10:01 AM
@mjhaston -- If you're using the approach outlined earlier, you will need to override the regexp used to remove existing filter params before the current (active) filters are serialized:



/**
* Removes filter related query parameters from the provided object.
*
* @param {Object} p Query parameters that may contain filter related fields.
*/
cleanParams: function(p){
var regex = new RegExp("^" + this.paramPrefix + "-"); //loose but adequate
for(var key in p)
if(regex.test(key))
delete p[key];
},

mjhaston
12 Feb 2008, 10:28 AM
Awesome! Thanks a bunch for the help. I just have to accomodate more than one filter on my serverside and this will be functioning the way I want.

I guess next thing to try is opening this in a panel by clicking in a West nav section. And then I'd like to export this to Excel or CSV. I've been eyeballing a few topics on each. The export doesn't seem like much more than POSTing the form to a different url and letting the serverside build the file.

KGL
13 Feb 2008, 4:55 AM
thanks tatcoder.

No it works without an error. I just had to find out that that displayed date is a different one than the one that is used for filtering. I used a renderer to the format d.m.Y but the internal format was Y-m-d hh:mi. Now I use the ISO8601Long-Format from your patterns and everything is fine.

Thanks a lot

KGL

mfrancey
13 Feb 2008, 11:36 AM
It should not be dependent on the HttpProxy, I am passing the filter information to the store and that information should be provided to any proxy used by the store.

Sorry, I had an error on my JSON page, everything is fine now

mfrancey
13 Feb 2008, 11:46 AM
Hi,

I searched the whole forum to find a solution for saving the last state of filtering without success.
It's automatically made for sorting (I think through a cookie system), but is it possible to also store the last filtering state ?

Thanks for helping me using the very usefull plugin

\:D/

ambience
13 Feb 2008, 12:03 PM
Hi,

I searched the whole forum to find a solution for saving the last state of filtering without success.
It's automatically made for sorting (I think through a cookie system), but is it possible to also store the last filtering state ?

Thanks for helping me using the very usefull plugin

\:D/

The latest version *should* do this provided you give the filter the plugin is attached to a stateId. I have not had a chance to do anything but preliminary testing

mfrancey
13 Feb 2008, 12:14 PM
The latest version *should* do this provided you give the filter the plugin is attached to a stateId. I have not had a chance to do anything but preliminary testing

How to call this stateId ? Would you have an exemple?

ambience
13 Feb 2008, 12:50 PM
Made a small update, grab the latest version and the specify a 'stateId' in your grids config.

mfrancey
13 Feb 2008, 1:19 PM
Made a small update, grab the latest version and the specify a 'stateId' in your grids config.

Thanks ambience!

It seems to work fine!!!!!! Wonderful... I'll be keeping testing it and will tell you if I find any bug.

Great job, great functionnality, great plugin !!!

:D

6epcepk
13 Feb 2008, 7:25 PM
ambience
Can you attach latest server-side class for filtering with ine query-example? Thanks.

ambience
14 Feb 2008, 10:40 AM
Guys, I'm sorry. I can not give out the server code for this. The real implementation is in Java and property of Controlpath. I would love to share it, but my hand are tied. The PHP code is *very* hacked together in order to make the example work and it is fairly dependent on a much larger framework. Again, sorry. This will be the last time I respond to any questions regarding the server side implementation.

If some one else wants to share a proper reference PHP implementation I will gladly link to it in the OP.

george.antoniadis
15 Feb 2008, 3:36 AM
Grid filter is just AWESOME ! ^_^
Amb gratz on this...

now...
Making autogrid play nice with grid filter :P

But plugins are very nice written and making them work together is a breeze...

open up autogrid.js, find "this.view.hmenu.add(" and above it add...



if(meta.filters !== undefined)
{
for(var i = 0, len = meta.filters.length; i < len; i++)
{
d = meta.filters[i];
if((d.type !== undefined)&&(d.dataIndex !== undefined)){
this.filters.addFilter(d);
}
}
}


then just add one more array to your JSON data called filter with types and dataIndexs and you are set...

I really don't think there is something wrong with this but I didn't give it much testing... (less than 2 mins tbh! ^_^)

so if anyone can think of why it shouldn't be so simple let me know :P

luv2hike
15 Feb 2008, 5:57 AM
This rocks! Thank you for posting it. I did find one small issue that I cannot seem to resolve. It acts quirky in Camino (OS/X browser). By that I mean the filter popup menu (using a ListFilter) doesn't stay displayed and the highlight does not show up where the mouse points. So it is hard to tell what you are clicking plus you have to do so very fast or the window goes away until you click on Filters again in the header menu. It works perfectly in Firefox on both OS/X and Linux though!



<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Bowflex</title>
<link rel="stylesheet" type="text/css" href="resources/css/ext-all.css"/>

<style type="text/css">
.x-btn-center:hover {
background: white url(gradedtanbutton.gif) repeat-x scroll left bottom;
}
.x-tab-strip span:hover {
background-color: lightblue;
background-image: none;
}
.x-grid3-body {
background: #bacfff;
}
.x-grid3-scroller {
background: #bacfff;
}
.x-grid3-row {
background-color: white;
background-image: none;
border: thin solid lightgray;
}
.x-grid3-row-alt {
background-color: lightgray;
background-image: none;
}
.x-grid3-row-selected {
background-color: orange !important;
background-image: none;
}
.x-grid3-row-over {
background-color: lightblue;
background-image: none;
}
.x-grid3-header-offset {
background-color: #bacfff;
background-image: none;
}
.x-grid3-hd-inner, .x-grid3-hd-row td {
background: #EBF3FD url(resources/images/default/grid/grid3-hrow-over.gif) repeat-x scroll left bottom;
}
td.x-grid3-hd-over .x-grid3-hd-inner, td.x-grid3-hd-menu-open .x-grid3-hd-inner {
border: thin solid blue;
}
.x-layout-split, .x-layout-cmini-south, .x-layout-cmini-east {
background: darkblue;
}
.x-panel-btns-ct {
background: #bacfff;
}
</style>

<script type="text/javascript" src="adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="ext-all.js"></script>
<script type="text/javascript" src="RowExpander.js"></script>
<script type="text/javascript" src="ux/grid/GridFilters.js"></script>
<script type="text/javascript" src="ux/grid/filter/Filter.js"></script>
<script type="text/javascript" src="ux/grid/filter/ListFilter.js"></script>

<script type="text/javascript">
var spanel;
var workgrid;
var repsStore;
var grid;
var queryForm;

Ext.onReady(function()
{
var workData = [
[36,'2008-02-23'],
[38,'2008-02-14'],
[37,'2008-02-14'],
[35,'2008-02-11'],
[34,'2008-01-28'],
[33,'2008-01-21'],
[32,'2008-01-16'],
[31,'2008-01-14'],
[30,'2008-01-11'],
[29,'2008-01-09'],
[28,'2008-01-07'],
[27,'2008-01-04'],
[26,'2008-01-02'],
[25,'2007-12-21'],
[24,'2007-12-19'],
[23,'2007-12-17'],
[22,'2007-12-12'],
[21,'2007-12-10'],
[20,'2007-12-08'],
[19,'2007-12-05'],
[18,'2007-12-03'],
[17,'2007-11-30'],
[16,'2007-11-28'],
[15,'2007-11-26'],
[14,'2007-11-16'],
[13,'2007-11-12'],
[12,'2007-11-09'],
[11,'2007-11-07'],
[10,'2007-11-05'],
[9,'2007-11-02'],
[8,'2007-10-31'],
[7,'2007-10-29'],
[6,'2007-10-25'],
[5,'2007-10-23'],
[4,'2007-10-21'],
[3,'2007-10-18'],
[2,'2007-10-16'],
[1,'2007-10-11']
];

// row expander
var expander = new Ext.grid.RowExpander(
{
tpl : new Ext.Template('<div id="myrow-{workoutID}"></div>')
});

// an item in the grid has been selected
function expandedRow(obj, record, body, rowIndex)
{
id = "myrow-" + record.get("workoutID");
id2 = "mygrid-" + record.get("workoutID");

var reader2 = new Ext.data.ArrayReader({},
[
{ name: 'repID' },
{ name: 'exercise' },
{ name: 'bench' },
{ name: 'lifts' },
{ name: 'weight' }
]);

repsStore = new Ext.data.Store(
{
reader: reader2,
sortInfo: { field: "repID", direction: "ASC" },
autoLoad: true,
proxy: new Ext.data.HttpProxy(new Ext.data.Connection(
{
url: "getReps.jsp",
method: "POST",
extraParams: { id:record.get("workoutID") }
}))
});

var gridX = new Ext.grid.GridPanel(
{
store: repsStore,
columns: [
{ id:'idXX', header: 'ID', width: 50, sortable: true, dataIndex: 'repID' },
{ id: 'exer', header: 'Exercise', width: 120, sortable: true, dataIndex: 'exercise' },
{ header: 'Bench', width: 80, sortable: true, dataIndex: 'bench' },
{ header: 'Lifts', width: 60, sortable: true,
editor: new Ext.form.TextField({ allowBlank: false }),
dataIndex: 'lifts' },
{ header: 'Weight', width: 75, sortable: true,
editor: new Ext.form.TextField({ allowBlank: false }),
dataIndex: 'weight' }
],
viewConfig: {
forceFit:true
},
autoExpandColumn: 'exer',
width: 370,
height: 190,
id: id2,
title: 'Details for '+record.get("workoutDate").format('m/d/Y'),
renderTo: body,
frame: true,
tbar: [
{
text: 'Add Set',
handler: function()
{
gridX.getSelectionModel().clearSelections();
spanel.setTitle("Add a Set");
spanel.expand();
spanel.load(
{
url: "repDetails.jsp",
params: { workoutID: record.get("workoutID") },
scripts: true
});
},
tooltip: 'Click to add a new set.'
}]
});

gridX.on('rowClick', function(thegrid, row, e)
{
spanel.setTitle("Edit Set Details");
spanel.expand();
spanel.load(
{
url: "repDetails.jsp",
params: { workoutID: record.get("workoutID"), repID: thegrid.getStore().getAt(row).get("repID") },
scripts: true
});
});

gridX.render(id);
gridX.getEl().swallowEvent(['mousedown', 'click', 'dblclick']);
}

expander.on("expand", expandedRow);

var Workout = Ext.data.Record.create([
{ name: 'workoutID', type: 'int' },
{ name: 'workoutDate', type: 'date', dateFormat: 'Y-m-d' },
{ name: 'filler' }
]);

var workReader = new Ext.data.ArrayReader({}, Workout);

var workStore = new Ext.data.Store({
data: workData,
reader: workReader,
sortInfo: { field: "workoutDate", direction: "DESC" }
});

workgrid = new Ext.grid.EditorGridPanel({
store: workStore,
columns: [
expander,
{ id: 'Id', header: 'ID', width: 50, sortable: true, dataIndex: 'workoutID' },
{ header: 'Workout Date', width: 120, sortable: true,
editor: new Ext.form.DateField({ allowBlank: false }),
renderer: Ext.util.Format.dateRenderer('m/d/Y'),
dataIndex: 'workoutDate' },
{ id: 'filler', header: ' ', width: 180, hideable: false, resizable: false, sortable: false, dataIndex: 'filler' }
],
viewConfig: {
forceFit: true
},
autoExpandColumn: 'filler',
renderTo: 'work',
stripeRows: false,
frame: true,
clicksToEdit: 1,
plugins: expander,
tbar: [
{
id: 'plus',
text: 'Add Workout',
handler: function()
{
var w = new Workout(
{
workoutID: 0,
workoutDate: new Date()
});
workgrid.stopEditing();
workStore.insert(0, w);
workgrid.startEditing(0, 2);
},
tooltip: 'Click to begin a new workout.'
},
{
text: 'Save Changes',
handler: function()
{
workStore.commitChanges();
},
tooltip: 'Click to save all changes.'
}
]
});

workStore.on('update', function(thestore, record, operation)
{
if(operation == Ext.data.Record.COMMIT)
{
var sortstate = thestore.getSortState();

Ext.Ajax.request(
{
url: "saveWorkout.jsp",
params: { workoutId: record.get("workoutID"), workoutDate: Ext.util.Format.date(record.get("workoutDate"), "Y-m-d") },
success: function(response, options)
{
record.data.workoutID = response.responseText;
thestore.sort(sortstate.field, sortstate.direction);
}
});
}
});

var myData = [
[27,'AA and once again','incline'],
[44,'AA Another test','rowing'],
[11,'Ab Crunch','flat'],
[31,'AB new event handler','rowing'],
[30,'AC New Handler','squat'],
[32,'Again...','rowing'],
[25,'AND and again','incline'],
[50,'And now make it paint','squat'],
[22,'Another new key 2','rowing'],
[24,'another new one','incline'],
[46,'AY huh Do it Now','incline'],
[43,'AZ testing panel load','incline'],
[45,'AZB testing panel load','flat'],
[6,'Bench Press','incline'],
[13,'Chinups','squat'],
[33,'Did it finally work?','rowing'],
[29,'Double Commit','flat'],
[36,'Final Sorting Test','leg'],
[49,'Fix sort error and Repaint','flat'],
[17,'Friday 1','leg'],
[18,'Friday 2','rowing'],
[21,'Get the key','flat'],
[8,'Leg Extension','leg'],
[7,'Leg Press','rowing'],
[1,'Lying Biceps Curl','flat'],
[2,'Lying Shoulder Press','flat'],
[23,'new one','flat'],
[38,'Now without a sort','squat'],
[26,'one more time','incline'],
[14,'pushups','flat'],
[37,'Really last sort test','incline'],
[3,'Rear Deltoid Rows','flat'],
[4,'Reverse Fly','flat'],
[10,'Seated Ab Crunch','incline'],
[9,'Seated Shoulder Press','flat'],
[5,'Seated Triceps Extension','incline'],
[48,'Slimline','incline'],
[12,'Squat','squat'],
[19,'Test add 1','rowing'],
[20,'test add 2','flat'],
[39,'Test Commit single','flat'],
[34,'Test the sort','flat'],
[35,'testing sort again','rowing'],
[15,'the first test','incline'],
[16,'Thursday night test','incline'],
[40,'Tuesday 1','flat'],
[41,'Tuesday 2','leg'],
[42,'Tuesday 3','squat'],
[47,'ZZ Top','squat']
];

var Exercise = recdef = Ext.data.Record.create([
{name: 'exerID', type: 'int'},
{name: 'exerName'},
{name: 'bench'}
]);

var myReader = new Ext.data.ArrayReader({}, Exercise);

var store = new Ext.data.Store({
proxy: new Ext.data.MemoryProxy(myData),
reader: myReader,
autoLoad: true,
sortInfo: { field: "exerName", direction: "ASC" }
});

var filters = new Ext.ux.grid.GridFilters(
{
local: true,
filters:[
{
type: 'list',
dataIndex: 'bench',
options: ['flat','incline','leg','rowing','squat']
}
]
});

grid = new Ext.grid.EditorGridPanel({
store: store,
columns: [
{header: 'ID', width: 30, sortable: true, dataIndex: 'exerID'},
{header: 'Exercise Name', width: 120, sortable: true, dataIndex: 'exerName', editor: new Ext.form.TextField({ allowBlank: false })},
{header: 'Bench Position', width: 80, sortable: true, dataIndex: 'bench',
editor: new Ext.form.ComboBox({ // dropdown based on client side data (from html)
editable: false,
triggerAction: 'all',
lazyInit: false,
lazyRender: true,
transform: 'benchposID' // look for this id to transform the html option values to a dropdown
})
}
],
viewConfig: {
forceFit: true
},
renderTo: 'exer',
stripeRows: false,
frame: true,
clicksToEdit: 1,
plugins: filters,
tbar: [
{
text: 'Add Exercise',
handler: function()
{
var e = new Exercise(
{
exerID: 0,
exerName: "",
bench: ""
});
grid.stopEditing();
store.insert(0, e);
grid.startEditing(0, 1);
},
tooltip: 'Click to add a new exercise.'
},
{
text: 'Save Changes',
handler: function()
{
store.commitChanges();
},
tooltip: 'Click to save all changes.'
}
]
});

store.on('update', function(thestore, record, operation)
{
if(operation == Ext.data.Record.COMMIT)
{
var sortstate = thestore.getSortState();

Ext.Ajax.request(
{
url: "saveExerciseRow.jsp",
params: { exerId: record.get("exerID"), exerName: record.get("exerName"), bench: record.get("bench") },
success: function(response, options)
{
record.data.exerID = response.responseText;
thestore.sort(sortstate.field, sortstate.direction);
}
});
}
});

var tabPanelWidth = 430;

var viewport = new Ext.Viewport(
{
layout:"border",
items:[
{
region:"north",
title:"Bowflex Workout Database",
bodyStyle:"background-color:#bacfff",
height:20
},
spanel = new Ext.Panel({
region: "east",
bodyStyle: "background-color:#bacfff",
title: " ",
width: 400,
autoScroll: true,
collapsible: true,
collapseMode: 'mini',
collapsed: true,
hideCollapseTool: true,
split: true
}),
new Ext.TabPanel({
region: 'center',
deferredRender: false,
minWidth: tabPanelWidth,
activeTab: 0,
items:[
// workouts tab grid
new Ext.Panel({
layout:'border',
title: 'Workouts',
items:[
new Ext.Panel({
layout: 'fit',
region: 'west',
width: tabPanelWidth,
items: [ workgrid ]
}),
{
region:'center',
bodyStyle:"background-color:#bacfff"
}
]
}),
// exercises tab grid
new Ext.Panel({
layout:'border',
title: 'Exercises',
items:[
new Ext.Panel({
layout: 'fit',
region: 'west',
width: tabPanelWidth,
items: [ grid ]
}),
{
region:'center',
bodyStyle:"background-color:#bacfff"
}
]
}),
// query form tab
new Ext.Panel({
layout:'border',
title: 'Query Viewer',
items:[
new Ext.Panel({
layout: 'border',
region: 'west',
width: tabPanelWidth,
items: [
queryForm = new Ext.form.FormPanel({
region: 'north',
height: 200,
url: 'respond.jsp',
method: 'POST',
onSubmit: Ext.emptyFn,
labelAlign: "top",
bodyStyle: "background-color:#bacfff",
items: [
{
fieldLabel: 'Enter Query',
labelStyle: 'font-weight:bold;',
xtype: 'textarea',
name: 'sqlQuery',
allowBlank: false,
width: tabPanelWidth,
height: 180,
emptyText: 'Type a valid SQL query here then click Submit'
}
],
buttons: [
{
text: 'Submit',
tooltip: 'Click to submit the query,',
handler: function()
{
queryForm.getForm().submit(
{
success: function(form, action)
{
spanel.getUpdater().getEl().dom.innerHTML = action.response.responseText;
spanel.setTitle("Query Results");
spanel.expand();
}
});
}
},
{
text: 'Clear',
tooltip: 'Click to clear the query and results.',
handler: function()
{
spanel.getUpdater().getEl().dom.innerHTML = " ";
spanel.setTitle(" ");
spanel.collapse();
queryForm.getForm().reset();
}
}]
}),
new Ext.Panel({
region: 'center',
bodyStyle: "background-color:#bacfff; border:0"
})
]
}),
{
region:'center',
bodyStyle:"background-color:#bacfff"
}
]
})
]
})
]
});

// Init the singleton. Any tag-based quick tips will start working.
Ext.QuickTips.init();

// Apply a set of config properties to the singleton
Ext.apply(Ext.QuickTips.getQuickTip(), {
showDelay: 50,
dismissDelay: 0,
animCollapse: false,
trackMouse: true,
mouseOffset: [10, 10]
});
});//end onReady function
</script>

</head>

<body>
<div id="work"></div>
<div id="exer"></div>

<!-- you must define the select box here, as the custom editor for the 'Light' column will require it -->
<select name="benchPosition" id="benchposID" style="display: none;">
<option value="">Select Bench Position</option>

<option value="flat">flat</option>
<option value="incline">incline</option>
<option value="leg">leg</option>
<option value="rowing">rowing</option>
<option value="squat">squat</option>
</select>

</body>
</html>

luv2hike
15 Feb 2008, 8:20 AM
Ok, I'm able to clarify a bit. Firstly, this problem is not unique to the filter code. It also seems to happen with the standard grid header menus for sorting and hiding columns. So it is an ExtJS compatibility issue with Camino. I was able to get the menu to remain visible in use by moving the mouse to the right of the expansion arrow to the blank space where the menu should appear, then move it back to the left over the parent menu. Strange. But when the mouse sits still over any selection in the submenu, it flickers like mad.

6epcepk
15 Feb 2008, 10:28 AM
Guys, I'm sorry. I can not give out the server code for this. The real implementation is in Java and property of Controlpath. I would love to share it, but my hand are tied. The PHP code is *very* hacked together in order to make the example work and it is fairly dependent on a much larger framework. Again, sorry. This will be the last time I respond to any questions regarding the server side implementation.

If some one else wants to share a proper reference PHP implementation I will gladly link to it in the OP.
Ok, no problems :)

I have write function wich creates SQL query. Works fine with string, numeric and date column types.
Functions:

// ==================================================
// FUNCTION - BUILD FILTER QUERY
// ==================================================
function get_filter($data, $alias = false, $glue = 'AND') {

$condition = '';

$comparison = array('gt' => '>', 'lt' => '<', 'eq' => '=');

foreach ($data as $el) {

if ($el['data']['type'] === 'string') {

$condition .= get_filter_alias($el['field'], $alias) . $el['field'] . ' LIKE \'%' . $el['data']['value'] . '%\' ' . $glue . ' ';

} elseif ($el['data']['type'] === 'numeric') {

$condition .= get_filter_alias($el['field'], $alias) . $el['field'] . ' ' . $comparison[$el['data']['comparison']] . ' ' . $el['data']['value'] . ' ' . $glue . ' ';

} elseif ($el['data']['type'] === 'date') {

$timestamp = strtotime($el['data']['value']);
$condition .= get_filter_alias($el['field'], $alias) . $el['field'] . ' ' . $comparison[$el['data']['comparison']] . ' ' . $timestamp . ' ' . $glue . ' ';

}

}

$condition = (!empty($condition)) ? 'WHERE ' . $condition : '';

return rtrim($condition, ' ' . $glue . ' ');

}


// ==================================================
// FUNCTION - GET FIELD ALIAS
// ==================================================
function get_filter_alias($field, $alias) {


if (!empty($alias) && !is_array($alias)) {

return $alias . '.';

} elseif (!empty($alias) && is_array($alias)) {

return !empty($alias[$field]) ? $alias[$field] . '.' : false;

} else {

return;

}

}

Using:

$filter = (!empty($_POST['filter'])) ? get_filter($_POST['filter'], array('id' => 'A', 'date_c' => 'A', 'date_u' => 'A', 'title' => 'B')) : '';

$result = mysql_qw('
SELECT A.id FROM news A
INNER JOIN news_locale B ON B.news_id = A.id AND B.lang_id = ?
' . $filter,
$_SESSION['lang']
) or die(mysql_error());

I hope this code will helpful for anybody =)

mjlecomte
15 Feb 2008, 12:03 PM
I posted this problem in this thread before, I assume I'm doing something wrong. If I take a working grid with this plugin working filtering the grid, and then comment out one line of the "filters" var that specifies one of the column filters then the filter option no longer shows up for ANY column.
Any ideas what I'm doing wrong if this is not the expected behavior?


I'll have to run some tests, but I am on vacation for 2 weeks. So it won't be till January sorry =(

I just wanted to bump this. If you could just alter your js on the demo site that would be one way to convince me that the filters need not be applied to every column. I just never got it to work.:s

luv2hike
15 Feb 2008, 12:57 PM
You only apply filters to the columns you want filtered by using the dataIndex. See my code example (that works great for everything but Camino) a few posts above this one.

http://extjs.com/forum/showthread.php?p=124392#post124392

ambience
15 Feb 2008, 1:41 PM
I have modified another example I made to answer a question about filtereing on columns that do not exist in the grid to also filter only a few of the visible ones (name and size).

http://ccinct.com/lab/filter-grid/hidden.html

mjlecomte
15 Feb 2008, 3:04 PM
I have modified another example I made to answer a question about filtereing on columns that do not exist in the grid to also filter only a few of the visible ones (name and size).

http://ccinct.com/lab/filter-grid/hidden.html


Fair enough. Will try to see what's wrong with my code.:((

Thank you.

denkoo
15 Feb 2008, 9:07 PM
Hi,

First, thanks for this working and sharing ))

Actualy I would design my grid width indicate (like background color of colomn or icon header) whose column was filtered...

I found only this solution but it's not great :
/* info: filter.png is binocular icon */
add this Css element :

.ux-filtered-column DIV{
background-image:url(img/filter.png);
background-repeat:no-repeat;
background-position:0 4px;
padding-left:16px;
color:#008;
font-weight:700;
}
.ux-filtered-column .sort-asc DIV{
color:#008;
padding-left:14px;
font-weight:700;
}

But when you selected the column, background image disapear (normal :-)) but I would find a solution to keep it.

If you have better solution, i would be please

Thanks

b0c1
19 Feb 2008, 11:57 PM
Guys, I'm sorry. I can not give out the server code for this. The real implementation is in Java and property of Controlpath. I would love to share it, but my hand are tied. The PHP code is *very* hacked together in order to make the example work and it is fairly dependent on a much larger framework. Again, sorry. This will be the last time I respond to any questions regarding the server side implementation.

If some one else wants to share a proper reference PHP implementation I will gladly link to it in the OP.

Ohh, You use Java on server side? Great! You can tell me how can I convert the filters to array/map/etc? (/me using Spring framework 2.5) Or you write a custom parser for filter rule?

ambience
20 Feb 2008, 9:50 AM
I can't share the actual source but I can give you some idea of how it works with an pseudo interface.

Filter.java:


public abstract class Filter implements Serializable {
protected enum Direction {ASC, DESC};
protected enum Comparison {
GT(">"), LT("<"), GTE(">="), LTE("<="),
EQ("="), NEQ("!="), LIKE("LIKE"), IN("IN"), NOTIN("NOT IN");

private String sql;

Comparison(String sql){
this.sql = sql;
}

public String toString(){
return sql;
}
};

protected List<WhereClause> where;
protected String orderField;
protected Direction orderDir;
protected int offset, limit;

/**
* Where clause classes
*/
public abstract static class WhereClause<T> implements Serializable {
public String field;
public Comparison comparison;
public T value;

public WhereClause(String field, T value, Comparison comparison) {
this.field = field;
this.value = value;
this.comparison = comparison;
}

public int setFieldValue(PreparedStatement stmt, int paramOffset) throws SQLException {
return paramOffset;
}
}

public static class ListWhereClause extends WhereClause<List<String>> {
...
}

public static class NumericWhereClause extends WhereClause<Float> {
...
}

public static class StringWhereClause extends WhereClause<String>{
...
}

public static class BusinessObjectWhereClause extends WhereClause<String>{
...
}

public static class DateWhereClause extends WhereClause<Date> {
...
}

public static class BooleanWhereClause extends WhereClause<Boolean> {
...
}
}


ExtTableFilter.java


import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;

import javax.servlet.http.HttpServletRequest;

@SuppressWarnings("serial")
public class ExtTableFilter extends Filter {
private static final DateFormat DF = SimpleDateFormat.getDateInstance(DateFormat.SHORT);

public ExtTableFilter(HttpServletRequest request) throws ParseException {
this(request, true);
}

public ExtTableFilter(HttpServletRequest request, boolean paged) throws ParseException {
this(request, paged ? "start" : null, paged ? "limit" : null, "sort", "dir", "filters");
}

public ExtTableFilter(HttpServletRequest request, String offsetParam, String limitParam, String sortParam, String sortDirParam, String filtersParam) throws ParseException {
offset = offsetParam != null && request.getParameter(offsetParam) != null ? Integer.parseInt(request.getParameter(offsetParam)) : -1;
limit = offsetParam != null && request.getParameter(limitParam) != null ? Integer.parseInt(request.getParameter(limitParam)) : -1;
orderField = request.getParameter(sortParam);
orderDir = request.getParameter(sortDirParam) != null ? Direction.valueOf(request.getParameter(sortDirParam)) : null;

parseWhereClause(request);
}

private void parseWhereClause(HttpServletRequest request) throws ParseException {
this.where = new ArrayList<WhereClause>();

for(int i=0; request.getParameter("filter[" + i + "][field]")!=null; i++){
String prefix = "filter[" + i + "]";
String field = request.getParameter(prefix + "[field]");
String type = request.getParameter(prefix + "[data][type]");
String value = request.getParameter(prefix + "[data][value]");

if("string".equals(type)){
this.where.add(new StringWhereClause(field, value, Comparison.LIKE));
} else if("numeric".equals(type)) {
Comparison comp = Comparison.valueOf(request.getParameter(prefix + "[data][comparison]").toUpperCase());
this.where.add(new NumericWhereClause(field, Float.parseFloat(value), comp));
} else if("date".equals(type)){
Comparison comp = Comparison.valueOf(request.getParameter(prefix + "[data][comparison]").toUpperCase());
this.where.add(new DateWhereClause(field, new java.sql.Date(DF.parse(value).getTime()), comp));
} else if("stringList".equals(type) || "list".equals(type)){
String[] values = request.getParameterValues(prefix + "[data][value]");
this.where.add(new StringListWhereClause(field, values, Comparison.IN));
} else if("boolean".equals(type)){
this.where.add(new BooleanWhereClause(field, "1".equals(value)));
}
}
}
}


So, on the webserver you will take your request object (be it in a JSP, servlet, whatever) and create a ExtTableFilter with it. Having done this, you pass that filter to some sort of database interface (over RMI, inline, whatever) that constructs a SQL statement with the filter clauses concatenated with "AND" operators and returns the filter data. How you corral that data into XML or JSON is again, up to you ^.^

ajaxE
21 Feb 2008, 10:11 PM
By default the field is 'filter', with out the 's'. But that is configurable with the 'paramPrefix' confg option. For example:


plugins: new Ext.ux.grid.GridFilters({paramPrefix: 'omgBearIsDriving'});


Additionally, the filter param will be expressed as an array of objects for example:


filter[0][data][type]=string
filter[0][data][value]=Geek
filter[0][field]=name
filter[1][data][type]=list
filter[1][data][value]=medium,large,extra large
filter[1][field]=size


If you wish to change how the data is structured and sent to the server you can either extend GridFilters and overload the 'buildQuery' function or pass a new function as config option:



plugins: new Ext.ux.grid.GridFilters({
buildQuery: function(filters){
var p = {};
for(var i=0, len=filters.length; i<len; i++){
// Custom filter serialization
}

return p;
}
});


I still have no idea in how to get the filter name and value to pass to the server side. Please help.

For example, I did
buildQuery: function(filters){
var p = {};
for(var i=0, len=filters.length; i<len; i++){
// Custom filter serialization
alert(filters[i][data][value]);
}

return p;
}

It said data and value is not defined.

Thanks!

ambience
22 Feb 2008, 9:40 AM
Well first or foremost get firbug (http://www.getfirebug.com/). Secondly, replace alert(filters[i][data][value]); with console.log(filters) and explore the data structure. I could give you the basic structure, but teach a man to fish etc. etc.

ajaxE
23 Feb 2008, 1:28 PM
Well first or foremost get firbug (http://www.getfirebug.com/). Secondly, replace alert(filters[i][data][value]); with console.log(filters) and explore the data structure. I could give you the basic structure, but teach a man to fish etc. etc.

Thanks for teaching me fishing...:-) Everything is alright now. I like the local fiter or grouping. Only that I found it works on the page scope not the data already in the memory.

Is there a way to apply grouping and filter to all data in the memory but still keep the pagination?

Thanks!

hendricd
23 Feb 2008, 4:55 PM
@ajaxE - I use the GF coupled with an enhanced PagingMemoryProxy. It works really well.

You just need to get your data into it, and start paging....

ajaxE
24 Feb 2008, 2:21 PM
@ajaxE - I use the GF coupled with an enhanced PagingMemoryProxy. It works really well.

You just need to get your data into it, and start paging....

Thanks hendricd for giving me pointer. I will definitely try it out. The data I got from server is in the JSON format,since I need to use this PagingMemoryProxy, I will have to covert data into JS array format, correct? Did I miss understanding anything.

The reason I am asking such stupid question is that I found for the linked combo, the data get to be in the array format

LCombo.countries = [
['USA', 'United States']
,['D', 'Germany']
,['F', 'France']
,['GB', 'Great Britain']
];

If I chnage it to following, it won't work.

LCombo.countries = [
{'USA', 'United States'}
,{'D', 'Germany'}
,{'F', 'France'}
,{'GB', 'Great Britain'}
];

Do you know any thrid party lib can generate those kind JS Array format data instead of me doing it manually?

Thanks!

ajaxE
24 Feb 2008, 4:50 PM
Do you know any thrid party lib can generate those kind JS Array format data instead of me doing it manually?

Thanks!

I know how to do it in JS array format. It's quite easy. Data came from DB is already in that format. Thanks for your help.

Zyclops
24 Feb 2008, 5:49 PM
If you use a filter with paging when your on page 2 of the data, and the results of the filter give you less than 1 page of results nothing is displayed. The only solution I can think is to store an array of all the previous sort orders + filters + pagination and set it to page 1 if they change.

Any one else had this issue?

Zyclops
24 Feb 2008, 8:39 PM
If anyone's at all interested in my solution check out: http://extjs.com/forum/showthread.php?t=27361

Zyclops
25 Feb 2008, 1:49 AM
http://ccinct.com/lab/filter-grid/ << actually I can't replicate the issue on the example. i.e. goto page 2 and filter, is this done serverside?

ambience
25 Feb 2008, 9:11 AM
Yes, paging is done server side. Dealing with groups that fall over a page boundary is really a discussion about grouping as a default implementation with no filtering will exhibit similar behavior. You will most likely need to return more or less results then is defined by the paging tool bar and have some sort of intelligence on the server that assures that groups are shipped as whole units (limit x, y is not going to cut it), or as Douge pointed out ship all your data to to a memory proxy that has similar logic built in. Not sure how all of this plays out with the paging toolbar as it seems like if you have partial or excessive pages it could over or under estimate the final page count.

chernomorez
26 Feb 2008, 4:46 PM
Hi Ambience,
Do you have a sample where you programmatically set a numeric field?
Currently I try setting it like this:

filter.setValue(filterValue);
filter.setActive(true);

However, I still need to set the operation for numeric types, e.g. "gt", "lt", "eq".
Can you show how that is supposed to be done.

Thanks!


I have modified another example I made to answer a question about filtereing on columns that do not exist in the grid to also filter only a few of the visible ones (name and size).

http://ccinct.com/lab/filter-grid/hidden.html

tmartinez
28 Feb 2008, 6:18 AM
Hello,
I've a pb to use the class ExTableFilter. I don't understand how to use it.
Actually i've put theses lines on my php file:

include ('DatabaseFilter.php');
include ('ExtTableFilter.php');
$filters = new ExtTableFilter($_POST['filter']);but i have this error:

<b>Catchable fatal error</b>: Argument 1 passed to ExtTableFilter::__construct() must be an instance of Request, array givenIf someone could help me...

Thanks you

ajaxE
28 Feb 2008, 2:58 PM
@ajaxE - I use the GF coupled with an enhanced PagingMemoryProxy. It works really well.

You just need to get your data into it, and start paging....

I did that, but it still filter and group on one page only. The following is my code. Did i miss anything?

[PHP]var ds = new Ext.data.GroupingStore({
proxy: new Ext.ux.data.PagingMemoryProxy(data),
reader: myReader,
groupField: 'request',
sortInfo: {field: 'date', direction: 'DESC'},
remoteSort: false
});

var filters = new Ext.ux.grid.GridFilters({filters:[
{type: 'date', dataIndex: 'date'},
{type: 'string', dataIndex: 'customer'},
{type: 'string', dataIndex: 'request'},
{type: 'numeric', dataIndex: 'orders'},
{
type: 'list',
dataIndex: 'size',
options: ['Small', 'Medium', 'Large'],
phpMode: false
}],
local: true
});[PHP]

Thanks!!

hendricd
28 Feb 2008, 4:31 PM
@ajaxE: I think this (http://extjs.com/forum/showthread.php?p=113573#post113573) is the version you might want to try.

Although what you have may work fine if your set remoteSort:true. ;)

ajaxE
28 Feb 2008, 7:25 PM
@ajaxE: I think this (http://extjs.com/forum/showthread.php?p=113573#post113573) is the version you might want to try.

Although what you have may work fine if your set remoteSort:true. ;)

Thank you very much! I tried to set remoteSort: true. It worked somehow when I sort on column first. But not quite there yet I guess I need to set page to the first page after filtering.

I would like to try out another solution you pointted out with BufferedMemoryProxy. I tried this format. It always complained
Ext.ux.data.BufferedPagingMemoryProxy is not a Constructor.

I must have use it in a wrong way. The code is below:

First way:

var ds = new Ext.data.GroupingStore({
proxy: new Ext.ux.data.BufferedPagingMemoryProxy(data,{
filter: filters,
sortField: 'date'
},
reader: myReader,
groupField: 'request',
sortInfo: {field: 'date', direction: 'DESC'},
remoteSort: true
});
Second way:


var ds = new Ext.data.GroupingStore({
proxy: new Ext.ux.data.PagingMemoryProxy(data),
reader: myReader,
groupField: 'request',
//sortInfo: {field: 'date', direction: 'DESC'},
remoteSort: true,
plugins:[new Ext.ux.data.BufferedPagingMemoryProxy(data,{
filter: filters,
sortField: 'date'
})]
});

Thanks!

hendricd
28 Feb 2008, 7:32 PM
. I tried this format. It always complained
Ext.ux.data.BufferedPagingMemoryProxy is not a Constructor.Did you copy that class from the post I gave you into your script somewhere ? You'll need to (its a different version of the original extension).

Your "first way" is the correct usage.

ajaxE
28 Feb 2008, 8:04 PM
Did you copy that class from the post I gave you into your script somewhere ? You'll need to (its a different version of the original extension).

Your "first way" is the correct usage.

I copied the code you gave and now I am getting this error:
Ext.ux.data has no properties
[Break on this error]

Another extension which I don't have? Do you have it?

Thanks!!

ajaxE
29 Feb 2008, 12:48 PM
I copied the code you gave and now I am getting this error:
Ext.ux.data has no properties
[Break on this error]

Another extension which I don't have? Do you have it?

Thanks!!

The error has nothing to do with extension. I included the wrong JS file in the path! Dummmmm

Thanks for your help!

sanjshah
1 Mar 2008, 5:46 AM
Hi ambience,

would it be possible for you to show the datastore as per the extjs example, I'm trying to go through your example but am getting lost - I would really appreciate using the extjs example so I can follow it better.

Thanks in advance!

Sanjay

tmartinez
3 Mar 2008, 1:55 AM
Hello,
I've a pb to use the class ExTableFilter. I don't understand how to use it.
Actually i've put theses lines on my php file:

include ('DatabaseFilter.php');
include ('ExtTableFilter.php');
$filters = new ExtTableFilter($_POST['filter']);but i have this error:

<b>Catchable fatal error</b>: Argument 1 passed to ExtTableFilter::__construct() must be an instance of Request, array givenIf someone could help me...

Thanks you

Hello, i still have this problem and i don't know how to resolve it !! I think i will be mad with that !
If someone could help me...
Thanks you

mjlecomte
3 Mar 2008, 5:43 AM
What are those files? Did you get them from somewhere in this thread? If yes, those files were not plug and play, just examples to give you an idea what to do.
I think someone else may have posted a php file or snippet somewhere in this thread that allegedly works. You'll have to find it.

tmartinez
3 Mar 2008, 6:34 AM
Hello, thanks you for your reply. Those files came with the php-grid example. They are into the root directory of this example. But the example don't use them. It only use local filtering.
I have search a lot a snippet but i have just find the function of page 35 and it don't work with list.

ambience
3 Mar 2008, 9:50 AM
Hi ambience,

would it be possible for you to show the datastore as per the extjs example, I'm trying to go through your example but am getting lost - I would really appreciate using the extjs example so I can follow it better.

Thanks in advance!

Sanjay

The store used in the example is 100% compatible with Ext's store, it simply facilitates translating the specific format of the framework's response.

mjlecomte
3 Mar 2008, 12:02 PM
Hello, thanks you for your reply. Those files came with the php-grid example. They are into the root directory of this example. But the example don't use them. It only use local filtering.
I have search a lot a snippet but i have just find the function of page 35 and it don't work with list.


Those files were provided in this thread. They were posted to give an idea (not working) what to do. There was another post recently that might help you more.

http://extjs.com/forum/showthread.php?p=132283#post132283

mikemc
9 Mar 2008, 5:45 AM
Does anybody have a simple working example with static data? XML or dummy ... I've been looking all over this thread and none of the static examples work, even with the instructions and suggested modifications.

OK, i've got it finally, stupid me, it works exactly like explained in the other posts on this thread. :)

marco76
10 Mar 2008, 2:11 AM
I have a simple question.
Can I set a list filter where the labels of filter and the value of the POST are different ?
How can I do this?

dterle
10 Mar 2008, 3:46 AM
Hi,

I've read all pages in this thread but i didn't find how to specify a Ext.data.Store for options parameter of a list filter.

Can you help me please ?

In my example, civilite is the col name in my db ('0' for 'Mlle', '1' for 'Mme', '2' for 'M.').



var storeCivilite = new Ext.data.SimpleStore(
{
id: 'code',
fields: ['code', 'libelle'],
data :
[
['0', 'Mlle'],
['1', 'Mme'],
['2', 'M.']
]
});


Filter definition (don't work, no error in firebug, but no item are shown in filter's items) :

this.myFilter = new Ext.ux.grid.GridFilters({
local:true,
filters:[
{dataIndex: 'id_User', type: 'numeric'},
{dataIndex: 'civilite', type: 'list',
active:false,
//options: ['0', '1', '2'], // works, but i would like 'Mlle, 'Mme', 'M.', not keys
options: storeCivilite, // Don't work, is it the good syntax ?
phpMode: false
}
]
});

Thanks a lot :)

jbd007
11 Mar 2008, 12:41 PM
This seems to work pretty good on the other types of filtering but when I use 'local' and try to do a Date filer, I keep getting this error:
record.get(this.dataIndex).clearTime is not a function

And the line it's happening on is in DateFilter.js line 89

I don't see in your example code any requirement (or way) to set that a cell is a 'date' because that seems to be what the problem is ... it wants the cell to be a date and I guess it's not.

mrollins
13 Mar 2008, 9:40 AM
I was experiencing the same error as thatcoder and KGL. Mainly, at line 89 of DateFilter.js there was an error that record.get(this.dataIndex).clearTime is not a function.

A slightly easier fix than what thatcoder recommended is to replace line 89 with this line of code:



var val = new Date(record.get(this.dataIndex)).clearTime(true).getTime();


The problem with the way things currently are is that record.get(this.dataIndex) is returning a Record, but the Record is being treated as a Date when you try to clearTime(true) on it. Since Record has no clearTime function, it throws the error.


@ambience

Great plug-in.

I caught a bug in the DateFilter.js line 89.

Same bug as KGL.

Here is my solution.


Date.patterns = {
ISO8601Long:"Y-m-d H:i:s",
ISO8601Short:"Y-m-d",
ShortDate: "n/j/Y",
LongDate: "l, F d, Y",
FullDateTime: "l, F d, Y g:i:s A",
MonthDay: "F d",
ShortTime: "g:i A",
LongTime: "g:i:s A",
SortableDateTime: "Y-m-d\\TH:i:s",
UniversalSortableDateTime: "Y-m-d H:i:sO",
YearMonth: "F, Y"
};

I recommend creating a file called Date.patterns.js with the Javascript object and include it in head of your document.

Replace this (Line: 89)


var val = record.get(this.dataIndex).clearTime(true).getTime();


With this:


var val = new Date(Date.parseDate(record.get(this.dataIndex),Date.patterns.SortableDateTime)).clearTime(true).getTime();


Rationale
The date from my HTTP Payload returns the date in the format 2008-02-07T09:00:00 which corresponds to SortableDateTime according to the Date.patterns object (see the ExtJS docs)
Since clearTime and getTime are prototype functions of the Date object they need to be called on a Date object, not on a malformed date.

mrollins
13 Mar 2008, 9:43 AM
@dterle

I think that the options are expecting an array, not an object (such as a Store). Might be nice if it would read a Store, though.

steppinrazor
13 Mar 2008, 2:16 PM
Hey guys,

This grid plugin is totally marvelous but 1 of my filter text boxes shows up larger than all the others -- I have not a clue, any ideas.

Steppinrazor

jbd007
13 Mar 2008, 2:25 PM
Thanks for the reply mrollins, but it still won't work for me ... I think the problem is that some of my cells are empty ... and I also don't think it likes my date format (m/d/yy like '3/1/05') ... even the existing code render .getTime() for one of these fields to be like:
-2046099600000

mrollins
14 Mar 2008, 9:03 AM
Thanks for the reply mrollins, but it still won't work for me ... I think the problem is that some of my cells are empty ... and I also don't think it likes my date format (m/d/yy like '3/1/05') ... even the existing code render .getTime() for one of these fields to be like:
-2046099600000

Hmmm... I don't know if this will help, but the "official" way to specify your date pattern is "m/d/Y". 'Y' means a 2 digit year.

When our dates go into the grid, they come in in the Oracle date format and we input them as a date type into our store. Like this:



{name: id,
type: 'date',
//Date is of format 2007-06-18 00:00:00.0
dateFormat: 'Y-m-d H:i:s.0'}


I'm pretty sure that Ext takes that and converts it to its own "native" date format, which can be plugged directly into Ext.Date(...) to get a proper Date object. Maybe you should look at how your data is going into the store. If it's getting put in as a string instead of a date, then it wouldn't be properly formatted to go into the Date constructor.

Don't know if that will help, but it might could be a solution.

jbd007
14 Mar 2008, 11:51 AM
Well I'm using Java (JSP) to return the JSON data (which is all just Strings). Is there a different way to return the JSON data to make it known that it's a Date? I don't see why I can't just alter the DateFilter.js code to make it force the String into a Date?

mrollins
14 Mar 2008, 12:12 PM
Hacking DateFilter to turn it into a date is what I did, so I'm sure a further hack to make it compatible with your date won't hurt.

We use servelts to return our JSON, but we pass in metadata, too, which specifies the data type of each column, etc. We hacked together our own version of XStream and convert our objects right into JSON, so all of our JSON objects are just some sort of Java object converted to JSON by XStream. I think it might be the metadata that you're missing.

We use the metadata to configure our JSON reader, our column model and our filters. It's in the JSON reader that you'd specify the date type.

GraemeBryce
20 Mar 2008, 1:57 AM
Ambience

I would lime to make a request for a new feature to this superb plug-in.

There is much discussion in this thread on the merits or otherwise in using the column header menus to present the filter functionality.

Personally I support this use as it uses no additional screen real-estate coupled with the feature that applies classes to the filtered column headers making visual feedback to the user very clear.

It is the case however that many users don't appreciate the filters because they don't know they are there! One solution to this would be to render a "filters" split button on one of the gridPanel's toolbars. This button would present a checkbox menu containing the names of each available filter column with the same sub menus are currently appear in the headers as dependent upon the filter type. This "super" menu is really just a collection of the menus added to the headers with the name of the column replacing the word "Filter".

Having a menu like this also allows for the easy presentation of filters for columns that are hidden or, in the case of remote (server-side) filtering, presentation of filters for columns not actually in the grid.

My request takes two forms either of which would allow developers to easily achieve this outcome.

1. add the config option menuOnToolbar: 'top/bottom'
and / or
2. add the method getFilterMenus() that returns the menu collection suitable of inclusion in a button or menu that the developer would add manually to the grid toolbars or indeed anywhere else in the application.

The second option is perhaps more powerful and requires only slightly more effort on behalf of the developer.

If you feel this is not something you want to add to the filter code, or you do not have the time then I would be happy if you could post in reply some pseudo code suggesting the best approach and i will be happy to give it best efforts and post the results back here.

My thanks

akannu
20 Mar 2008, 4:14 AM
One solution to this would be to render a "filters" split button on one of the gridPanel's toolbars. This button would present a checkbox menu containing the names of each available filter column with the same sub menus are currently appear in the headers as dependent upon the filter type. This "super" menu is really just a collection of the menus added to the headers with the name of the column replacing the word "Filter".

Having a menu like this also allows for the easy presentation of filters for columns that are hidden or, in the case of remote (server-side) filtering, presentation of filters for columns not actually in the grid

Hi Graeme,
I am very interested in this topic as well. The current approach is great except that many users want to see the filter values exposed rather than have to remember what they are. I am not sure that your solution addresses this problem. If it does, can you please post a mockup of some sort?

Here is what we are doing. We created a 2nd row inside the column order and we are adding fields that are filters. The fields are data type dependant. A date column gets date picker. A text column gets a text field. etc. We are also adding operators (using minimal space) in front of these filters. We use a grid settings menu which has a FILTER toggle menu. When toggled on, the 2nd row inside column header is revealed. User filters. When toggled off, the 2nd row is hidden and the column header is collapsed. This is actually coming along very well for us. I will post screenshots later.

I think if ExtJS can offer filtering this way as well, it would be very nice.

Another option for ExtJS to do is to somehow extend the current implementation to display 'filter values' in the 2nd row of the column header. The italicized column header + display of filter values applied could address this problem as well.

Thanks

bhomass
20 Mar 2008, 7:42 PM
I got GridFilter working fine. but it messes up the paging toolbar. all the numbers say NaN. see figure.

I don't see this problem in all the posted samples, and I am using ext-2.0.1.

Any guess what it might be and where to look? it is pretty tough to step thru the ext-all.js.

ambience
21 Mar 2008, 9:03 AM
GraemeBryce: I don't have time to implement and test a menu at the moment. However, I believe setting up a 'spinner' menu that does what you need would be fairly simple. You would most likely need to just iterate over the GridFilters.filters collection and build menu items for your spinner who's name is the 'header' value stored in the column model that corresponds to filter.dataIndex and who's 'menu' attribute is set to the corresponding filter.menu. The most difficult part may honestly be getting access to the name ^.^

GraemeBryce
21 Mar 2008, 10:02 AM
ambience

Thanks for the reply,
I will undertake to develop the delta and to post it back to you for approval and if you wish for addition to the current release.

I will also implement it in a live project and gather any user feedback that is relevant.

Regards: Graeme

1900
21 Mar 2008, 2:37 PM
This is the greatest - best - super work !!!

---

I'm having a problem on a state reload of the filters.

I needed to add a check as the 'in' loop had before, after, on, and jsonString vars

in ux/grid/filter/DateFilter.js



setValue: function(value){
for(var key in this.dates)
if (this.dates[key].menu!=undefined) { // exception thrown during state reload
if(value[key]){
this.dates[key].menu.picker.setValue(value[key]);
this.dates[key].setChecked(true);
} else {
this.dates[key].setChecked(false);
}
}
},


This allowed the date filter to reload.

technicaltitch
24 Mar 2008, 6:07 AM
dterle - set your options array to the same array you set your SimpleStore dataArray to, ie

options: [['0', 'Mlle'],['1', 'Mme'],['2', 'M.']],(or better still have one named array variable that both point to).

ntumma
26 Mar 2008, 8:43 AM
Hello:

I am trying to integrate the Grid Filter feature in one of my projects. When I am setting any type anything like date, numeric other than string I am find one extra key as toJSONString and then getting this exception in the script "fields[key].on is not a function" can you please let me know what is going wrong.

Note: Everything is working fine when I set all the types as String.

Thanks in advance ...

ronnin
26 Mar 2008, 9:30 PM
calling grid.reconfigure(newDS, newCM); raises exception at line in Ext.grid.GridView

reminder
27 Mar 2008, 3:18 AM
hello.
the filtering is very nice!
but i cannot find the way for multifiltering?
im doing in php like

if(isset($_POST["filter"])) {
foreach($_POST["filter"] as $key => $val) {
$filter .= $_POST["filter"][$key]["field"]." LIKE '%".$_POST["filter"][$key]["data"]["value"]."%' AND";
}
$fil = substr($filter, 0, strlen($filter) -3);
}

but without results?
any suggestion appreciated...
thanx in advance!

highmemory
27 Mar 2008, 8:59 AM
When I apply a filter in local mode to a column with a renderer, the filter is applied to the record value and not to the rendered value.

This is not what a user expects from a local filter.

Suppose the record value for a column is the string 'Yes';
the column renderer is:


function renderAgentName(value) {
if (value == 'Yes');
return 'Si';
else
return 'No';
}


The string filter works if I use 'Yes' (or 'Y').
A user expects the filter to be applied on the values on the screen.

Regards

Marco

jelt
28 Mar 2008, 5:41 AM
@highmemory : if you can transform your record dataset before sending it to ext, i think the better solution is to define this field as a boolean.

Arthur.Blake
28 Mar 2008, 8:08 AM
Hi,

I have another kind of filters, if anyone is interested. At the moment, they only work for 'remote' grids, and the idea is more limited as you can't do all kinds of filters, but you can do text searches or combos or date (whatever kind of ext field).

The idea is that the filter is always visible and is in the column model...


:D

cocorossello, this is fantastic and exactly what I've been looking for! Have you improved it at all since you last talked about it?

Has anyone done any work to render filters in a style like this, but have more of the power and features of the filtering as in the main plugin that this thread is about?

If not, I'm going to be working on it...

I think the ability to show the filters directly under each column header is a much easier and simpler model for typical end users to grasp... it may not be quite as powerful, but it's more accessible, simpler and easier to use.

reminder
28 Mar 2008, 11:04 PM
hello.
when i pass the filter parameter to php with multifiltering i get only filter[0][... in the foreach loop?
please can you advice me on how to get the rest filter[1][... filter[2][...etc
any suggestion appreciated...
thanx in advance!

6epcepk
28 Mar 2008, 11:15 PM
reminder
I'm posting my filter function some pages ago...you can use it.

reminder
29 Mar 2008, 11:55 AM
Ok, no problems :)

I have write function wich creates SQL query. Works fine with string, numeric and date column types.
Functions:

// ==================================================
// FUNCTION - BUILD FILTER QUERY
// ==================================================
function get_filter($data, $alias = false, $glue = 'AND') {

$condition = '';

$comparison = array('gt' => '>', 'lt' => '<', 'eq' => '=');

foreach ($data as $el) {

if ($el['data']['type'] === 'string') {

$condition .= get_filter_alias($el['field'], $alias) . $el['field'] . ' LIKE \'%' . $el['data']['value'] . '%\' ' . $glue . ' ';

} elseif ($el['data']['type'] === 'numeric') {

$condition .= get_filter_alias($el['field'], $alias) . $el['field'] . ' ' . $comparison[$el['data']['comparison']] . ' ' . $el['data']['value'] . ' ' . $glue . ' ';

} elseif ($el['data']['type'] === 'date') {

$timestamp = strtotime($el['data']['value']);
$condition .= get_filter_alias($el['field'], $alias) . $el['field'] . ' ' . $comparison[$el['data']['comparison']] . ' ' . $timestamp . ' ' . $glue . ' ';

}

}

$condition = (!empty($condition)) ? 'WHERE ' . $condition : '';

return rtrim($condition, ' ' . $glue . ' ');

}


// ==================================================
// FUNCTION - GET FIELD ALIAS
// ==================================================
function get_filter_alias($field, $alias) {


if (!empty($alias) && !is_array($alias)) {

return $alias . '.';

} elseif (!empty($alias) && is_array($alias)) {

return !empty($alias[$field]) ? $alias[$field] . '.' : false;

} else {

return;

}

}

Using:

$filter = (!empty($_POST['filter'])) ? get_filter($_POST['filter'], array('id' => 'A', 'date_c' => 'A', 'date_u' => 'A', 'title' => 'B')) : '';

$result = mysql_qw('
SELECT A.id FROM news A
INNER JOIN news_locale B ON B.news_id = A.id AND B.lang_id = ?
' . $filter,
$_SESSION['lang']
) or die(mysql_error());

I hope this code will helpful for anybody =)

solved..
thank you very much!!!
i used key instead value from the beggining!!!
got all working now!

jineshkunnath
31 Mar 2008, 4:42 AM
i try to use the code for gridfilter. but i failed to do that
this is my code please help me



var GlobalModel = [
// set up the fields mapping into the json
{name: 'INVENAVAIL_ID', mapping: 'INVENAVAIL_ID', type:'int'},
{name: 'QTY',mapping: 'QTY', type:'string'},
{name: 'LINE', mapping: 'LINE', type:'string'},
{name: 'GENDER', mapping: 'GENDER', type:'string'},
{name: 'TEAMCD', mapping: 'TEAMCD', type:'string'},
{name: 'TEAMNAME', mapping: 'TEAMNAME', type:'string'},
{name: 'STYLE', mapping: 'STYLE', type:'string'}
]

// create the reader
var GlobalReader = new Ext.data.CFJsonReader(GlobalModel,{id:'INVENAVAIL_ID'});

// get the data from coldfusion as json
var globegrid_ds = new Ext.data.Store({
url: 'cfc/salesorder.cfc?method=getInstockReportView&returnFormat=json',
reader: GlobalReader,
groupField: 'INVENAVAIL_ID' ,
// sortInfo: {field: 'INVENAVAIL_ID', direction: 'ASC'},
// remoteSort: true,
listeners: {
loadexception: function(proxy, store, response, e) {
},
load: function(){
}
}
});

Ext.ux.grid.filter.StringFilter.prototype.icon = 'img/find.png';
Ext.state.Manager.setProvider(new Ext.state.CookieProvider());

var filters = new Ext.ux.grid.GridFilters({
filters:[
{type: 'numeric', dataIndex: 'INVENAVAIL_ID'},
{type: 'string', dataIndex: 'LINE'},
{type: 'string', dataIndex: 'GENDER'},
{type: 'string', dataIndex: 'TEAMCD'},
{type: 'string', dataIndex: 'TEAMNAME'},
{type: 'string', dataIndex: 'STYLE'}

]
});



// create the column model
var globegridCols = new Ext.grid.ColumnModel([
checkActive,
{
header: 'Qty',
dataIndex: 'QTY',
width: 50,
align: 'right',
editor: new Ext.form.NumberField({
allowBlank: false,
allowNegative: false,
maxValue: 100000
})
},{
header: 'Line',
dataIndex: 'LINE',
width: 50
},{
header: 'Gender',
width: 40,
dataIndex: 'GENDER'
},{
header: 'Team_cd',
width: 40,
dataIndex: 'TEAMCD'
},{
header: 'Team_name',
width: 100,
dataIndex: 'TEAMNAME'
},{
header: 'Style',
width: 50,
dataIndex: 'STYLE'
}
]);
globegridCols.defaultSortable = true;

var stockgrid= new Ext.grid.EditorGridPanel({ id: 'instockreport',
width:900,
height:300,
ds: globegrid_ds,
cm: globegridCols,
plugins:[checkActive,filters],
enableColLock: false,
loadMask: true,
viewConfig: {
forceFit: true
},
frame: true/*,
clicksToEdit:2,
sm: new Ext.grid.RowSelectionModel({singleSelect:true})*/
})

var globewin;
var button1 = Ext.get('globe-btn');
button1.on('click', function(){
// create the window on the first click and reuse on subsequent clicks
if(!globewin){
globewin = new Ext.Window({
el:'globepopupwin',
layout:'fit',
width:920,
height:300,
closeAction:'hide',
plain: true,
title: 'In Stock Report View',
items: new Ext.Panel({
width:900,
items : stockgrid,
tbar: [{
text: 'Submit',
enableToggle:true,
toggleHandler: updateStockDB
}],
bbar: new Ext.PagingToolbar({
store: globegrid_ds,
pageSize: 2,
plugins: filters,
displayInfo: true
})
})
});
}
globewin.show(this);
});

globegrid_ds.load({params:{start:0, limit:8}});


please help me

LeonardoAP
31 Mar 2008, 12:02 PM
Hello!
The grid filter is working great with me.

But, i'm wondering if there any way to use the filters if i disable the column's header menu.

wm003
7 Apr 2008, 3:05 AM
Great Extension. One thing i needed to change was the ability to have a custom Text on the Menu-Entry "Filters" and menufilter Texts for BooleanFilter and DateFilter


GridFilters.js:

...
menuFilterText: 'Filters', // ADDED LINE

onRender: function(){
var hmenu;

if(this.showMenu){
hmenu = this.grid.getView().hmenu;

this.sep = hmenu.addSeparator();
this.menu = hmenu.add(new Ext.menu.CheckItem({
//------------------
text: this.menuFilterText, //<- CHANGED LINE
//------------------
menu: new Ext.menu.Menu()
}));
this.menu.on('checkchange', this.onCheckChange, this);
this.menu.on('beforecheckchange', this.onBeforeCheck, this);

hmenu.on('beforeshow', this.onMenu, this);
}

this.grid.getView().on("refresh", this.onRefresh, this);
this.updateColumnHeadings(this.grid.getView());
},
...

BooleanFilter.js:


yesText: 'Yes', //ADDED LINE
noText: 'No', //ADDED LINE

init: function(){
var gId = Ext.id();
this.options = [
new Ext.menu.CheckItem({text: this.yesText, group: gId, checked this.defaultValue === true}), //CHANGED LINE
new Ext.menu.CheckItem({text: this.noText, group: gId, checked: this.defaultValue === false})]; //CHANGED LINE

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);
}
},

DateFilter.js:


beforeText: 'Before', //ADDED LINE
afterText: 'After', //ADDED LINE
onText: 'On', //ADDED LINE

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)}), //CHANGED LINE
'after': new Ext.menu.CheckItem({text: this.afterText, menu: new Ext.menu.DateMenu(opts)}), //CHANGED LINE
'on': new Ext.menu.CheckItem({text: this.onText, menu: new Ext.menu.DateMenu(opts)})}; //CHANGED LINE

this.menu.add(dates.before, dates.after, "-", dates.on);
...
This way you can simply translate it by (e.g. German)



Ext.ux.grid.GridFilters.prototype.menuFilterText = 'Filter';
Ext.ux.grid.filter.BooleanFilter.prototype.yesText = 'Ja';
Ext.ux.grid.filter.BooleanFilter.prototype.noText = 'Nein';
Ext.ux.grid.filter.DateFilter.prototype.beforeText = 'vor dem';
Ext.ux.grid.filter.DateFilter.prototype.afterText = 'nach dem';
Ext.ux.grid.filter.DateFilter.prototype.onText = 'am';

pil0t
9 Apr 2008, 5:53 AM
I try to use list filter with comma inside the filter words, and there no way to devide in request where is comma between list elements or comma inside list element. any ideas to fix this?
and what about list filter with "filtertext" and "captiontex"?

AlxH
14 Apr 2008, 9:52 AM
One suggestion for EditableItem:
I replaced


html: '<img src="' + this.icon + '" class="x-menu-item-icon" style="margin: 3px 3px 2px 2px;" />'});

with:


html: '<img src="' + (this.icon||Ext.BLANK_IMAGE_URL)+ '" class="x-menu-item-icon'+(this.iconCls?' '+this.iconCls:'')+'" style="margin: 3px 3px 2px 2px;" />'});


To make it more reusable, if I was intended.

wm003
14 Apr 2008, 10:49 AM
I
and what about list filter with "filtertext" and "captiontex"?


{
type: 'list',
dataIndex: 'filterfield',
options: [
['1','Caption One'],
['2','Caption two'],
['3','Caption three'],
['4','Caption four']
],
phpMode: true
},


This way the filterfield is filtered by 1,2,3,4 but the menu displays the caption texts

steppinrazor
16 Apr 2008, 1:25 PM
I recently realized that the filter grid does not save state in IE6 like it does in FF. Has anyone had this issue and found a solution(workaround)

I create the state manager


Ext.onReady(function() {

Ext.QuickTips.init();
Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
....
and I set a stateId



var gridPanel = new Ext.grid.GridPanel({
loadMask:true,
ds: dataStore,
cm: userCM,
renderTo:'grid',
viewConfig:{forceFit:true},
bbar: myPagingToolbar,
frame:true,
height:550,
width:1200,
layout:'fit',
title:'Application Queue',
iconCls:'app',
autoSizeColumns:true,
stateId:'filter',
plugins: filter,
....
Can anyone share some light on the pain that is IE6.

stevets
21 Apr 2008, 7:44 PM
I am still pretty new to Ext. I just found out about the GridFilter today since it is included with 2.1. I looked at the example code and read the API docs. I searched the forums as well but can not find out what the phpmode configuration does. I can't find the API docs for the grid filter anywhere.

Help?

mjlecomte
22 Apr 2008, 4:05 AM
I am still pretty new to Ext. I just found out about the GridFilter today since it is included with 2.1. I looked at the example code and read the API docs. I searched the forums as well but can not find out what the phpmode configuration does. I can't find the API docs for the grid filter anywhere.

Help?I believe it just collates the data differently in the POST array. Just monitor the POST in firebug as you play with it. I think you'll notice the difference once you have a couple of filters applied.

Chemist
23 Apr 2008, 10:53 PM
Can anyone help? I'm trying to load data into the listfilter using Ext.data.GroupingStore (ScriptTagProxy+JsonReader) with this code:



{type:'list', dataIndex:'idRefItem', labelField:'sCaption',
store:new Ext.data.GroupingStore({
proxy:new Ext.data.ScriptTagProxy({
url:'http://localhost:2570/ReferenceBackEnd.aspx?sRefName=IndicatorsPeriods'
}),
baseParams:[{action:'GetItems'}],
reader:new Ext.data.JsonReader({
root:'Root',totalProperty: 'totalCount', fields:['idRefItem','sCaption']
})
})
}


As I understand, store must load data and make filter. Is this possible? The problem is, that data isn't loading. Firebug tells that there were no any data load. And the filter isn't drawing in the column menu at all...

mjlecomte
24 Apr 2008, 5:30 AM
Can anyone help? I'm trying to load data into the listfilter using Ext.data.GroupingStore (ScriptTagProxy+JsonReader) with this code:



{type:'list', dataIndex:'idRefItem', labelField:'sCaption',
store:new Ext.data.GroupingStore({
proxy:new Ext.data.ScriptTagProxy({
url:'http://localhost:2570/ReferenceBackEnd.aspx?sRefName=IndicatorsPeriods'
}),
baseParams:[{action:'GetItems'}],
reader:new Ext.data.JsonReader({
root:'Root',totalProperty: 'totalCount', fields:['idRefItem','sCaption']
})
})
}


As I understand, store must load data and make filter. Is this possible? The problem is, that data isn't loading. Firebug tells that there were no any data load. And the filter isn't drawing in the column menu at all...
My suggestion would be to:

Get the grid working (loading data, etc) WITHOUT filters
Add filtering so it shows up in the column model (don't worry about server side yet)
Finally add the filtering logic server side

It sounds like you have multiple things going wrong at the last 2 stages above. Once 2 is complete and you try to use it you should see the filters included in firebug's console.
If you were to add a loadexception event you would probably see that it's firing right now.

Twain
25 Apr 2008, 10:31 AM
First, congratulations Ambience, this is a great plugin!. Thanks for this excelent contribution.
I

ambience
25 Apr 2008, 1:34 PM
Thanks,

The List type filter takes a 'store' option that allows you to provide the menu with a store that is loaded on show. Be sure that the records have their id properties set correctly and that the store either contains a field called 'text' or that you set the 'labelField' config value to the field you wish the labels to be generated from.

steppinrazor
25 Apr 2008, 2:15 PM
Ambience did you realize that the filter demo does not save state in IE 6? This was a surprise to me, what do you think?

notjoshing
26 Apr 2008, 8:05 PM
In my data grid, I differentiate between data types such as "int" and "float". To use your filters with these types, I modified GridFilters.js, and figured I'd put the code here in case anyone needs to do similar handling:


getFilterClass: function(type){
/*customizations to handle data types*/
if( type=='int' || type=='float' ) {
type = 'numeric';
}
return Ext.ux.grid.filter[type.substr(0, 1).toUpperCase() + type.substr(1) + 'Filter'];
}

Josh

notjoshing
26 Apr 2008, 8:57 PM
In RangeMenu.js, you've a typo in the declaration of the fields variable in 0.2.6. When declaring the field configuration, you give this:


'eq': new Ext.ux.menu.EditableItem({
icon: this.icons.eq,
editor: new cls(typeof cfg == "object" ? cfg.gt || '' : cfg)})

What you want, I think, is this


'eq': new Ext.ux.menu.EditableItem({
icon: this.icons.eq,
editor: new cls(typeof cfg == "object" ? cfg.eq || '' : cfg)})

Josh

notjoshing
26 Apr 2008, 9:51 PM
I found that people using my site often wanted to combine "equals" and "not equals" searches for numeric data. They also wanted to be able to use wild cards, so you could do a LIKE search, such as for "123*456.7*". In the attached edited version of RangeMenu.js, I incorporate both of these, based on 0.2.6.

I'll upload similar functionality for strings soon.

Josh

Edit: A couple things I forgot to mention:
* The code here presumes you're doing server-side filtering. To handle this in the browser, you'd need to add some regular expressions to the validation code in NumericFilter.js
* I should have uploaded the PNG I'm using for this as well. It's basically just a combination of the greater than and less than pngs, stitched together.

wm003
26 Apr 2008, 11:49 PM
I'll upload similar functionality for strings soon.

That would be really nice! :DThank you for sharing!

m0nu
27 Apr 2008, 11:25 AM
thanks for this plugin! realy great job...

notjoshing
27 Apr 2008, 6:51 PM
I plugged away a bit today on adding NOT EQUAL TO functionality (ne) to the string and numeric filters. Here's a summary of changes:


[LIST]
[B]

pic_Nick
27 Apr 2008, 9:13 PM
Hello ambience!
This is really great work, but unfortunatly it is not localization-friendly, so I suggest you to make some changes:
In GridFilter.js


...
showMenu: true,

filtersText: 'Filters',

init: function(grid){
...
onRender: function(){
var hmenu;

if(this.showMenu){
hmenu = this.grid.getView().hmenu;

this.sep = hmenu.addSeparator();
this.menu = hmenu.add(new Ext.menu.CheckItem({
text: this.filtersText,
menu: new Ext.menu.Menu()
}));
this.menu.on('checkchange', this.onCheckChange, this);
this.menu.on('beforecheckchange', this.onBeforeCheck, this);

hmenu.on('beforeshow', this.onMenu, this);
}

this.grid.getView().on("refresh", this.onRefresh, this);
this.updateColumnHeadings(this.grid.getView());
},
...

In BooleanFilter.js


Ext.ux.grid.filter.BooleanFilter = Ext.extend(Ext.ux.grid.filter.Filter, {
defaultValue: false,

yesText: 'Yes',
noText: 'No',

init: function(){
var gId = Ext.id();
this.options = [
new Ext.menu.CheckItem({text: this.yesText, group: gId, checked: this.defaultValue === true}),
new Ext.menu.CheckItem({text: this.noText, group: gId, checked: this.defaultValue === false})];

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

In DateFilter.js


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

beforeText: 'Before',
afterText: 'After',
onText: 'On',

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)})};

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

With best regards.

wm003
28 Apr 2008, 2:26 AM
Hello ambience!
This is really great work, but unfortunatly it is not localization-friendly, so I suggest you to make some changes:

If you may have looked some posts above, i already mentioned this here ;) (http://extjs.com/forum/showthread.php?p=149052#post149052)

pic_Nick
28 Apr 2008, 5:24 AM
Oh, you are right. I've just overlooked your post :">

sinma
5 May 2008, 2:52 AM
I'm trying to apply filters to a datagrid.

When I add a filter to a column, the filter is sent correctly to server side, and on server side the filter is applied correctly and it returns a json with the filtered records. But when the datagrid is reloaded, it doesn't apply the filter, it shows all records...

Where can be the problem?

Thanks!

ambience
5 May 2008, 8:26 AM
I will try to release and update around the end of this week to patch in some of the fixes / updates people have submitted (primarily the multi-language support). I will try to scan the thread, but there are quite a few posts. So if you have fixed a bug / or have made an update please PM me with the details and I will try to merge the changes and credit you. If I don't include your update as part of the core functionality I will try to link to your related thread on the original post, so please provide forum / site links if you can.

jelt
6 May 2008, 1:53 AM
Hi,

i try to use the buildquery to override filtering process.



filters = new Ext.ux.grid.GridFilters({
filters:[ ... ]
buildQuery: function(filters){
var p = null;
if(!!filters.length){
p= function(record){
return false;
};
}
alert(p);
return {filter:p};
}
In FF with this simplified example, at first display, all entries are displayed after a "null" alert.
When i filter on one column, popup display "function(record){return false;};" and all entries are filtered, grid is now empty. It's OK, as attended

In IE6, all entries are displayed after a "null" alert. When i filter on one column, popup display "function(record){return false;};" but all entries stay visible. If i try to page down using paging, popup "function..." is displayed and nothing else append (paging is not done, staying on page 1).
If i delete the filter, "null" popup is displayed again and paging is done (goto page 2)

I have tried to set an alert inside the filtering function :


buildQuery: function(filters){
var p = null;
if(!!filters.length){
p= function(record){
alert('Hello world !');
return false;
};
}
return {filter:p};
Alert is normally displayed one time by line in the grid with FF, but never displayed in IE

If i change the buildquery function to filter at the first display (not only when i set a filter) :


buildQuery: function(filters){
var p = null;
p= function(record){
return false;
};
return {filter:p};
Then filtering function is used by FF and by IE6, and no data is displayed, as attended !

I use BufferedPagingMemoryProxy. I dont know if the problem came from gridFilter,BufferedPagingMemoryProxy, or me :-?

Could you help me ?

Edit :


buildQuery: function(filters){
var p = null;
p= function(record){
return true;
};
return {filter:p};
Then FF display all lines as attended, IE6 display no data :-(

in BufferedPagingMemoryProxy, the line 139 :

result.records = result.records.filter(config.filters.using);
is executed, but never return (with IE6). Then data rendering is never done.
(result is filled by : result = reader.readRecords(this.data); and reader is the store.reader of the grid)

hendricd
6 May 2008, 4:58 AM
@jelt -- BPMP uses some gnarly logic to compare filter changes, try:


return {filter:p||false};

Fabyo
6 May 2008, 5:11 AM
One idea, instead using the current system of searching for dates, could use the grant in place between the fields before and after 2 enter fields to put a starting date and another end

another idea is to create a filter and instead use checkbox use radionbutton, person to select only 1 option

jelt
6 May 2008, 5:34 AM
the return {filter:p} seem to be correct (i can detect that parameter is correctly filled)

The record.filter() function never end

Totally outside any plugins, i test this code (added at the end of array-grid.js example) :


var test = grid.store.reader.readRecords(myData);
alert('BEFORE:'+test.records);
var filter_fn = function(record){return true;};
test.records = test.records.filter(filter_fn);
alert('AFTER:'+test.records);
FF ok
IE6, the second alert never occurs. Is it Normal ?

edit : opera error log (with ext-all-debug.js):

Event thread: DOMContentLoaded
Error:
name: TypeError
message: Statement on line 101: Type mismatch (usually a non-object value used where an object is required)
Backtrace:
Line 101 of linked script file://localhost/M:/ext4sap/ext-2.1/examples/grid/array-grid.js
test.records = test.records.filter(filter_fn);
Line 1488 of linked script file://localhost/M:/ext4sap/ext-2.1/ext-all-debug.js
if (l.fireFn.apply(l.scope || this.obj || window, arguments) === false)
Line 1525 of linked script file://localhost/M:/ext4sap/ext-2.1/ext-all-debug.js
docReadyEvent.fire();
At unknown location
[statement source code not available]

I don't know if this error is linked to my problem, in the complete case (with plugins, etc...) i dont have any javascript error logged (in IE6 or opera 9)

hendricd
6 May 2008, 6:23 AM
@jelt -- reviewing my code (library), you'll need an Array.prototype.filter function, like:



Ext.applyIf(Array.prototype, {
filter: function(iter, scope) {
var results = [];
Ext.each(this, function(value, index) {
if (iter.call(scope, value, index)) results.push(value);
});
return results;
});
..for line 139 to work

jelt
6 May 2008, 6:41 AM
@hendricd : You are right, it work now :)
THANK YOU VERY MUCH !!! =D>

marceloprietos
7 May 2008, 9:59 PM
Hello friends, I will be thankfull if somebody let me know how i have to change this example in order to work with dummyData


Ext.onReady(function(){
Ext.ux.menu.RangeMenu.prototype.icons = {
gt: 'img/greater_then.png',
lt: 'img/less_then.png',
eq: 'img/equals.png'
};
Ext.ux.grid.filter.StringFilter.prototype.icon = 'img/find.png';
Ext.state.Manager.setProvider(new Ext.state.CookieProvider());

var ds = new Ext.data.GroupingStore({
proxy: new Ext.data.HttpProxy({
url:'action.php'
}),

reader: new Ext.data.JsonReader({
id: 'id',
totalProperty: 'data.total',
root: 'data.results'
}, Ext.data.Record.create([
{name:'id'},
{name:'name'},
{name:'price'},
{name:'dateAdded'},
{name:'visible'},
{name:'size'}])),

groupField: 'size',
sortInfo: {field: 'name', direction: 'ASC'},
remoteSort: true
});

var filters = new Ext.ux.grid.GridFilters({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'}
]});

var cm = new Ext.grid.ColumnModel([{
dataIndex: 'id',
header: 'Id'
}, {
dataIndex: 'name',
header: 'Name'
}, {
dataIndex: 'price',
header: 'Price'
}, {
dataIndex: 'dateAdded',
header: 'Date Added'
}, {
dataIndex: 'size',
header: 'Size'
}, {
dataIndex: 'visible',
header: 'Visible'
}]);
cm.defaultSortable = true;

var grid = new Ext.grid.GridPanel({
id: 'example',
ds: ds,
cm: cm,
enableColLock: false,
loadMask: true,
view: new Ext.grid.GroupingView(),
plugins: filters,
height:400,
width:700,
stateId: 'testGrid',

el: 'grid-example',

bbar: new Ext.PagingToolbar({
store: ds,
pageSize: 15,
plugins: filters
})
});
grid.render();

ds.load({params:{start: 0, limit: 15}});
});

Thanks in advance

Phunky
9 May 2008, 3:31 AM
It might be a good idea to have a little explaination on what vars get passed when filtering the data i've just started looking at getting this intergrated into an Air App im working on and couldnt find what it was sending to the datastore.

I've since downloaded your phpFilters zip and will be looking through that to understand how you have worked your queries.

Still a great plugin through :)

spectrus
9 May 2008, 5:16 AM
You have to fill the store (ds) with your own data. Take a look at various grids in the examples section (http://extjs.com/deploy/dev/examples/samples.html), like this one (http://extjs.com/deploy/dev/examples/grid/array-grid.html) - they just fill the store with dummy data from an array (myData).


Hello friends, I will be thankfull if somebody let me know how i have to change this example in order to work with dummyData
Thanks in advance

vladok
13 May 2008, 3:34 AM
Hi, there!


I want to make a function that should pass the content of dblclicked cell to another grid's filter. I have this filter installed and working pretty well, but I can't even imagine how to code the function. Where can I look for syntax of FilterGrid? Need your advice.

mjlecomte
13 May 2008, 4:48 AM
Hi, there!


I want to make a function that should pass the content of dblclicked cell to another grid's filter. I have this filter installed and working pretty well, but I can't even imagine how to code the function. Where can I look for syntax of FilterGrid? Need your advice.

What if you have Grid1 = original grid where you double click
and then Grid2 = grid where you want the filter applied

In grid1 you add doubleclick event that does a store load for Grid2 (you just need a reference to store for Grid2 which you can get from store manager or Grid2.getStore(), in either case you assign an id to the grid or store so you can get reference easily via the storeManager or ComponentManager).

You'd need to store these filter params in a session or global variable if you want them preserved I think (if you're paging or need these filters later for whatever reason).

Anyway, avoids extending this plugin I think. Maybe there's an easy way to call the Grid2 filters easily so it loads the filters into Grid2.

joshjdevl
14 May 2008, 4:41 PM
Hi,

This is quite a long thread... :)

I was reading the blog interview at http://extjs.com/blog/2007/11/26/extended-filtering-using-the-grid-filter-plugin/

Could someone please let me know which control was used in the screen shot to do the accordion table view sorted by size (small, large, medium). Also, if the sample code is available that would be even nicer...

Thanks,
Josh

mjlecomte
14 May 2008, 6:37 PM
joshjdevl

Check out the demos, that is just grouping summary.
http://extjs.com/deploy/dev/examples/grid/grouping.html

You can see filtering here:
http://extjs.com/deploy/dev/examples/grid-filtering/grid-filter.html

Combine the two, or just add grouping to the filtering example and you're there.

nunziofiore
15 May 2008, 5:04 AM
Hi all,
i use this plugin cause IT S GREAT :)... i have only a question... it's possible ( and if yes, how?) to start a page with a grid yet filtered showing columns css filtered symbol and value of textfield for example, yet valorized ?
Nunzio

eleseint
15 May 2008, 5:18 AM
I want update filter list dynamically with a json response. But i find nothing on this. It is possible ?

Twain
15 May 2008, 12:11 PM
I want update filter list dynamically with a json response. But i find nothing on this. It is possible ?

Yes, it is possible. It

nunziofiore
16 May 2008, 6:07 AM
i need to set if a filter is active and which is the data to write in textfield for filter (active or inactive)... please... :(

ambience
16 May 2008, 9:13 AM
All filters support the setValue and setActive methods. You will need to call filters.getFilter(dataIndex) to retrieve the individual filter objects and then invoke the setValue methods according to your configuration. Each setValue function expects data formated in a specific way. However, I don't have the time to detail each of those so you will need to consult the source (or other posts in this thread) for the specifics.

nunziofiore
16 May 2008, 10:46 AM
thank you so much ... i'll try in these days ... thanks.
nunzio

nnextjs
17 May 2008, 4:49 PM
Hi,

I am trying the filter plugin for extjs 2.1. The filter works; however, for date type, it is not easy to set a date range (before and after). It seems to post back to the server right after setting 'before' or 'after'. Is there any way to 'lock' the mouse pointer during the setting? As I click on a check box, the popup menu tends to disappear and post back to server.

Thank you.

Nghia

efiebba
19 May 2008, 12:55 AM
Hi

Maybe anybody asked this in the prev. 45 pages ;-) But is there a filter for images?


Bastian

nunziofiore
19 May 2008, 2:02 AM
Ok,
writing somthing like:

{type: 'string', dataIndex: 'name', value:'3',active:false},

I have a filter disabled and valued with 3... but i don't understand (and i say sorry if there's somewhere but i didn't read it) how can i set comparison operator ?
There's some API i didn't see..?
Thank you for your help
nunzio fiore

nunziofiore
19 May 2008, 2:34 AM
DIANA! READ IT BEFORE TO ASK IT!

I start reading the long thread and i founded the answer here http://extjs.com/forum/showthread.php?t=14503&page=10
sorry, next time I read it before!

to set value to filter elements before rendering table:

type: 'numeric', dataIndex: 'price',value:{gt:40,lt:80}},
{type: 'date', dataIndex: 'dateAdded',value:{before:new Date('1/1/1980'),after:new Date('12/1/1979')}},

ambience
19 May 2008, 9:00 AM
nnextjs: Currently there is no support with in the filters to do this directly. However by passing 'pickerOpts' to the DateFilter config you may be able to coax the functionality out with some creative listener work or some other option. This value is passed directly to the Ext.menu.DateMenu objects.

efiebba: I am unclear as to what an 'image' filter is. So no, I don't think it is supported by default ^.^

ambience
19 May 2008, 9:05 AM
nunziofiore: Cox was once my hero as well, but sadly there is only room enough for House now.

mrollins
21 May 2008, 12:00 PM
Hey Ambience, thanks for an awesome plugin. It's exactly what the Dr. ordered for our project, and we use it extensively.

I have a problem with an EditorGrid.

I have a button that adds a blank record to my grid, like this:



handler: function(){
var r = new Record({
EXP_OBJECTIVE: '',
delete: false
});
grid.stopEditing();
store.insert(0, r);
grid.startEditing(0, 0);
}


Works like a charm. The problem occurs when I attempt to filter after I've added a record. Once I've added a record, then attempt to filter, all the records that have been added since the page was loaded simply disappear. They don't come back when I reset the filters, either. It's as if they disappear into thin air.

I've tried using store.commitChanges(), but this doesn't solve the problem.

I'm using a local filter with a local store.

Thanks to anyone for any help.

snow
22 May 2008, 8:03 AM
Is it possible to use Grid Filter with PagingMemoryProxy and local store , under 2.1 ?

My Grid renders, and has the various filters defined, but there is no
update to the grid once a filter selection is made.

Assuming it can be done .... is it possible to filter on all pages at once rather than just
the one page on screen

Thanks





Ext.onReady(function() {

Ext.menu.RangeMenu.prototype.icons = {
gt: '/ext/img/greater_then.png',
lt: '/ext/img/less_then.png',
eq: '/ext/img/equals.png'
};
Ext.grid.filter.StringFilter.prototype.icon = '/ext/img/find.png';
Ext.state.Manager.setProvider(new Ext.state.CookieProvider());





//Ext.namespace("Ext.ux.data");

Ext.grid.myData = [
['<style type=text/css>.x-grid3-cell-inner, .x-grid3-hd-inner { white-space:normal !important; }</style><a href=/prod/syslog.pl?mode=syslog&act=edit&id=428192&type=ID&stage=1>428192</a>',
'<style type=text/css>.x-grid3-cell-inner, .x-grid3-hd-inner { white-space:normal !important; }</style><a href=/prod/syslog.pl?mode=syslog&act=edit&id=428192&type=FromHost&stage=1>1.1.1.1</a>',
'<style type=text/css>.x-grid3-cell-inner, .x-grid3-hd-inner { white-space:normal !important; }</style><a href=/prod/syslog.pl?mode=syslog&act=edit&id=428192&type=DeviceReportedTime&stage=1>2008-05-20 15:43:44</a>',
'<style type=text/css>.x-grid3-cell-inner, .x-grid3-hd-inner { white-space:normal !important; }</style><a href=/prod/syslog.pl?mode=syslog&act=edit&id=428192&type=Facility&stage=1>KERN</a>',
'<style type=text/css>.x-grid3-cell-inner, .x-grid3-hd-inner { white-space:normal !important; }</style><a href=/prod/syslog.pl?mode=syslog&act=edit&id=428192&type=Priority&stage=1>LOG_INFO</a>',
'<style type=text/css>.x-grid3-cell-inner, .x-grid3-hd-inner { white-space:normal !important; }</style><a href=/prod/syslog.pl?mode=syslog&act=edit&id=428192&type=Message&stage=1>imklog 3.19.1, log source = /proc/kmsg started.</a>',
'<style type=text/css>.x-grid3-cell-inner, .x-grid3-hd-inner { white-space:normal !important; }</style><a href=/prod/syslog.pl?mode=syslog&act=edit&id=428192&type=SysLogTag&stage=1>kernel:</a>',
'<style type=text/css>.x-grid3-cell-inner, .x-grid3-hd-inner { white-space:normal !important; }</style><a href=/prod/syslog.pl?mode=syslog&act=delete&id=428192>Ack</a>']
,
['<style type=text/css>.x-grid3-cell-inner, .x-grid3-hd-inner { white-space:normal !important; }</style><a href=/prod/syslog.pl?mode=syslog&act=edit&id=428193&type=ID&stage=1>428193</a>',
'<style type=text/css>.x-grid3-cell-inner, .x-grid3-hd-inner { white-space:normal !important; }</style><a href=/prod/syslog.pl?mode=syslog&act=edit&id=428193&type=FromHost&stage=1>1.1.1.1</a>',
'<style type=text/css>.x-grid3-cell-inner, .x-grid3-hd-inner { white-space:normal !important; }</style><a href=/prod/syslog.pl?mode=syslog&act=edit&id=428193&type=DeviceReportedTime&stage=1>2008-05-20 15:43:44</a>',
'<style type=text/css>.x-grid3-cell-inner, .x-grid3-hd-inner { white-space:normal !important; }</style><a href=/prod/syslog.pl?mode=syslog&act=edit&id=428193&type=Facility&stage=1>KERN</a>',
'<style type=text/css>.x-grid3-cell-inner, .x-grid3-hd-inner { white-space:normal !important; }</style><a href=/prod/syslog.pl?mode=syslog&act=edit&id=428193&type=Priority&stage=1>LOG_INFO</a>',
'<style type=text/css>.x-grid3-cell-inner, .x-grid3-hd-inner { white-space:normal !important; }</style><a href=/prod/syslog.pl?mode=syslog&act=edit&id=428193&type=Message&stage=1>Inspecting /boot/System.map</a>',
'<style type=text/css>.x-grid3-cell-inner, .x-grid3-hd-inner { white-space:normal !important; }</style><a href=/prod/syslog.pl?mode=syslog&act=edit&id=428193&type=SysLogTag&stage=1>kernel:</a>',
'<style type=text/css>.x-grid3-cell-inner, .x-grid3-hd-inner { white-space:normal !important; }</style><a href=/prod/syslog.pl?mode=syslog&act=delete&id=428193>Ack</a>']

];

var myReader = new Ext.data.ArrayReader({}, [
{name: 'ID'},
{name: 'Host'},
{name: 'Date_Time'},
{name: 'Facility'},
{name: 'Priority'},
{name: 'Message'},
{name: 'Tag'},
{name: 'Ack'}
]);

var filters = new Ext.grid.GridFilters({
filters:[
{type: 'numeric', dataIndex: 'ID'},
{type: 'string', dataIndex: 'Host'},
{type: 'date', dataIndex: 'Date_Time'},
{
type: 'list',
dataIndex: 'Facility',
options: ['KERN','USER','MAIL','DAEMON','AUTH','SYSLOG','LPR','NEWS','UUCP','CRON','AUTHPRIV','FTP','NTP','LOG_AUDIT','LOG_ALERT','CLOCK','LOCAL0','LOCAL1','LOCAL2','LOCAL3','LOCAL4','LOCAL5','LOCAL6','LOCAL7'],
},
{
type: 'list',
dataIndex: 'Priority',
options: ['EMERG','ALERT','CRIT','ERR','WARNING','NOTICE','INFO','DEBUG'],
},
{type: 'string', dataIndex: 'Message'},
{type: 'string', dataIndex: 'Tag'},
{type: 'boolean', dataIndex: 'Ack'}
]});



var dstore = new Ext.data.Store({
proxy: new Ext.data.PagingMemoryProxy(Ext.grid.myData),
reader: myReader,
remoteSort: true,
autoLoad: {params: {start: 0, limit: 9}}
});



var grid = new Ext.grid.GridPanel({
store: dstore,

cm: new Ext.grid.ColumnModel([
{header: 'ID', width: 20, sortable: true, locked:true, dataIndex: 'ID'},
{header: 'Host', width: 100, sortable: true, locked:true, dataIndex: 'Host'},
{header: 'Date_Time', width: 120, sortable: true, locked:true, dataIndex: 'Date_Time'},
{header: 'Facility', width: 100, sortable: true, locked:true, dataIndex: 'Facility'},
{header: 'Priority', width: 100, sortable: true, locked:true, dataIndex: 'Priority'},
{header: 'Message', width: 200, sortable: true, locked:true, dataIndex: 'Message'},
{header: 'Tag', width: 80, sortable: true, locked:true, dataIndex: 'Tag'},
{header: 'Ack', width: 60, css: '{white-space:normal;}', sortable: false, dataIndex: 'Ack'}
]),
viewConfig: {
forceFit: true,
autoFill : true
},
title: 'Grid syslog Management',
autoFit: true,
autoExpandColumn: 'Host',
autoHeight: true,
frame: true,
enableColLock: false,
loadMask: true,
plugins: filters,
id: 'grid',
renderTo: 'dgrid',
bbar: new Ext.PagingToolbar({
pageSize: 9,
store: dstore,
plugins: filters,
displayInfo: true
})
});

grid.getSelectionModel().selectFirstRow();

grid.render();

// trigger the data store load
//dstore.load({params:{start:0, limit:15}});


});

marmots
25 May 2008, 1:15 AM
Congratulations, nice work...

I've used on my application, it was really easy to integrate with my existing Grid... and really powerfull...

only one question: it's possible to clear all filters by code? how?

Thanks,

Here is my java code (I'm using it to query via XPath, not SQL):


logger.debug("--> Filers");
String queryString = "";
for (int i = 0; true; i++) {
String field = request.getParameter("filter[" + i + "][field]");
if (field == null) {
queryString += queryString.length() > 0 ? "]" : "";
break;
}
queryString += queryString.length() == 0 ? "[" : " and ";
String comparison = request.getParameter("filter[" + i + "][data][comparison]");
if (comparison != null) {
if (comparison.equals("lt")) {
comparison = "<";
} else if (comparison.equals("gt")) {
comparison = ">";
} else if (comparison.equals("eq")) {
comparison = "=";
}
}
String type = request.getParameter("filter[" + i + "][data][type]");
String value = request.getParameter("filter[" + i + "][data][value]");

if (logger.isDebugEnabled()) {
logger.debug("Filter found: " + field);
logger.debug("--- field: " + field);
logger.debug("--- comparison: " + comparison);
logger.debug("--- value: " + value);
}

if (type.equals("string")) {
queryString += "ucase(@" + field + ") like \"%" + value.toUpperCase() + "%\"";
} else if (type.equals("date")) {
queryString += "@" + field + " " + comparison + " \"" + value + "\"";
} else if (type.equals("numeric")) {
queryString += "@" + field + " " + comparison + " " + value + "";
}
}
query += queryString;
logger.debug("End of Filers >--");

ethan
25 May 2008, 1:17 AM
dterle - set your options array to the same array you set your SimpleStore dataArray to, ie

options: [['0', 'Mlle'],['1', 'Mme'],['2', 'M.']],(or better still have one named array variable that both point to).

Hi, I got the same question as dterle
the filter store config looks like don't work with SimpleStore object, but data.Store.
and sometime you just need the same SimpleStore a lot
you don't want to use options: [....] everywhere

is there any way to use SimpleStore for options?
something we don't have to convert by ourself

for example, in my case, i just convert by myself:


function dsToArray(ds) {
var foobar = new Array();
for (var i=0; i < ds.data.length; i++) {
foobar[i] = ds.data.items[i].json;
};
return foobar;
}

var dsYesNo = new Ext.data.SimpleStore({
fields: ['value', 'name'],
data: [[0, 'No'], [1, 'Yes']]
});

var filters = new Ext.ux.grid.GridFilters({
filters: [
{type: 'list', dataIndex: 'active', options: dsToArray(dsYesNo)}
]
});

aresot
28 May 2008, 9:29 AM
Thanks for sharing your plugin Abience. Very usefull.
I was wondering if anyone tried to mark filtered column in the header with image icon instead of font. I tried to change style for the filter but changing background-image will break default background for the header.
After digging deeper into source code I see that its possible to change header cell template and overwriting GridView.prototype.renderHeaders but then it would be hacking.

Anyone solved this or have better idea?

Thanks.

el_dark
30 May 2008, 12:10 PM
Didn't know that this existed =( I was struggling all morning with some colleagues to know how to filter on our grids... until I saw this :) it's a bit too long to read all the js files though, is there a particular order or specific set of files which I can modify to adapt the plugins to my data? for the moment I'm assuming it is [ambience's source root]\ux\grid\GridFilter.js, am I right?

btw, thanks for your great filter :) I tried the demo @ your site and works just fine

mjlecomte
30 May 2008, 2:36 PM
Didn't know that this existed =( I was struggling all morning with some colleagues to know how to filter on our grids... until I saw this :) it's a bit too long to read all the js files though, is there a particular order or specific set of files which I can modify to adapt the plugins to my data? for the moment I'm assuming it is [ambience's source root]\ux\grid\GridFilter.js, am I right?

btw, thanks for your great filter :) I tried the demo @ your site and works just fine

I believe this plugin is now included in the download package, so there's a working version in your local download. Check the various grid demos.

pantarhei
2 Jun 2008, 5:40 AM
not sure. but i think there's a bug in RangeMenu.js.

i tried to use the fieldCfg without success. After changing the fields creation the config worked like expected. i'm not sure what cfg.gt, cfg.lt and cfg.eq stands for, but if a config object is passed it will never work. changing the lines to this helped me out.




var fields = this.fields = Ext.applyIf(this.fields || {}, {
'gt': new Ext.ux.menu.EditableItem({
icon: this.icons.gt,
editor: new cls(typeof cfg == "object" ? cfg || '' : cfg.gt)}),
'lt': new Ext.ux.menu.EditableItem({
icon: this.icons.lt,
editor: new cls(typeof cfg == "object" ? cfg || '' : cfg.lt)}),
'eq': new Ext.ux.menu.EditableItem({
icon: this.icons.eq,
editor: new cls(typeof cfg == "object" ? cfg || '' : cfg.eq)})
});

mystix
2 Jun 2008, 5:51 AM
@pantarhei

configs for greater than (gt), less than (lt) and equals (eq)?

Rotomaul
2 Jun 2008, 4:58 PM
Hi. This is a RoR and Ext newbie's take on the Grid and Grid Filter RoR back end code after reading through this forum. Thanks to ambience for this plugin and thanks to Zyclops (http://extjs.com/forum/showthread.php?p=77326#post77326) for his example. Hope it will be useful for someone.

Update: It now correctly handles the 'list' filter type with more than one value. Make sure phpMode is true in the javascript filters definition: e.g. filters = new Ext.ux.grid.GridFilters({filters:[ {type: 'list', dataIndex: 'col1', options: ["1", "2", "3"], phpMode: true}, ...


def grid_filter
minlimit = 15 #Minimun number of rows displayed

gf_offset = (params[:start] || 1).to_i
gf_limit = (params[:limit] || minlimit).to_i
gf_sortcol = (params[:sort] || 'created_at')
gf_sortdir = (params[:dir] || 'DESC')

gf_total = Datatable.count

if gf_offset > gf_total
gf_offset = gf_total
elsif gf_offset < 0
gf_offset = 0
end

if gf_limit <= minlimit
gf_limit = minlimit
end

if not Datatable.column_names.include?(gf_sortcol.to_s) #Verify sort column field name
gf_sortcol = 'created_at'
end

if gf_sortdir != 'ASC' and gf_sortdir != 'DESC'
gf_sortdir = 'DESC'
end

records = Datatable.find(:all,
:conditions => buildFilterOptions(params[:filter]), #Get grid filter SQL condition string
:limit => gf_limit,
:offset => gf_offset,
:order => gf_sortcol + ' ' + gf_sortdir)

render :json => {:total => gf_total.to_s, :rows => records}
end

def buildFilterOptions(filter_hash)

return '' if filter_hash.nil? #Return an empty string if the filter is empty

fs = ''

filter_hash = filter_hash.delete_if {|key, value| value.blank? }
filter_hash.each do |columns, fvals|
fs_tmp = ''

gf_field = fvals[:field].downcase
gf_type = fvals[:data][:type].downcase
gf_type = '' unless Datatable.column_names.include?(gf_field) #Verify field name
gf_value = fvals[:data][:value]
gf_comparison = fvals[:data][:comparison]

case gf_type
when 'numeric'
case gf_comparison
when 'gt'
fs_tmp = '>'
when 'lt'
fs_tmp = '<'
when 'eq'
fs_tmp = '='
when 'ne'
fs_tmp = '!='
end
gf_value = gf_value.to_i
fs_tmp = gf_field + ' ' + fs_tmp + ' ' + gf_value.to_s unless fs_tmp.empty?
when 'string'
fs_tmp = gf_field + ' like \'%' + gf_value + '%\''
when 'boolean'
gf_value = gf_value.downcase
if gf_value == 'true' or gf_value == 'false'
fs_tmp = gf_field + ' = ' + gf_value
end
when 'list'
fs_tmp = buildFilterOptions_List(gf_value, gf_field) #Need to implement your own data validation
when 'date'
case gf_comparison
when 'gt'
fs_tmp = '>'
when 'lt'
fs_tmp = '<'
when 'eq'
fs_tmp = '='
when 'ne'
fs_tmp = '!='
end
#Note: I modified DateFilter.js 'dateFormat' from 'm/d/Y' to 'Y-m-d'
fs_tmp = gf_field + ' ' + fs_tmp + ' \'' + gf_value + '\'' unless fs_tmp.empty?
end

if not fs_tmp.empty?
fs = fs + ' AND ' unless fs.empty?
fs = fs + fs_tmp
end
end

fs
end
end

def buildFilterOptions_List(val, key)

if val.nil? or val.empty? or key.nil? or key.empty? then return val end

skey = key + ' = '
rtn = ''
cnt = 0
if val.include? ','
val.split(',').each {|sval|
rtn = rtn + ' OR ' unless cnt < 1
rtn = rtn + skey + sval
cnt += 1
}
rtn = '(' + rtn + ')' unless cnt <= 1
else
rtn = skey + val
end
rtn
end

zhiliang
5 Jun 2008, 2:27 AM
hello, first thanks for this great plugin, it's awesome

I try to use the jsonstore to update the List filter, but it doesn't work very well, first it can not pass the right data to the server side,


my store is like this:


var teamstore = new Ext.data.Store({
proxy: new Ext.data.HttpProxy({
url: './php/backend.php',
method: 'POST'
}),
baseParams:{task: "showTeam"},
reader: new Ext.data.JsonReader({
root: 'team'
}, [
{name: 'text', mapping : 'team'},
{name: 'team', mapping : 'team'}

])
});then i set the list filter:

{type: 'list', dataIndex: 'team', store: teamstore, phpMode: true},

it shows correct but i check the firebug that every time it send some numbers as the filter value, so i check the ListFilter.js and I found it will send the item id as value, i made some changes:

in onLoad function i add:

item.value = records[i].get(this.labelField);

and in checkChange

this.menu.items.each(function(item){
if(item.checked)
value.push(item.value);
},this);

It seems work fine, but there is new problem, teamstore is based on some other comboboxes, so the data will change when they update, if I do not uncheck the menuItem and only uncheck the filter menu , it will keep the value in the Fliter, so next time when the grid update , even in the filter list there is not these menuItem anymore, it will still send the old values to the server, anyone know how to solve this problem? thx


Figure it out, onLoad() add this.value = [];

stradej
5 Jun 2008, 10:27 PM
Is it possible to use more than one column in large list filter?

AlxH
7 Jun 2008, 12:12 AM
Is it possible to use more than one column in large list filter?

not two columns, but i use this for long menus:


Ext.override(Ext.menu.Menu,{
listeners:{ // Make long menus scrollable
show : function(m) {
var maxHeight = Ext.getBody().getHeight() - 30;
if (m.el.getHeight()+m.el.getY() > maxHeight) {
m.el.setHeight(maxHeight-m.el.getY());
m.el.applyStyles('overflow:auto;');
}
}
}
});

mahendragayatri
8 Jun 2008, 9:12 PM
Hello,

Can anyone pls point me to where I can get the Grid-filter example code.
I saw the demo and it seems really good.. It would be great if someone could help me implement it.

wm003
8 Jun 2008, 9:40 PM
Download the latest Ext 2.1 Distribution.Then you will find it under

ext-2.1\examples\grid-filtering

jarofclay
9 Jun 2008, 12:07 PM
Great plugin!

We have been using this on table data where some of the numeric values are null (or string values) and can't find a way to filter where XCOL = NULL. If the filter box is empty then the filter will not activate.

Is there a way to override this so it will allow for blank or null?

FireGlow
11 Jun 2008, 4:56 AM
Ehm... short question!

Where I have to install the files to use ux? I tried to copy it in widgets, but then I get an error that Ext.ux.... is undefined!

Sorry for my stupid question, but I didn't find the answer in the first 20 sites here. :-)

mjlecomte
11 Jun 2008, 6:22 PM
Ehm... short question!

Where I have to install the files to use ux? I tried to copy it in widgets, but then I get an error that Ext.ux.... is undefined!

Sorry for my stupid question, but I didn't find the answer in the first 20 sites here. :-)
This plugin is included in the download package for ext. Just find it in your local examples and you'll see all the files etc. It even includes the php serverside code.
/examples/grid-filtering/grid-filter.html

jarofclay
13 Jun 2008, 4:58 AM
Is there a way to filter on an empty field?

JorisA
16 Jun 2008, 12:00 PM
Hm slightly offtopic but I would like to point out that vinylfox's code looks VERY vulnarable for SQL injection. I suggest mysql-escaping all user input.

Furtermore, nice update. I only notice a bit inconsistance between icon and iconCls variables.

peio72
17 Jun 2008, 1:37 AM
OK I have tried to use this method to send filters as parameters:


I'm using it with ColdFusion, but it required overriding the buildQuery() method to send "cleaner" name/value pairs to the server.


Ext.override(Ext.ux.grid.GridFilters, {
buildQuery: function(filters) {
var p = {};
var filterlist = [];
var field, type, comparison, value;
for(var i = 0, len = filters.length; i < len; i++) {
field = filters[i].field;
type = filters[i].data.type;
comparison = null;
if(filters[i].data.comparison)
comparison = filters[i].data.comparison;
value = filters[i].data.value || '';
p[field + '_type'] = type;
if(!comparison)
p[field + '_value'] = value;
else
p[field + '_' + comparison] = value;
if(filterlist.indexOf(field) == -1)
filterlist.push(field);
}
filterlist = filterlist.join(',');
p.filters = filterlist;
return p;
}
});

The problem is when I clear a filter field (for example in a numeric filter) the params are still sent. What to do to solve that issue ?

businessman332211
19 Jun 2008, 6:36 AM
It won't let me download the "Plugin" for some reason. It downloads a file and I unzip it and it let's me look but it won't let me "Extract" it from the zip file. When I extract in the root it's an unrecognized file type, and when it's opened then extracted it throws some error. I have WinRar and I am very efficient with computers (I have been in that field and programming for a LONG time). I have never encountered this kind of problem before.

businessman332211
20 Jun 2008, 9:57 AM
Ok. I am having some major problems here and I have been working on this for almost 4 days (12-14 hours per day) and I am getting nowhere. It's friday and I most likely have to work over the weekend (saturday sunday) and then start again monday if I can't figure this out.
Basically I need to get data from a php file (done) and turn it into a grid (done). Now I need to add in filtering (I chose http://extjs.com/forum/showthread.php?t=14503).
After that I need to add in editing (not even focusing on that yet.
After posting/getting answers for awhile + Running through that ENTIRE thread for HOURS) + Looking through TONS of EXTJS tutorials/samples/sites/sample files/documentation/api) I am out of ideas. I was fighting with the "Icons" for hours but finally got it working. The whole thing is in place and I can't get it to filter locally. I am trying to pass the data back into PHP so I can work on filtering it that way but that won't work. I have no way of knowing what params are being sent. This is all in cakephp and for some reason params aren't showing up in firebug. Here is my entire code..



<script>
var AuditDataMgr = {
store : null,
grid : null,
url : '{{$html->url('/admin/users/getusers')}}',

init : function (){

// create the Data Store
this.store = new Ext.data.Store({
// load using an HttpProxy
proxy: new Ext.data.HttpProxy({
url: this.url
}),

// 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
remoteSort: false
});
// Plugin Code: 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: 'string', dataIndex: 'subarea'},
{type: 'string', dataIndex: 'city'}
]});
// create the Grid
this.grid = new Ext.grid.GridPanel({
store: AuditDataMgr.store,
columns: [
{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'}
],
loadMask: true,
stripeRows: true,
collapsible: false,
collapsed: false,
plugins: filters,
height:350,
width:1100,
title:'Users Data'
});
this.grid.on('load', AuditDataMgr.loadMe);
this.grid.render('audit-data-grid');
},
load : function (){
this.store.load();
},
loadMe : function (e){
AuditDataMgr.load();
}
};
Ext.onReady(function(){
// Set this image separetly. It's very important
Ext.ux.grid.filter.StringFilter.prototype.icon = 'img/find.png';
Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
AuditDataMgr.init();
AuditDataMgr.loadMe();
});
</script>
<link rel="stylesheet" type="text/css" href="/css/extcss/auditgrids.css" />
<!-- Common Styles for the examples -->
<div id="audit-data-grid"></div>
<br>


I can't reveal more than that because it's an internal system. The things I don't get is why it's not working. This code might be changed but I had the local variable set to true (didn't work) I had A LOT of things I have tried within about...36 hours total this week. Plus the weekend will make it...60 ALL focusing on why this filter won't filter. I have been in this business awhile but my Javascript Experience has never been RICH but being forced to use it SO much within the past year has gotten me a lot better. I am totally lost. I have no way of trying this out and I am completely confused. The PHP file is just a file that goes and get's the data and encodes it into JSON and echo's it for the ExTJS to grab. The entire grid works perfectly but when it goes to filter it just thinks awhile then reloads the page again with no filtering done.
Is there a way to make local filtering work...when I am using PHP to get the initial data or is that impossible. If not then how do I get teh parameters using cake...there not showing in firebug and I can't echo out $this->params because it just throws an error since it's expecting to retrieve JSON. I have used every mental resource I have on figuring this out and I am stuck..

mjlecomte
21 Jun 2008, 2:53 AM
businessman332211

If I were you, I would figure out how to work with your server without any plugins, extensions, etc. You're complicating things if you don't figure out the basics first. Get a simple grid working with data backed from your server, verifying that you can see the transactions between client and server with firebug or fiddler.

Once you get that part working then slowly add features like editing and filtering. I'm pretty sure I saw a full working example of an editor grid with this filter plugin posted somewhere in the forums/tutorials.

businessman332211
21 Jun 2008, 5:07 AM
* I have figured out the basics (far beyond that with how much time I put into EXTJS.
* As I mentioned in the post..I have a fully functional grid retrieving/showing data from a php file.
* I have the basic implementation of the "filtering up" I can see the filter icon in the menu but when I filter it just returns the original set of data.

I have done everything "basic". There isn't anything on the net to "read" about the filtering that I haven't read. I even went through it's ENTIRE post very slowly. FOllowing every link, reading every word. I am far from in-experienced so I knew all the standard things to try first before posting. After all of this I am still to the point where it's not filtering. I even saw how to do local filtering and put in the code for that but it has no affect like that either.

mjlecomte
21 Jun 2008, 5:15 AM
My point about 'basic' is that you need to see what is being sent to/from your server. You said you don't know. You need to be able to see that to understand what to do. Check some of the demos delivered with the ext download package that use php....can you see what is sent with post/response in those examples?

businessman332211
23 Jun 2008, 7:54 AM
Ok...Well I did what you said. I finally found something in cake that let me log out the errors as an array so I can see what is in the $this->params. I found something strange. The first time it goes to get the data it sends nothing (obviously) via post or get (whichever i set it to). But...when the filter goes it sets NOTHING when I try to send it through POST. When it goes through get it adds on one param...


[url] => Array
(
[url] => admin/users/getusers
[_dc] => 1214236025731
)


That is what it returns. But that number changes everytime. So instead of sending filters (like it's suppose to) it's sending that parameter with a random number attached. The coding I am using seems to all be correct. The code I posted in an above post is exactly what I have and I have gotten that together from tons of examples in the forum and other parts of the net. Any advice on why this is happening?

businessman332211
23 Jun 2008, 7:57 AM
I was able to find a $this->log function inside of cake that let me log the array of $this->params so I could finally see what all was going on.
First of all the initial data gathering (the first time ExtJS goes and get's the data for the grid) it sends nothing (either post or get) which is as expected. However the second time (when it's trying to filter) if I send it via post it sends nothing. If I send it via get then it sends something that makes no sends. It sends a dc parameter with a random string of numbers (that randomizes each time it hits the server for filters). This is very strange and unexpected. Any ideas on what I may have done wrong (the code I am using is in one of my earlier posts.
But cake returns


[url] => Array
(
[url] => admin/users/getusers
[_dc] => 1214236025731
)


That's what being sent when it's sent via GET when it's trying to get filters. I don't understand why. When I change method to POST it sends nothing.

AlxH
23 Jun 2008, 10:09 AM
The "_dc"-param in get-requests are there to prevent the browser from caching - this is pretty normal.
To debug you should use firefox with firebug, there is no better tool I know of.
You can see every request with post and get-params in firebug under "console" or "net".

If you use PHP you can drop something like


file_put_contents("debugfile.txt",print_r($_POST,true),FILE_APPEND);

in your PHP-Code to log all post params in a file.


I was able to find a $this->log function inside of cake that let me log the array of $this->params so I could finally see what all was going on.
First of all the initial data gathering (the first time ExtJS goes and get's the data for the grid) it sends nothing (either post or get) which is as expected. However the second time (when it's trying to filter) if I send it via post it sends nothing. If I send it via get then it sends something that makes no sends. It sends a dc parameter with a random string of numbers (that randomizes each time it hits the server for filters). This is very strange and unexpected. Any ideas on what I may have done wrong (the code I am using is in one of my earlier posts.
But cake returns


[url] => Array
(
[url] => admin/users/getusers
[_dc] => 1214236025731
)

That's what being sent when it's sent via GET when it's trying to get filters. I don't understand why. When I change method to POST it sends nothing.

businessman332211
23 Jun 2008, 11:02 AM
Just for "Sanity" sake I spent 4 hours this morning going over EVERY single post within this thread VERY carefully. I have reformatted/redone a lot of my code. It's listed below.

Ok first off I am in a Cakephp framework/php (just so you know).
have rewritten this which solved A LOT of my issues now that I studied this entire thread and tried everything and I know practically what all of the following code does. Here is my problem..the params are not (for a fact) getting set (AT ALL). Whether I send them via Post or via Get they are not getting set either way. That's the current problem. I have verified this in firebug. I also used an example based off what you gave me and something in cake to echo out the params (which is everything that's being passed via get and post) and I was saving that into a log file so I could view it. But NONE of the filters in ANY way are getting passed via get or post when either of them is set. I have no idea what is wrong. Is there something wrong with my code. I compared mine practically line by line with many others on here that said it was working and I see nothing wrong with my code. Does it have something to do with cake doing something to the date getting sent or something. The GRID itself works perfectly the first time it's loaded. Then I perform a filter and it reloasd the data (proving it's hitting the server) but it's just not passing all of the filter data for some reason...
Any advice would be greatly appreciated. After working on this for 2 weeks i have come a long ways and this is my last obstacle (making the filtering work). After that I can finally start on the editing functionality.


// 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')}}',
method: 'POST'
}),
// 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
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;
// 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>

businessman332211
23 Jun 2008, 11:17 AM
Update:
Ok something strange is going on here.
2008-06-23 15:13:01 Debug: Array
(
)
2008-06-23 15:13:36 Debug: Array
(
[sort] => first_name
[dir] => ASC
)
2008-06-23 15:13:59 Debug: Array
(
[sort] => first_name
[dir] => ASC
)
I was doing an echo of $this->params (This is SUPPOSE to carry everything related to get and post that is passed into CakePHP) (it's the internal cakephp method of handling incoming variables)....
Well when I redid it using just $_POST
then that's what I got. I don't understand...the sorting wasn't even being passed into cake. The filters still aren't showing up for some reason but the sorting is obviouslly... Well it's more of I go in and filter USING first name and then submit the filter but it comes up like this as a sort information?
I don't see the actual filter data. Also I am still heavily confused as to why the POST wasn't present inside of cakes $this->params in the first place. This stuff is now present but not correct. I did a filter search under first_name for "Adam" and it's not going through.

businessman332211
23 Jun 2008, 11:23 AM
More Discoveries..ok I did more testing and this is what I found.
If I print out the
$_POST and try it with post and then $_GET and try it with get here are the results.

* Being sent via $_POST method with local set to true it prints out what I listed in the previous post (about sorting but nothing about the filtering).
*Being sent via $_POST method with local set to false it actually sends out absolutely nothing. The post is empty then.
* Being sent via $_GET method with local set to true it prints out what I listed in the previouspost. All it sends is the DC parameter (nothing to do with filters)
* Being sent via $_GET method with local set to false it actually sends absolutely nothing. The Get is empty then. All it sends is the DC parameter. (Nothing to do with filters).

Either way I lose. Basically either of the 4 ways of trying it reveal that no matter what/how I send it the data isn't getting sent by either $_GET, $_POST, or cakephp' built in $this->params. Nothing is being sent in any of those no matter how I attempt to setup the filters.

steppinrazor
23 Jun 2008, 2:53 PM
OK I have tried to use this method to send filters as parameters:



The problem is when I clear a filter field (for example in a numeric filter) the params are still sent. What to do to solve that issue ?

What you had to do was define your custom buildQuery function inside the Ext.ux.grid.GridFilters config e.g.



var filter = new Ext.ux.grid.GridFilters(
{
filters:[
{type:'numeric',dataIndex:'id'},
....
],
buildQuery:function(filters){
....
}
}
)

hendricd
23 Jun 2008, 6:50 PM
Either way I lose......

@businessman332211 (perhaps others) -- Not so fast. If I could recommend a couple things to check:

filters.local = true
In this mode, your active filters are applied to the underlying store directly (using store.filterBy functions) to limit what is rendered in the current gridView. The filters are not serialized to request parameters in this mode.

- If you intend to do server-side filtering, you must use local:false.

Custom Filter param encoding.
Some find the default parameter encoding a bit daunting for the server-side. To modify the serialization (params encoding) of the filter criteria for use on the server, you generally have two choices:

1) Override the the GridFilters::buildQuery function. An alternate filter-encoding strategy can be found here (http://extjs.com/forum/showthread.php?p=89375#post89375) (and more about it here (http://extjs.com/forum/showthread.php?p=121460#post121460)). Using that or a similar approach you can design your filter request 'protocol' to suite your query-engine needs.

2) Use your stores' 'beforeload' event to massage the filter criteria into the format desired. BUT, remember that your new filter 'beforeload' listener may not be the only one (or the first) in the 'load event chain'. Make sure you assert options.params before you mess with it too badly:


myGrid.getStore().on('beforeload',
onBeforeLoad: function(store, options){
options.params || (options.params = {}); //assert, but add to any existing collected params
this.cleanParams(options.params); //make sure prev criteria are erased.
var queryParams = this.buildQuery(this.getFilterData());
Ext.apply(options.params, queryParams);
},myGrid.filters);
If (while filters are active) you'd like to see what GridFilter thinks the current critera are, try a
console.log( grid.filters.getState() );That will give you hash object showing what's currently active. (I good test to see if you've got the filters setup properly.)

Yes, GridFilters is state-aware (remembering the last filter criteria -- if you set it up properly).
>:) Turn all the state-management crap OFF (and delete any such exising cookies) until you've got the basics working, or you'll be choking on your own cookies. :s

If you're not sending any POST/GET filter params with local:false, one of the above (or close relative) are usually the culprit. :-?

LeonardoAP
24 Jun 2008, 5:23 AM
Heya, i got a problem,

i used this workaround to put a maxLength in the input of an editing cell


Ext.override(Ext.form.TextField, {
afterRender: function(){
Ext.form.TextField.superclass.afterRender.call(this);
if(this.maxLength){
this.el.dom.maxLength = this.maxLength;
}
}
});


After that, the filter for this column is comming with maxlength=0, blocking me to enter a text to filter by.
I don't know why, but it's possibly a little bug.

LeonardoAP
24 Jun 2008, 5:45 AM
Obs:
if i put a static value in place of this.maxLength, it works!



Ext.override(Ext.form.TextField, {
afterRender: function(){
Ext.form.TextField.superclass.afterRender.call(this);
if(this.maxLength){
this.el.dom.maxLength = 20;
}
}
});


very strange, somehow it tries to copy the editors input configurations, but it can't take the this.maxLength value.

businessman332211
24 Jun 2008, 6:47 AM
Ok. I tried everything that was listed. First off I wanted to make sure I wasn't missing anything. inside of cake I setup...


$this->log($_POST, LOG_DEBUG);
$this->log($_GET, LOG_DEBUG);
$this->log($this->params, LOG_DEBUG);

That will let me see every parameter of every type to find out if it's hitting cake at all. Also as a secondary test I also check firebug and check all it's parameters. I do this on every change I make to the script to see if that's what might be the problem. Well..I just tried everything that was listed here recently and more.
I played with the override code and buildquery as was requested. Again my ORIGINAL code is


<script>
// 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')}}',
method: 'POST'
}),
// 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
remoteSort: true
});
var filters = new Ext.ux.grid.GridFilters({
local: false,
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'}
]});
// 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>


The first thing I tried was the "Override" function that was requested with build query. I tried ALL of the following one after another and testing the output of parameters after each one.


Attempt One
Ext.override(Ext.ux.grid.GridFilters, {
buildQuery: function(filters) {
var p = {};
var filterlist = [];
var field, type, comparison, value;
for(var i = 0, len = filters.length; i < len; i++) {
field = filters[i].field;
type = filters[i].data.type;
comparison = null;
if(filters[i].data.comparison)
comparison = filters[i].data.comparison;
value = filters[i].data.value || '';
p[field + '_type'] = type;
if(!comparison)
p[field + '_value'] = value;
else
p[field + '_' + comparison] = value;
if(filterlist.indexOf(field) == -1)
filterlist.push(field);
}
filterlist = filterlist.join(',');
p.filters = filterlist;
return p;
}
});
Attempt Two
Ext.override( Ext.ux.grid.GridFilters , {
buildQuery : function(filters) {
var p = {};

for (var i = 0, len = filters.length; i < len; i++) {

var f = filters[i];

var root = [this.paramPrefix,'-', f.data.type , '-', f.field].join('');

if (f.data.type == 'date') {

if (f.data.comparison == 'gt') {
p[root+'-after'] = f.data.value; //yields:{filter-date-invoicedate-after:value}
}
if (f.data.comparison == 'lt') {
p[root+'-before'] = f.data.value;
}
if (f.data.comparison == 'eq') {
p[root+'-datetime'] = f.data.value;
}
} else {
p[root] = f.data.value;
}
if(f.data.format){
p[ [this.paramPrefix,'-',f.data.type,'-format'].join('') ]= f.data.format;
}

}

return p;

},
/**
* Removes filter related query parameters from the provided object.
*
* @param {Object} p Query parameters that may contain filter related fields.
*/
cleanParams: function(p){
var regex = new RegExp("^" + this.paramPrefix + "-"); //loose but adequate
for(var key in p)
if(regex.test(key))
delete p[key];
}

});Attempt ThreeExt.override( Ext.ux.grid.GridFilters , {
cleanParams : function(p) {
var params = this.paramPrefix.split(',');

for (var i = 0, len = params.length; i < len; i++) {

var regex = new RegExp('^' + params[i]);
for (var key in p) {

if (regex.test(key)) {

delete p[key];

}

}

}
}

});


Those are example uses I found throughout the posts you linked. I tried all of them I could find in any of the posts...and a few of my own variations. This had practically "no" affect on the result of what was happening. All the same things happen when I run the code whether I try to use these methods or not.

Another thing I noticed is that you said I HAD to set Local to true. I have that in there now definitely (as you can see in my posting of original code). I also for EACH change I make to it to try and get it to work I try sending it a method of POST then a method of GET to see if ANY of the changes make it work with one or the other butboth are the same thing. The ONLY difference is that the "GET" always contains that DC parameter that I mentiond earlier but that was explained to me.

Also I made sure all state management code was off as you suggested.

I have tried everything and I am still at the point where it's not working. Any other advice. When yuo look over my original code do you see anything I might have done wrong during the implementation. That code I took from someone who is working on the same project as me but used it in another area. He had collapsing menus and everything so I had to rewrite it in it's base form. I read through this thread here about 6 times (reading every word from beginning to end) + studying code examples + studying the source and I finally was able to rewrite everything that guy did and I had practically a full understanding of all of the coding nd what it was doing. Once the grid worked I studied the filters for awhile and after I had an understanding of how they worked I was stumped that it wasn't working. Now I am confused more than ever. As I mentioned before I am using CakePHP framework..does that have something to do with what's happening to my parameters. It also has Smarty templating engine built into it. Do you think that can all have something to do with it. Either way....We have used many different ajax frameworks/coding before and it's never been adversely affected by cake before.

hendricd
24 Jun 2008, 7:16 AM
filters.local = true
In this mode, your active filters are applied to the underlying store directly (using store.filterBy functions) to limit what is rendered in the current gridView. The filters are not serialized to request parameters in this mode.

- If you intend to do server-side filtering, you must use local:false.

Might want to read that again. /:)

businessman332211
24 Jun 2008, 7:22 AM
Yes. I read it. It basically says:
If local is set to TRUE then you have to write up javascript coding using built in functions from the plugin to manually sort (I couldn't figure out how to get this working so I am trying the other method).
It says if local is set to false then it's suppose to send the filter data to the server instead?

That is what I understand from reading that. Did I mss something?

businessman332211
24 Jun 2008, 7:25 AM
Unless you are trying to tell me that since it's not sending parameters server side I should try to do it locally? I could but I have no idea how to use those functions. Are there any "Examples" of filterBy because I didn't see anything like that when I went through the Forum those 4 times. Atleast not that I noticed. That still confuses me as to why they weren't being sent server side in the first place..but locally would be ideal anyway at sorting because it would be faster. So if you think it will work I can give it a try. If I am originally getting data FROM the server will it allow me to sort locally as well? I thought local sorting only worked if the data was naturally "Local" and not dynamic. More like static arrays?

hendricd
24 Jun 2008, 7:30 AM
If your goal is to filter server-side and sort locally, then

GridFilter.local must be false,and
Store.remoteSort should be false .

Does the gridpanel render any records at all without any active filters?

businessman332211
24 Jun 2008, 8:04 AM
Ok. Just to make sure we are on the same page here is my ultimate goal.
1. Get data from the database and show a grid.
2. Make it where the grid can be filtered (one is numeric the rest are strings)
3. Make a small form and do an ajax call to add new records
4. Make the grid editable.

That's IT. Right now I have finished number 1 and I am working on number 2 (3 and 4 should be easy). Now that's where I am trying to get.

Where I am at: Number 1 is completely done and I am trying to do number 2.
I don't mind whether it's server side or local. In fact LOCAL would be preferred since it's faster.

Now as far as server side. I have GUARANTEED that Local was set to false before I tried. Remote sort was also set to false. Both of those were FALSE when I tried to do it via server side and I also tried this in both POST and GET methods. Either way nothing is passed through Get, Post or cakes $this->param.

Now as far as doing it Local. If I could get it to work Locally that would be even better. The thing is I have no idea where to even "Find" the filterBy function. I looked through filters.js and gridfilters.js and can't find that function anywhere. Also I have NO idea how to implement it. I saw nothing in this post about it and I did a global search of the forum and found some broken examples that are hard to piece together.

As far as your question about does it render any records...yes. I have a page that has AJAX code (that I posted an earlier post ago). IN there you can see where I set the URL and the filters and everything. When the page FIRST loads it retursn all of the data in the database (like it should) when I filter it thinks a minute and returns the data again but it's all of the data in the database again. The parameters are not set when this happens for some reason.

So either way I am lost. I just want the filtering done but I have no idea how to do it locally. I could easily do it using PHP server side but I can't get the parameters to go through no matter what I try. There isn't much I haven't tried at this point.

If there is any other advice or anything else I can try I would be GREATLY appreciative. This is going on the second week I have been fighting with this and I still have to finish the editing functionality after this (which shouldn't be much of a problem).

hendricd
24 Jun 2008, 8:21 AM
Post your current GridPanel/filters config (only) for review.

businessman332211
24 Jun 2008, 8:25 AM
Note sure what you mean by config only. I posted my entire code a few posts above. Maybe you mean my config options?



el: 'audit-data-grid',
autoFitColumns: true,
loadmask: true,
store: store,
cm: column_model,
plugins: filters,
stripeRows: true,
height:350,
width:1100,
title:'Users Data'

Those are myconfig options for the grid panel. But the other parameters for filter and sorting change depending on what I am trying to do. If I am trying out something locally then local is set to true. If I am trying to get parameters to pass the it's set to false. Same thing with remote sorting. But if you needed my code in full it's above.. Those are just my config options I have set (I have even tried messing with those some).

hendricd
24 Jun 2008, 8:28 AM
All of it then. /:)

A plain vanilla version with no fancy custom methods.

businessman332211
24 Jun 2008, 9:07 AM
Here is all of my code listed down. Also my requirements just changed. I need to do it locally if possible. So I am about to start looking online for ways to do it locally. Are there any examples in this post about the FilterBy function or where to find examples of it, or even where to find it in the code.

Here is my current code.


// 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
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;
// 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>



Notice I changed the Local to true and remote sort to true because I need to go head and do it locally now. It took me so long trying to do it via server side he changed his mind and wanted it done locally somehow.

hendricd
24 Jun 2008, 9:31 AM
Are there any examples in this post about the FilterBy function or where to find examples of it, or even where to find it in the code.

The GridFilters class handles the store.filterBy for you when local is true.

Do you have this running on a public URL somewhere?

hendricd
24 Jun 2008, 9:40 AM
Why no selection model ?

businessman332211
24 Jun 2008, 9:59 AM
What do you mean selection model? I have the store model and the filter code and the column model and the grid model? And it works. Except the filtering. What is a selection model. Also no I don't have this url it's done locally. It's for a mega-company intranet and is a completely inside (private) job I can talk very little about due to signing NDA's and other like papers.

So...I have never heard of the selection model. Is there any "Example" code anywhere of the filterBy function being used/implemented with the filters plugin so I can see a sample of how it looks so I can make a mockup of it for my own testing purposes. I want to see if this code will function properly locally if I set it up right.

hendricd
24 Jun 2008, 10:11 AM
@businessman332211 -- You're going to have to get your hands dirty at this point. It's impossible to tell what is/isn't going on from out here.

Use Firebug and start setting breakpoints during the store.load to figure out what's not happening..

businessman332211
24 Jun 2008, 10:16 AM
I gave up on the server side because of the problems I was having and because they changed the specs of the project on it (now they want it locally). Do you know of any good basic implementation examples of how to figure out what they are trying to filter by and do it locally. I am not exactly sure how to use filterBy and the thing is I am rying to figure out how to pick up what filters are in place and then do it locally. Any examples because this post has none and I saw no "General" examples of "Local" implementation.

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?