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

1

9

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
  2. Local filtering

However, having the filter hidden in the default dropdown menu of Ext.ux.grid.FiltersFeature looks really awkward for me. A good ergonomic choice would to create search fields in the column headers, like @Ctacus shows in his question.

How can this be achieved ?

Tourane answered 25/2, 2014 at 12:54 Comment(0)
T
24

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())
        }
    }
})
Tourane answered 25/2, 2014 at 13:6 Comment(15)
I was able to implement your code in my ExtJS Grid. One of the problem is sometimes the user cannot switch between the searchTrigger fields in columns using mouse click. Also 'Tab' key works for switching between searchTriggers. Do you experience the same issue?Sane
I found that sometines, I cannot access the serach field with a mouse click, but I didn't look further, and I didn't recognize any pattern on when that problem occurs.Tourane
Ok. Thank you. I am trying to fix it. Sometimes on mouse click the 'focus' event is not fired at all and the search field is not accessible. Its random, sometimes it works and sometimes it doesnt. I will continue troubleshooting it, Let me know if you find something.Sane
possible to add combo field in this filter?Gloucestershire
@DharmeshHadiyal Sure you can filter a column with a combo box in it's header. Instead of extending the SearchTrigger form Ext.form.field.Trigger you would have to extend it from Ext.form.field.ComboBox and adapt the code a little.Tourane
if possible then please give small exampleGloucestershire
@DharmeshHadiyal Take the code above and adapt it for your needs. I cannot do your work in your place. Thanks for your understanding.Tourane
for those, who are using extjs5, triggerCls and trigger2Cls should be replaced with Ext.form.field.Text triggers, see here docs.sencha.com/extjs/5.1/5.1.0-apidocs/#!/api/…Elata
@Elata Thanks for this precision. I'll switch to ExtJs 5.0 soon.Tourane
While I was Implementing it in Extjs 5 ,TextField is not taking space in between the value (ex:- 'Form Field').If I paste the value It filters it but while typing it doesnot take the space. Any idea???Eyla
@yellen It needs some tweaks to work with 5.1. I did not yet migrate, so I cannot give the code yet.Tourane
For ExtJS 5.1: dev.sencha.com/ext/5.1.0/examples/kitchensink/#grid-filtering Not so intuitive, but it works and it's official.Dilator
Not Work for me. ExtJS 6.0.2. No errors, but no search fields are displayed.Demeter
Searching is working fine but resize of filter is not working.For Example if we resize Name column Filter is not resizing automatically.Is anyone having idea how to achieve this?Directed
Can someone reproduce code in Sencha Fiddle on 6.2.0?#46631502Kirven

© 2022 - 2024 — McMap. All rights reserved.