ExtJS - Фильтрация сетки с полем поиска в заголовке столбца

StackOverflow https://stackoverflow.com//questions/22014855

Вопрос

В ExtJS есть множество опций для фильтрации сетки.В документации есть два хороших примера, на которые ссылаются в этот вопрос.

  1. Удаленная фильтрация
  2. Локальная фильтрация

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

Как этого можно достичь?

Это было полезно?

Решение

После довольно продолжительных исследований в скудной документации и благодаря замечательным вопросам и ответам в 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 возможны и работают так, как описано в документе для 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())
        }
    }
})
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top