使用Ext.ux.grid.FiltersFeature,我有远程过滤器,我正在尝试编写一个函数来以编程方式在网格列上应用日期过滤器(而不是单击列标题中的过滤器下拉菜单)。第一次运行该函数时,网格存储在没有过滤器的情况下重新加载。当我第二次运行该功能(以及之后每次)它完全正常工作时,商店会重新加载过滤器。以下是我所拥有的功能的要点:
// a filter object for testing
aFilter = {type: 'date', field: 'a_date_field', comparison: 'gt', value: '2012-03-08 00:00:00'}
var grid = Ext.create('Ext.grid.Panel', {
store: store,
features: [{
ftype: 'filters',
}],
columns[{
header: 'ID',
dataIndex: 'id',
itemId: 'id',
width: 40,
}, {
xtype: 'datecolumn',
header: 'Date',
dataIndex: 'a_date_field',
itemId: 'a_date_field',
width: 75,
format:'j-M-Y',
filterable: true
}],
listeners: {
'afterrender': function() {
// Need to create the filters as soon as the grid renders
// rather than waiting for the user to click on the header
grid.filters.createFilters();
}
},
bbar: [{
text: 'Do a filter',
handler: function() {
// get the filter that is attached to the grid
var gridFilter = grid.filters.getFilter(aFilter.field);
// have to do this to create a menu for this filter
gridFilter.init({dataIndex: aFilter.field, type: aFilter.type, active: true});
// if this column is a date filter column
if (gridFilter.type == 'date') {
var dateValue = Ext.Date.parse(aFilter.value, 'Y-m-d H:i:s');
if (filter.comparison == 'gt') {
gridFilter.setValue({after: dateValue});
} else {
gridFilter.setValue({before: dateValue});
}
}
}
}
});
我还发现,如果在运行该函数之前单击任何网格标题菜单,此函数将首次运行。
我一直试图找出对网格做了哪些更改,这使得过滤器在第一次尝试失败后工作,或者点击任何网格标题使其工作。但是我添加的任何东西似乎都没有解决它所以它会第一次运行。有没有人成功实现过这个?
答案 0 :(得分:9)
我有解决方法:
bbar: [{
text: 'Do a filter',
handler: function() {
var grid = this.up('grid');
var dateValue = Ext.Date.parse(aFilter.value, 'Y-m-d H:i:s');
var value = aFilter.comparison == 'gt' ? {after: dateValue} : {before: dateValue};
var gridFilter = grid.filters.getFilter(aFilter.field);
if (!gridFilter) {
gridFilter = grid.filters.addFilter({
active: true,
type: aFilter.type,
dataIndex: aFilter.dataIndex,
});
gridFilter.menu.show();
gridFilter.setValue(value);
gridFilter.menu.hide();
} else {
gridFilter.setActive(true);
}
Ext.Function.defer(function(){
gridFilter = grid.filters.getFilter(aFilter.field);
gridFilter.setValue(value);
}, 10);
}
}]
如您所见,我实际上应用过滤器2次。
答案 1 :(得分:6)
作为更新,我扩展了此功能并对其进行了修改以使用ExtJS 4.1.1
以下是动态设置网格过滤器的功能示例(无需用户点击菜单项)。之后,过滤的项目将在网格列标题菜单中对用户可见,就像他点击它们并手动设置它们一样。
“网格”参数是您想要过滤的FiltersFeature
网格。另一个参数是“过滤器”对象的数组(我将在下面显示一个示例),该函数只是将所有传递的“过滤器”对象应用于网格。
doGridFilter: function(grid, filters) {
// for each filter object in the array
Ext.each(filters, function(filter) {
var gridFilter = grid.filters.getFilter(filter.field);
gridFilter.setActive(true);
switch(filter.data.type) {
case 'date':
var dateValue = Ext.Date.parse(filter.data.value, 'm/d/Y'),
value;
switch (filter.data.comparison) {
case 'gt' :
value = {after: dateValue};
break;
case 'lt' :
value = {before: dateValue};
break;
case 'eq' :
value = {on: dateValue};
break;
}
gridFilter = log.filters.getFilter(filter.field);
gridFilter.setValue(value);
gridFilter.setActive(true);
break;
case 'numeric':
var value;
switch (filter.data.comparison) {
case 'gt' :
value = {gt: filter.data.value};
break;
case 'lt' :
value = {lt: filter.data.value};
break;
case 'eq' :
value = {eq: filter.data.value};
break;
}
gridFilter = log.filters.getFilter(filter.field);
gridFilter.setValue(value);
gridFilter.setActive(true);
break;
case 'list':
gridFilter = log.filters.getFilter(filter.field);
gridFilter.menu.setSelected(gridFilter.menu.selected, false);
gridFilter.menu.setSelected(filter.data.value.split(','), true);
break;
default :
gridFilter = log.filters.getFilter(filter.field);
gridFilter.setValue(filter.data.value);
break;
}
});
}
以下是“过滤器”对象数组的示例。
// an example of a "filters" argument
[{
field: 'some_list_column_data_index',
data: {
type: 'list',
value: 'item1,item2,item3,item4,item5,item6,item7'
}
}, {
field: 'some_date_column_data_index',
data: {
type: 'date',
comparison: 'gt',
value: '07/07/2007'
}
}]
有一点需要注意,在使用此功能之前,您需要手动“创建”过滤器。通常FiltersFeature
网格过滤器是在用户第一次点击其中一个时“创建”的,如果用户只想应用其中一个预定义过滤器,则可能不会发生这种情况。
通过在网格面板中包含此Afterrender侦听器,可以轻松处理。
listeners: {
// must create the filters after grid is rendered
afterrender: function(grid) {
grid.filters.createFilters();
}
}
答案 2 :(得分:3)
添加
filter: true
到这样的网格列描述:
me.columns = [
{header:"Name", dataIndex:"name", editor:"textfield", filter: true},
];
如果您想在第一次尝试后获得过滤器,则首先创建实例。
答案 3 :(得分:1)
这是值得研究的事情。似乎过滤器插件正在侦听menucreate
事件以初始化过滤器。我想知道菜单创建事件是否延迟到必要,因此过滤器不会被初始化?
/**
* @private Handle creation of the grid's header menu. Initializes the filters and listens
* for the menu being shown.
*/
onMenuCreate: function(headerCt, menu) {
var me = this;
me.createFilters(); //<------
menu.on('beforeshow', me.onMenuBeforeShow, me);
},
答案 4 :(得分:0)
你想应用网格过滤器还是store.filter()能力更适合你?在这种情况下,只需过滤商店,网格将显示过滤后的记录。
答案 5 :(得分:0)
我发现了另一种实现这个的方法。在渲染网格后,网格特征似乎仅绑定到网格。这意味着在渲染网格之前,过滤器的任何设置都不会生效。商店的初始加载似乎是在呈现网格之前启动的。
我通过使用不包含数据的内存代理创建商店来解决我的问题。
me.store = Ext.create('Ext.data.Store', {
model: 'SummaryData',
data: [],
proxy: {
type: 'memory',
reader: 'array'
},
remoteSort: true,
remoteFilter: true
});
然后在网格上设置afterrender
处理程序以查找正确的代理并启动商店的加载。
afterrender: function () {
var me = this;
me.store.setProxy({
type: 'ajax',
url : '/print_unallocated/change_site__data',
reader: {
type: 'json',
root: 'rows'
},
listeners: {
exception: function (proxy, response) {
Max.reportException(response);
}
}
});
me.filters.createFilters();
me.store.load();
},
答案 6 :(得分:0)
在源代码中,您可以看到与此相关的评论。
// Call getMenu() to ensure the menu is created, and so, also are the filters. We cannot call
// createFilters() withouth having a menu because it will cause in a recursion to applyState()
// that ends up to clear all the filter values. This is likely to happen when we reorder a column
// and then add a new filter before the menu is recreated.
me.view.headerCt.getMenu();
您可以在应用过滤器之前测试是否已创建菜单。如果没有,请自己动手。
if(!grid.getView().headerCt.menu){
grid.getView().headerCt.getMenu();
}