Pregunta

En ExtJs, hay muchas opciones para filtrar una cuadrícula.Hay dos buenos ejemplos en la documentación, como se menciona en esta pregunta.

  1. Filtrado remoto
  2. Filtrado local

Sin embargo, tener el filtro oculto en el menú desplegable predeterminado de Ext.ux.grid.FiltersFeature Me parece realmente incómodo.Una buena opción ergonómica sería crear campos de búsqueda en los encabezados de las columnas, como muestra @Ctacus en su pregunta.

¿Cómo se puede lograr esto?

¿Fue útil?

Solución

Después de mucha investigación a través de la escasa documentación, y gracias a excelentes preguntas y respuestas en SO, se me ocurrió una clase simple que agrega esta funcionalidad y permite configuraciones.

Se parece a esto:

Search filter fields in column header

Agrega este campo en su cuadrícula de esta manera:

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

La siguiente configs son posibles y funcionan como se describe en el documento para Ext.util.Filter:

  • anyMatch
  • caseSensitive
  • exactMatch
  • operator
  • además puedes usar autoSearch.Si es verdadero, el filtro busca a medida que escribe; si es falso o no está configurado, hay que hacer clic en el icono de búsqueda para aplicar el filtro.

ExtJs 5/6 Fuente:

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

Para ExtJs 6.2.0, el siguiente error y su solución es relevante para esto; de lo contrario, la columna no se puede flexed.

ExtJs 4 Fuente:

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())
        }
    }
})
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top