ExtJs - Filter a grid with a search field in the column header

前端 未结 1 1657
慢半拍i
慢半拍i 2020-12-01 08:54

In ExtJs, there are many options to filter a grid. There are two nice examples in the documentation, like referenced in this question.

  1. Remote filtering
相关标签:
1条回答
  • 2020-12-01 09:10

    After quite much research through the sparse documentation, and thanks to great questions and answers in SO, I came up with a simple class, that adds this functionality and and allows for configurations.

    It looks like this:

    Search filter fields in column header

    You add this field in your grid like this:

    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
        }]
    },
    

    The following configs are possible, and work like described in the doc for Ext.util.Filter:

    • anyMatch
    • caseSensitive
    • exactMatch
    • operator
    • additionnaly you can use autoSearch. If true, the filter searches as you type, if false or not set, one has to click on the search icon to apply the filter.

    ExtJs 5 / 6 Source:

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

    For ExtJs 6.2.0, the following bug and its workaround is relevant to this, else the column cannot be flexed.

    ExtJs 4 Source:

    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())
            }
        }
    })
    
    0 讨论(0)
提交回复
热议问题