ExtJs-фильтр сетки с полем поиска в заголовке столбца

в ExtJs есть много вариантов фильтрации сетки. В документации есть два хороших примера, как указано в этот вопрос.

  1. удаленный фильтрации
  2. локальная фильтрация

однако, если фильтр скрыт в раскрывающемся меню по умолчанию Ext.ux.grid.FiltersFeature выглядит очень неудобно для меня. Хороший эргономичный выбор для создания полей поиска в заголовках столбцов, как @Ctacus показывает в его вопрос.

как этого можно добиться ?

1 ответов


после довольно много исследований через разреженную документацию, и благодаря большим вопросам и ответам в SO, я придумал простой класс, который добавляет эту функциональность и и позволяет конфигурации.

это выглядит так:

Search filter fields in column header

вы добавляете это поле в свою сетку следующим образом:

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 возможны и работают, как описано в doc для Ext.util.Filter:

  • anyMatch
  • caseSensitive
  • exactMatch
  • operator
  • additionnaly вы можете использовать autoSearch. Если true, фильтр выполняет поиск по мере ввода, если false или not set, нужно щелкнуть значок поиска, чтобы применить фильтр.

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,следующая ошибка и ее решение имеет отношение к этому, иначе столбец не может быть flexed.

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