Code:
Ext.define('Ext.ux.grid.FilterRow', {
extend:'Ext.util.Observable',
remoteFilter:true,
init: function(grid) {
this.grid = grid;
this.grid.filterRow = this;
this.grid.on('afterrender', this.applyTemplate, this, {single:true});
},
applyTemplate: function() {
// Setup events and apply the template
if(this.grid.lockedGrid) {
this.applyFilterEvents(this.grid.lockedGrid);
this.applyTemplateToColumns(this.grid.lockedGrid);
this.applyFilterEvents(this.grid.normalGrid);
this.applyTemplateToColumns(this.grid.normalGrid);
} else {
this.applyFilterEvents(this.grid);
this.applyTemplateToColumns(this.grid);
}
},
applyFilterEvents:function(grid) {
// Add events
if(!grid.gridFilterEvent) {
// when column width programmatically changed
grid.on("columnresize", this.resizeFilterField, this);
// Reset filter on some events
grid.on("staterestore", this.resetFilterRow, this);
grid.on("resize", this.resetFilterRow, this);
grid.on("move", this.resetFilterRow, this);
grid.on("columnmove", this.resetFilterRow, this);
grid.on("columnshow", this.resetFilterRow, this);
grid.on("columnhide", this.resetFilterRow, this);
// when the scroller bar scroll, need to move the filter row columns
if(grid.horizontalScroller) {
grid.horizontalScroller.on('bodyscroll', this.scrollFilterField, grid);
}
// Setup a variable to tell that the events where already bind
grid.gridFilterEvent = true;
}
},
applyTemplateToColumns:function(grid) {
var searchItems = [];
this.eachColumn(grid.columns, function(col) {
var filterDivId = this.getFilterDivId(col.id);
var width = col.getWidth()-2;
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({
grid:grid,
id:filterDivId,
hidden:col.hidden,
xtype:'component',
baseCls: "xfilter-row",
width:width,
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);
col.xfilterField.on("focus", this.onFieldFocus, this);
col.xfilterField.on("blur", this.onFieldBlur, this);
col.xfilterField.setWidth(width);
searchItems.push(col.xfilterField);
});
if(searchItems.length > 0) {
grid.addDocked(grid.dockedFilter = Ext.create('Ext.container.Container', {
id: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();
}
},
onFieldFocus:function(field) {
var pos = field.getPosition(true);
var grid = field.grid;
if(grid.horizontalScroller && grid.horizontalScroller.scrollEl && grid.horizontalScroller.scrollEl.dom) {
var scrollEl = grid.horizontalScroller.scrollEl;
var clientWidth = scrollEl.dom.clientWidth;
var scrollLeft = scrollEl.dom.scrollLeft;
if(pos[0] <= scrollLeft || pos[0] >= clientWidth) {
if(pos[0] < clientWidth) {
pos[0] = 0;
}
grid.horizontalScroller.setScrollLeft(pos[0]);
}
}
},
onFieldBlur:function(field) {
// Fix for the last field blur
var grid = field.grid;
var columns = grid.headerCt.getVisibleGridColumns();
if(columns[columns.length-1].xfilterField == field) {
this.onFieldFocus(columns[0].xfilterField);
}
},
getSearchValues: function() {
var values = {};
// Does it contain a locked grid
if(this.grid.lockedGrid) {
values = Ext.apply(this.getGridSearchValues(this.grid.lockedGrid), this.getGridSearchValues(this.grid.normalGrid));
} else {
values = this.getGridSearchValues(this.grid);
}
return values;
},
getGridSearchValues:function(grid) {
var values = {};
this.eachColumn(grid.columns, function(col) {
if(col.xfilterField && col.xfilterField.xtype != 'component') {
values[col.dataIndex] = col.xfilterField.getValue();
}
});
return values;
},
storeSearch: function() {
if(this.remoteFilter) {
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();
} else {
var values = this.getSearchValues();
this.grid.store.clearFilter();
for(key in values) {
if(values[key] != undefined && values[key] != "") {
this.grid.store.filter(key, values[key]);
}
}
}
},
clearSearchValues:function() {
// Does it contain a locked grid
if(this.grid.lockedGrid) {
this.clearGridSearchValues(this.grid.lockedGrid);
this.clearGridSearchValues(this.grid.normalGrid);
} else {
this.clearGridSearchValues(this.grid);
}
},
clearGridSearchValues:function(grid) {
this.eachColumn(grid.columns, function(col) {
if(col.xfilterField && col.xfilterField.xtype != 'component') {
col.xfilterField.setValue('');
}
});
},
clearSearch:function() {
this.clearSearchValues();
this.storeSearch();
},
resetFilterRow: function () {
if(this.grid.lockedGrid) {
this.removeDockedFilter(this.grid.lockedGrid);
this.removeDockedFilter(this.grid.normalGrid);
} else {
this.removeDockedFilter(this.grid);
}
this.applyTemplate();
},
removeDockedFilter:function(grid) {
grid.removeDocked(grid.id+'docked-filter', true);
delete grid.dockedFilter;
//This is because of the reconfigure
var dockedFilter = document.getElementById(grid.id+'docked-filter');
if (dockedFilter) {
dockedFilter.parentNode.removeChild(dockedFilter);
}
},
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.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) {
Ext.each(this.grid.columns, function(col, i) {
if (col.xfilterField) {
func.call(this, col, i);
}
}, this);
},
// Iterates over each column in column config array
eachColumn: function(columns, func) {
Ext.each(columns, func, this);
}
});