ExtJS - Фильтрация сетки с полем поиска в заголовке столбца
Вопрос
В ExtJS есть множество опций для фильтрации сетки.В документации есть два хороших примера, на которые ссылаются в этот вопрос.
Однако наличие фильтра, скрытого в выпадающем меню по умолчанию Ext.ux.grid.FiltersFeature
выглядит действительно неловко для меня.Хорошим эргономичным выбором было бы создать поля поиска в заголовках столбцов, как показано на @Ctacus в его вопрос.
Как этого можно достичь?
Решение
После довольно продолжительных исследований в скудной документации и благодаря замечательным вопросам и ответам в SO я придумал простой класс, который добавляет эту функциональность и допускает конфигурации.
Это выглядит примерно так:
Вы добавляете это поле в свою таблицу следующим образом:
Ext.define('Sandbox.view.OwnersGrid', {
extend: 'Ext.grid.Panel',
requires: ['Sandbox.view.SearchTrigger'],
alias: 'widget.ownersGrid',
store: 'Owners',
columns: [{
dataIndex: 'id',
width: 50,
text: 'ID'
}, {
dataIndex: 'name',
text: 'Name',
items:[{
xtype: 'searchtrigger',
autoSearch: true
}]
},
Следующий configs
возможны и работают так, как описано в документе для Ext.util.Filter
:
anyMatch
caseSensitive
exactMatch
operator
- Кроме того, вы можете использовать
autoSearch
.Если значение true, фильтр выполняет поиск по мере ввода, если значение false или не задано, необходимо нажать на значок поиска, чтобы применить фильтр.
Источник ExtJS 5/6:
Ext.define('Sandbox.view.SearchTrigger', {
extend: 'Ext.form.field.Text',
alias: 'widget.searchtrigger',
triggers:{
search: {
cls: 'x-form-search-trigger',
handler: function() {
this.setFilter(this.up().dataIndex, this.getValue())
}
},
clear: {
cls: 'x-form-clear-trigger',
handler: function() {
this.setValue('')
if(!this.autoSearch) this.setFilter(this.up().dataIndex, '')
}
}
},
setFilter: function(filterId, value){
var store = this.up('grid').getStore();
if(value){
store.removeFilter(filterId, false)
var filter = {id: filterId, property: filterId, value: value};
if(this.anyMatch) filter.anyMatch = this.anyMatch
if(this.caseSensitive) filter.caseSensitive = this.caseSensitive
if(this.exactMatch) filter.exactMatch = this.exactMatch
if(this.operator) filter.operator = this.operator
console.log(this.anyMatch, filter)
store.addFilter(filter)
} else {
store.filters.removeAtKey(filterId)
store.reload()
}
},
listeners: {
render: function(){
var me = this;
me.ownerCt.on('resize', function(){
me.setWidth(this.getEl().getWidth())
})
},
change: function() {
if(this.autoSearch) this.setFilter(this.up().dataIndex, this.getValue())
}
}
})
Для ExtJS 6.2.0, следующая ошибка и ее обходной путь имеет отношение к этому, иначе столбец не может быть flex
ред.
Источник ExtJS 4:
Ext.define('Sandbox.view.SearchTrigger', {
extend: 'Ext.form.field.Trigger',
alias: 'widget.searchtrigger',
triggerCls: 'x-form-clear-trigger',
trigger2Cls: 'x-form-search-trigger',
onTriggerClick: function() {
this.setValue('')
this.setFilter(this.up().dataIndex, '')
},
onTrigger2Click: function() {
this.setFilter(this.up().dataIndex, this.getValue())
},
setFilter: function(filterId, value){
var store = this.up('grid').getStore();
if(value){
store.removeFilter(filterId, false)
var filter = {id: filterId, property: filterId, value: value};
if(this.anyMatch) filter.anyMatch = this.anyMatch
if(this.caseSensitive) filter.caseSensitive = this.caseSensitive
if(this.exactMatch) filter.exactMatch = this.exactMatch
if(this.operator) filter.operator = this.operator
console.log(this.anyMatch, filter)
store.addFilter(filter)
} else {
store.filters.removeAtKey(filterId)
store.reload()
}
},
listeners: {
render: function(){
var me = this;
me.ownerCt.on('resize', function(){
me.setWidth(this.getEl().getWidth())
})
},
change: function() {
if(this.autoSearch) this.setFilter(this.up().dataIndex, this.getValue())
}
}
})