-
18 May 2011 9:02 AM #11
Hi (Filter Row)
Hi (Filter Row)
Sorry about that, I didn't send the hole implementation...
You could use the following code :
I've also modified the FilterRow code so the onChange event work with a delay on combobox.Code:Ext.create('Ext.grid.Panel', { plugins: [ Ext.create('Ext.ux.grid.FilterRow') ], store: Ext.create('Ext.data.Store', { pageSize:25, remoteSort:true, fields:[ 'id', 'siteId', 'firstName', 'lastName', 'company', 'birthday' ], proxy:{ type:'direct', directFn:Progik.Remote.Contacts.read, reader:{ type:'json', root:'rows', successProperty:'success', idProperty:'id', totalProperty:'total' } } }), columns:[ { header:'#', dataIndex:'id', nofilter:{}}, { header:'siteId', dataIndex:'siteId', filter:{ xtype:'combo', queryMode: 'local', displayField: 'name', valueField: 'id', store:Ext.create('Ext.data.Store', { fields:['id', 'name'], data:[{ id:'0', name:'test' },{ id:'1', name:'test2' }] }) } }, { header:'firstName', dataIndex:'firstName', flex:1 }, { header:'lastName', dataIndex:'lastName', flex:1 }, { header:'company', dataIndex:'company'}, { header:'birthday', dataIndex:'birthday', filter:{ xtype:'datefield', format:'Y-m-d' } } ] });
Code:Ext.define('Progik.ux.grid.FilterRow', { extend:'Ext.util.Observable', init: function(grid) { this.grid = grid; this.applyTemplate(); // when Ext grid state restored (untested) grid.on("staterestore", this.resetFilterRow, this); // when column width programmatically changed grid.headerCt.on("columnresize", this.resizeFilterField, this); grid.headerCt.on("columnmove", this.resetFilterRow, this); grid.headerCt.on("columnshow", this.resetFilterRow, this); grid.headerCt.on("columnhide", this.resetFilterRow, this); grid.horizontalScroller.on('bodyscroll', this.scrollFilterField, this); }, applyTemplate: function() { var searchItems = []; this.eachColumn( function(col) { var filterDivId = this.getFilterDivId(col.id); if (!col.filterField) { if(col.nofilter) { col.filter = { }; } else if(!col.filter){ col.filter = { }; col.filter.xtype = 'textfield'; } //console.log(col); col.filter = Ext.apply({ id:filterDivId, hidden:col.hidden, xtype:'component', cls: "small-editor filter-row-icon", width:col.width-2, enableKeyEvents:true, style:{ margin:'1px 1px 1px 1px' } }, col.filter); col.filterField = Ext.ComponentManager.create(col.filter); } else { if(col.hidden != col.filterField.hidden) { col.filterField.setVisible(!col.hidden); } } if(col.filterField.xtype == 'combo' || col.filterField.xtype == 'datefield') { col.filterField.on("change", this.onChange, this); } else { col.filterField.on("keypress", this.onKeyPress, this); } searchItems.push(col.filterField); }); if(searchItems.length > 0) { this.grid.addDocked(this.dockedFilter = Ext.create('Ext.container.Container', { id:this.grid.id+'docked-filter', weight: 100, dock: 'top', border: false, baseCls: Ext.baseCSSPrefix + 'grid-header-ct', items:searchItems, layout:{ type: 'hbox' } })); } }, // Removes filter fields from grid header and recreates // template. The latter is needed in case columns have been // reordered. resetFilterRow: function() { this.grid.removeDocked(this.grid.id+'docked-filter', true); delete this.dockedFilter; this.applyTemplate(); }, onChange: function() { if(!this.onChangeTask) { this.onChangeTask = new Ext.util.DelayedTask(function(){ this.storeSearch(); }, this); } this.onChangeTask.delay(1000); }, onKeyPress: function(field, e) { if(e.getKey() == e.ENTER) { this.storeSearch(); } }, getSearchValues: function() { var values = {}; this.eachColumn( function(col) { if(col.filterField.xtype != 'component') { values[col.dataIndex] = col.filterField.getValue(); } }); return values; }, storeSearch: function() { if(!this.grid.store.proxy.extraParams) { this.grid.store.proxy.extraParams = {}; } this.grid.store.proxy.extraParams.search = this.getSearchValues(); this.grid.store.load(); }, // Resizes filter field according to the width of column resizeFilterField: function(headerCt, column, newColumnWidth) { var editor = column.filterField; editor.setWidth(newColumnWidth - 2); }, scrollFilterField:function(e, target) { var width = this.grid.headerCt.el.dom.firstChild.style.width; this.dockedFilter.el.dom.firstChild.style.width = width; this.dockedFilter.el.dom.scrollLeft = target.scrollLeft; }, // Returns HTML ID of element containing filter div getFilterDivId: function(columnId) { return this.grid.id + '-filter-' + columnId; }, // Iterates over each column that has filter eachFilterColumn: function(func) { this.eachColumn( function(col, i) { if (col.filterField) { func.call(this, col, i); } }); }, // Iterates over each column in column config array eachColumn: function(func) { Ext.each(this.grid.columns, func, this); } });
-
23 May 2011 5:18 AM #12
the filter box does not response to onchange event
the filter box does not response to onchange event
zonereseau,
I applied your filter row code. it does display the filter boxes in the under the head row, but there is no action associate with it.
By any chance, you may know the reason why?
Thanks very much for your help.
m101
-
23 May 2011 8:59 AM #13
Well, the action are currently bind with a ENTER keypress or onChange (when is't a datefield or a combo)... also, as you can see in the code, I put params search with field name and value in the extraparams of the datastore and reload it. So by example on a PHP page receiving that query you can do.
Note that the PHP code might have error in it... I haven't tested it directly... It's more the conceptCode:$search = json_decode($_POST['search']); $size = sizeof($search); $i = 0; foreach($search as $key => $value) { $where .= mysql_real_escape_string($key).' LIKE '.mysql_real_escape_string($value).'%'; if($i < $size) { $where .= ' AND '; } } // Put your code here $rows = array(); $rs = mysql_query("SELECT * FROM table WHERE".$where); if($rs !== false && mysql_num_rows($rs) > 0) { while($assoc = mysql_fetch_assoc($rs)) { $rows[] = $assoc; } } // Return you json data here echo "{success:true, totalCount:".sizeof($rows).", rows:".json_encode($rows)."}";
-
24 May 2011 6:59 AM #14
-
27 May 2011 6:50 AM #15
Thank you zonereseau.
This is a great job.
Width the following modifications you are able to reconfigure the grid without loosing the filterrow.
Code:resetFilterRow: function () { this.grid.removeDocked(this.grid.id + 'docked-filter', true); delete this.dockedFilter; //This is because of the reconfigure if (document.getElementById(this.grid.id + 'docked-filter')) { var dockedFilter = document.getElementById(this.grid.id + 'docked-filter'); dockedFilter.parentElement.removeChild(dockedFilter) } this.applyTemplate(); } resizeFilterField: function (headerCt, column, newColumnWidth) { var editor; if (!column.filterField) { //This is because of the reconfigure this.resetFilterRow(); editor = this.grid.headerCt.items.findBy(function (item) { return item.dataIndex == column.dataIndex; }).filterField; } else { editor = column.filterField; } editor.setWidth(newColumnWidth - 2); }
-
27 May 2011 9:27 AM #16
Tanks szolarp
Tanks szolarp
Great job szolarp, I've put it in my code it work great...
I also add an exception so that the filter won't appear if you create a checkcolumn
Code:applyTemplate: function() { var searchItems = []; this.eachColumn( function(col) { var filterDivId = this.getFilterDivId(col.id); if (!col.filterField) { if(col.nofilter || col.cls == 'x-column-header-checkbox ') { ...
-
1 Jun 2011 5:37 AM #17
Thanks.
Thanks.
Thanks.
the code works great!
-
12 Jul 2011 2:12 AM #18
Hey folks,
I used your implementations above. Sadly it doesn't work with a stateful Grid.
The problem pops up when columnresize is fired at start. Then the column.filterField is undefined.
I don't know if this has worked in the past but with 4.0.2a it doesn't
IMHO I guess the issue is the line:
after the applyTemplate function ends, the reference is lost.Code:col.filterField = Ext.ComponentManager.create(col.filter);
Any Ideas?
BTW: to use the normal plugin lazy loading (works with MVC-Pattern)
And in the grid:Code:Ext.define('Ext.ux.grid.FilterRow', { extend:'Ext.util.Observable', alias: 'plugin.gridfilterrow', ...
Code:requires: ['Ext.ux.grid.FilterRow'], plugins: [{ptype: 'gridfilterrow'}]
-
12 Jul 2011 7:51 AM #19
Ext 4.0.2a modification
Ext 4.0.2a modification
Hi,
It seems that with the Ext 4.0.2a the name filter is reserved so I changed the pluggin a bit, maybe that will resolve your problem.
Code:Ext.define('Ext.ux.grid.FilterRow', { extend:'Ext.util.Observable', init: function(grid) { this.grid = grid; this.applyTemplate(); // when Ext grid state restored (untested) grid.on("staterestore", this.resetFilterRow, this); // when column width programmatically changed grid.headerCt.on("columnresize", this.resizeFilterField, this); grid.headerCt.on("columnmove", this.resetFilterRow, this); grid.headerCt.on("columnshow", this.resetFilterRow, this); grid.headerCt.on("columnhide", this.resetFilterRow, this); grid.horizontalScroller.on('bodyscroll', this.scrollFilterField, this); }, applyTemplate: function() { var searchItems = []; this.eachColumn( function(col) { var filterDivId = this.getFilterDivId(col.id); if (!col.xfilterField) { if(col.nofilter || col.isCheckerHd != undefined) { col.xfilter = { }; } else if(!col.xfilter){ col.xfilter = { }; col.xfilter.xtype = 'textfield'; } col.xfilter = Ext.apply({ id:filterDivId, hidden:col.hidden, xtype:'component', baseCls: "xfilter-row", width:col.width-2, enableKeyEvents:true, style:{ margin:'1px 1px 1px 1px' }, hideLabel:true }, col.xfilter); col.xfilterField = Ext.ComponentManager.create(col.xfilter); } else { if(col.hidden != col.xfilterField.hidden) { col.xfilterField.setVisible(!col.hidden); } } if(col.xfilterField.xtype == 'combo') { col.xfilterField.on("select", this.onSelect, this); } else if(col.xfilterField.xtype == 'datefield') { col.xfilterField.on("change", this.onChange, this); } col.xfilterField.on("keydown", this.onKeyDown, this); searchItems.push(col.xfilterField); }); if(searchItems.length > 0) { this.grid.addDocked(this.dockedFilter = Ext.create('Ext.container.Container', { id:this.grid.id+'docked-filter', weight: 100, dock: 'top', border: false, baseCls: Ext.baseCSSPrefix + 'grid-header-ct', items:searchItems, layout:{ type: 'hbox' } })); } }, onSelect: function(field, value, option) { if(!this.onChangeTask) { this.onChangeTask = new Ext.util.DelayedTask(function(){ this.storeSearch(); }, this); } this.onChangeTask.delay(1000); }, onChange: function(field, newValue, oldValue) { if(!this.onChangeTask) { this.onChangeTask = new Ext.util.DelayedTask(function(){ this.storeSearch(); }, this); } this.onChangeTask.delay(1000); }, onKeyDown: function(field, e) { if(e.getKey() == e.ENTER) { this.storeSearch(); } }, getSearchValues: function() { var values = {}; this.eachColumn( function(col) { if(col.xfilterField && col.xfilterField.xtype != 'component') { values[col.dataIndex] = col.xfilterField.getValue(); } }); return values; }, storeSearch: function() { if(!this.grid.store.proxy.extraParams) { this.grid.store.proxy.extraParams = {}; } this.grid.store.proxy.extraParams.search = this.getSearchValues(); this.grid.store.currentPage = 1; this.grid.store.load(); }, resetFilterRow: function () { this.grid.removeDocked(this.grid.id+'docked-filter', true); delete this.dockedFilter; //This is because of the reconfigure var dockedFilter = document.getElementById(this.grid.id+'docked-filter'); if (dockedFilter) { dockedFilter.parentNode.removeChild(dockedFilter); } this.applyTemplate(); }, resizeFilterField: function (headerCt, column, newColumnWidth) { var editor; if (!column.xfilterField) { //This is because of the reconfigure this.resetFilterRow(); editor = this.grid.headerCt.items.findBy(function (item) { return item.dataIndex == column.dataIndex; }).xfilterField; } else { editor = column.xfilterField; } if(editor) { editor.setWidth(newColumnWidth - 2); } }, scrollFilterField:function(e, target) { var width = this.grid.headerCt.el.dom.firstChild.style.width; this.dockedFilter.el.dom.firstChild.style.width = width; this.dockedFilter.el.dom.scrollLeft = target.scrollLeft; }, // Returns HTML ID of element containing filter div getFilterDivId: function(columnId) { return this.grid.id + '-filter-' + columnId; }, // Iterates over each column that has filter eachFilterColumn: function(func) { this.eachColumn( function(col, i) { if (col.xfilterField) { func.call(this, col, i); } }); }, // Iterates over each column in column config array eachColumn: function(func) { Ext.each(this.grid.columns, func, this); } });
-
13 Jul 2011 12:35 AM #20
Thanks zonereseau, this does indeed work!
The only problem left ist the height. The textfields are only about 10px height. Do you have any css definitions like in the original plugin?
Regards
EDIT:
Ok 2 more strange things:
1. if i add a Ext.PagingToolbar to the bottom bar, the filterrow has a normal/expected height. If i remove it, the filter row is 10px height. (http://images.devs-on.net/Image/F8Cr...c4-Bereich.png and http://images.devs-on.net/Image/ZXpM...xt-Bereich.png)
2. after removing a column by deselecting it in the Header ContextMenu the FilterRow is damaged (http://images.devs-on.net/Image/5nDt...7n-Bereich.png)
Similar Threads
-
Grid FilterRow
By Surinder singh in forum Ext 3.x: User Extensions and PluginsReplies: 5Last Post: 17 Aug 2011, 7:12 PM -
GridPanel with FilterRow and Locking
By taxidriver in forum Ext 3.x: Help & DiscussionReplies: 3Last Post: 7 Sep 2010, 4:16 AM -
ListView and filterRow
By btogkas in forum Ext 3.x: Help & DiscussionReplies: 0Last Post: 7 Sep 2010, 3:23 AM -
Add FilterRow to ListViews
By taxidriver in forum Ext 3.x: Help & DiscussionReplies: 2Last Post: 2 Sep 2010, 4:27 AM -
FilterRow in ListViews
By taxidriver in forum Ext 3.x: Help & DiscussionReplies: 0Last Post: 1 Sep 2010, 5:52 AM


Reply With Quote