1. #1
    Sencha Premium Member d.zucconi's Avatar
    Join Date
    Jun 2008
    Location
    Piacenza (Italy)
    Posts
    78
    Vote Rating
    4
    d.zucconi is on a distinguished road

      0  

    Default Grid header filters

    Grid header filters


    This is a plugin that enables server-side filters for grid in columns headers. The plugin enables the new ColumnModel configuration option filter. This attribute value must be a valid Ext.form.Field component configuration or an array of filter configuration objects. The field becomes the filter field used into your column header.
    The filter will affect Store request parameters, adding a new parameter to Store.baseParams.Parameter name can be specified in filter configuration using the filterName option. If not specified, the name will be equal to ColumnModel dataIndex.

    An ExtJS 4 version of this plugin is developed and documented on this thread:
    http://www.sencha.com/forum/showthre...276#post660276

    Versions:

    1.0.0 - 12/1/09
    • Some bug fixes
    • Plugin now enables some new methods on grid such as "getHeaderFilter(name)" or
      "getHeaderFilterField(name)"
    • Changed filters rendering
    • Added "filterEncoder" and "filterDecoder" cfg attributes. These parameters allow to enable functions to encode or decode filter value before and after store reload or grid status update
    1.0.2 - 14/04/09
    • Some bug fixes (such as access to load parameters for grid store)
    • Fixed text selection support for TextField filters on Mozilla Firefox (-moz-user-select CSS property)
    • Filters header panel background color now is transparent (not white)
    • Added support for filter highlighting when at least one filter is active (useful if you have an active filter on the last column that could not be visibile without horizontal scroll)
    1.0.5 - 13/07/09 (tested with Ext 3.0)
    • Added stateful configuration parameter to select if filters values should be saved with Ext.state.Provider. This parameter is true by default. Ex: new Ext.ux.grid.GridHeaderFilters({stateful: false}).
    • Fixed column auto-show if a filter has empty value
    • Changed and simplified filters rendering (see onRender())
    • Minor fixes and code cleaning (thanks to dzj)
    1.0.6 - 30/07/09 (tested with Ext 3.0 - 3.0.1 - 3.0.2)
    • The plugin now enables for the grid the new method applyHeaderFilters.
    • Added applyMode configuration parameter to select if filters should be applied every time filter field value changes or only if user select to apply filters. If the value of this parameter is set to 'auto', filters are applied when each field value is changed (default, as previous versions). If the value is set to 'enter', the filters are applied only when the users hits the "ENTER" key on the filter field or when the grid method "applyHeaderFilters" is called (ex. add a button on your grid tbar and use this method as click handler). This would help when you need to change more than one filter before reloading the grid content.
    1.0.9 - 29/10/09 (tested with Ext 3.0.0 up to 3.0.3)
    • The plugin now signals render event when filters rendering is done. This could be useful to load store only when filters are already initialized.
    • Added filters configuration parameter to initialize filters values at configuration time. These values will override values loaded from state (if filters are stateful)
    • Fixed bug for store reload on column move.
    1.0.12 - 06/08/10 (tested with Ext 3.1.2)
    • Added applyFilterEvent filter configuration parameter. Allows developers to choose the field-event that applies filter value.
    • Added ensureFilteredVisible plugin configuration parameter.
    • Fixed some bugs. Thanks to ob1, dolittle and dzj.
    2.0.3 - 23/12/10 (tested with Ext 3.3.1)
    • The plugin now supports more than one filter for each column. The value for the filter column model attribute can be an array of field configurations (with specific filterName for each field)
    • Changed highlight filter mode and introduced highlightCls configuration parameter
    • EXPERIMENTAL support for grid reconfiguration: the plugin now intercepts grid reconfigure event to reconfigure and render filters.
    • Code rewritten, simplified filters render, compatible with Ext 3.3.0
    2.0.5 - 25/02/11 (tested with Ext 3.3.1)
    • Filter values specified into filters config parameter are removed if doesn't match with any available filter field
    • Fixed destroy memory leak caused by typo (thanks to qwikso)
    2.0.6 - 03/03/11
    • Fixed disabled filter field support (thanks to dolittle)

    Usage:
    1. Create a new instance of Ext.ux.grid.GridHeaderFilters and put it into your grid plugins list
    2. Define filter configuration with filter configuration attribute in ColumnModel configuration
    Configuration example:

    Code:
    var gridCfg = {
     xtype: "grid",
      store: articleStore,
     plugins: [new Ext.ux.grid.GridHeaderFilters()],
     cm: new Ext.grid.ColumnModel([{
        header : "Code",
        width: 120,
        sortable: true,
        dataIndex: "CODE",
         filter: {xtype:"textfield", filterName:"CODE"}
      },{
        id: "ART_DESC",
        header: "Description",
        width: 300,
        sortable: true,
        dataIndex: "ART_DESC",
         filter: [{xtype:"textfield"},{xtype:"textfield"}]
      },{
        id: "TYPE_DESC",
        header: "Type",
        width: 100,
        sortable: false,
        dataIndex: "TYPE_DESC",
       filter: {
          xtype: "combo",
          mode: "local",
          store: [["A","Type1"],["B","Type2"]],
          triggerAction: "all"
       }
    
    }]) }
    Source code (version 2.0.6):
    Code:
    
    Ext.namespace("Ext.ux.grid");
    
    /**
     * @class Ext.ux.grid.GridHeaderFilters
     * @extends Ext.util.Observable
     * 
     * Plugin that enables filters in columns headers.
     * 
     * To add a grid header filter, put the "filter" attribute in column configuration of the grid column model.
     * This attribute is the configuration of the Ext.form.Field to use as filter in the header or an array of fields configurations.<br>
     * <br>
     * The filter configuration object can include some special attributes to manage filter configuration:
     * <ul>
     * <li><code>filterName</code>: to specify the name of the filter and the corresponding HTTP parameter used to send filter value to server. 
     * If not specified column "dataIndex" attribute will be used, if more than one filter is configured for the same column, the filterName will be the "dataIndex" followed by filter index (if index &gt; 0)</li>
     * <li><code>value</code>: to specify default value for filter. If no value is provided for filter (in <code>filters</code> plugin configuration parameter or from loaded status), 
     * this value will be used as default filter value</li>
     * <li><code>filterEncoder</code>: a function used to convert filter value returned by filter field "getValue" method to a string. Useful if the filter field getValue() method
     * returns an object that is not a string</li>
     * <li><code>filterDecoder</code>: a function used to convert a string to a valid filter field value. Useful if the filter field setValue(obj) method
     *                         needs an object that is not a string</li>
     * <li><code>applyFilterEvent</code></li>: a string that specifies the event that starts filter application for this filter field. If not specified, the "applyMode" is used. (since 1.0.10)</li>
     *    </ul>
     * <br>
     * Filter fields are rendered in the header cells within an <code>Ext.Panel</code> with <code>layout='form'</code>.<br>
     * For each filter you can specify <code>fieldLabel</code> or other values supported by this layout type.<br>
     * You can also override panel configuration using <code>containerConfig</code> attribute.<br>
     * <br>
     * This plugin enables some new grid methods:
     * <ul>
     * <li>getHeaderFilter(name)</li>
     * <li>getHeaderFilterField(name)</li> 
     * <li>setHeaderFilter(name, value)</li> 
     * <li>setHeaderFilters(object, [bReset], [bReload])</li>
     * <li>resetHeaderFilters([bReload])</li>
     * <li>applyHeaderFilters([bReload])</li>
     * </ul>
     * The "name" is the filterName (see filterName in each filter configuration)
     * 
     * @author Damiano Zucconi - http://www.isipc.it
     * @version 2.0.6 - 03/03/2011
     */
    Ext.ux.grid.GridHeaderFilters = function(cfg){if(cfg) Ext.apply(this, cfg);};
        
    Ext.extend(Ext.ux.grid.GridHeaderFilters, Ext.util.Observable, 
    {
        /**
         * @cfg {Number} fieldHeight
         * Height for each filter field used by <code>autoHeight</code>.
         */
        fieldHeight: 22,
        
        /**
         * @cfg {Number} padding
         * Padding for filter fields. Default: 2
         */
        fieldPadding: 1,
        
        /**
         * @cfg {Boolean} highlightOnFilter
         * Enable grid header highlight if active filters 
         */
        highlightOnFilter: true,
        
        /**
         * @cfg {String} highlightColor
         * Color for highlighted grid header
         */
        highlightColor: 'yellow',
        
        /**
         * @cfg {String} highlightCls
         * Class to apply to filter header when filters are highlighted. If specified overrides highlightColor.
         * See <code>highlightOnFilter</code>. 
         */
        highlightCls: null,
        
        /**
         * @cfg {Boolean} stateful
         * Enable or disable filters save and restore through enabled Ext.state.Provider
         */
        stateful: true,
        
        /**
         * @cfg {String} applyMode
         * Sets how filters are applied. If equals to "auto" (default) the filter is applyed when filter field value changes (change, select, ENTER).
         * If set to "enter" the filters are applied only when user push "ENTER" on filter field.<br> 
         * See also <code>applyFilterEvent</code> in columnmodel filter configuration: if this option is specified in
         * filter configuration, <code>applyMode</code> value will be ignored and filter will be applied on specified event.
         * @since Ext.ux.grid.GridHeaderFilters 1.0.6
         */
        applyMode: "auto",
        
        /**
         * @cfg {Object} filters
         * Initial values for filters (mapped with filters names). If this object is defined,
         * its attributes values overrides the corresponding filter values loaded from grid status or <code>value</code> specified in column model filter configuration.<br>
         * Values specified into column model configuration (filter <code>value</code> attribute) are ignored if this object is specified.<br>
         * See <code>filtersInitMode</code> to understand how these values are mixed with values loaded from grid status.
         * @since Ext.ux.grid.GridHeaderFilters 1.0.9
         */
        filters: null,
        
        /**
         * @cfg {String} filtersInitMode
         * If <code>filters</code> config value is specified, this parameter defines how these values are used:
         * <ul>
         * <li><code>replace</code>: these values replace all values loaded from grid status (status is completely ignored)</li>
         * <li><code>merge</code>: these values overrides values loaded from status with the same name. Other status values are keeped and used to init filters.</li>
         * </ul>
         * This parameter doesn't affect how filter <code>value</code> attribute is managed: it will be always ignored if <code>filters</code> object is specified.<br>
         * Default = 'replace'
         */
        filtersInitMode: 'replace',
        
        /**
         * @cfg {Boolean} ensureFilteredVisible
         * If true, forces hidden columns to be made visible if relative filter is set. Default = true.
         */
        ensureFilteredVisible: true,
        
        cfgFilterInit: false,
        
        /**
         * @cfg {Object} containerConfig
         * Base configuration for filters container of each column. With this attribute you can override filters <code>Ext.Container</code> configuration.
         */
        containerConfig: null,
        
        /**
         * @cfg {Number} labelWidth
         * Label width for filter containers Form layout. Default = 50.
         */
        labelWidth: 50,
        
        fcc: null,
        
        filterFields: null,
        
        filterContainers: null,
        
        filterContainerCls: 'x-ghf-filter-container',
        
        init:function(grid) 
        {
            this.grid = grid;
            
            var gv = this.grid.getView();
            gv.updateHeaders = gv.updateHeaders.createSequence(function(){
                this.renderFilters.call(this);
            },this).createInterceptor(function(){
                this.destroyFilters.call(this);
                return true;
            },this);
            this.grid.on({
                scope: this,
                render: this.onRender,
                resize: this.onResize,
                columnresize: this.onColResize,
                reconfigure: this.onReconfigure,
                beforedestroy: this.destroyFilters
            });
            //this.grid.on("columnmove", this.renderFilters, this);
            if(this.stateful)
            {
                this.grid.on("beforestatesave", this.saveFilters, this);
                this.grid.on("beforestaterestore", this.loadFilters, this);
            }
            
            //Column hide event managed
            this.grid.getColumnModel().on("hiddenchange", this.onColHidden, this);
            
            this.grid.addEvents(
            /**
          * @event filterupdate
          * <b>Event enabled on the GridPanel</b>: fired when a filter is updated
          * @param {String} name Filter name
          * @param {Object} value Filter value
          * @param {Ext.form.Field} el Filter field
          */    
            'filterupdate');
            
            this.addEvents(
                /**
              * @event render
              * Fired when filters render on grid header is completed
              * @param {Ext.ux.grid.GridHeaderFilters} this
              */    
                {'render': true}
            );
            
            //Must ignore filter config value ?
            this.cfgFilterInit = Ext.isDefined(this.filters) && this.filters !== null;
            if(!this.filters)
                this.filters = {};
            
            //Configuring filters
            this.configure(this.grid.getColumnModel());
                
            Ext.ux.grid.GridHeaderFilters.superclass.constructor.call(this);
            
            if(this.stateful)
            {
                if(!Ext.isArray(this.grid.stateEvents))
                    this.grid.stateEvents = [];
                this.grid.stateEvents.push('filterupdate');
            }
            
            //Enable new grid methods
            Ext.apply(this.grid, {
                headerFilters: this,
                getHeaderFilter: function(sName){
                    if(!this.headerFilters)
                        return null;
                    return this.headerFilters.filters[sName];    
                },
                setHeaderFilter: function(sName, sValue){
                    if(!this.headerFilters)
                        return;
                    var fd = {};
                    fd[sName] = sValue;
                    this.setHeaderFilters(fd);
                },
                setHeaderFilters: function(obj, bReset, bReload)
                {
                    if(!this.headerFilters)
                        return;
                    if(bReset)
                        this.resetHeaderFilters(false);
                    if(arguments.length < 3)
                        var bReload = true;
                    var bOne = false;
                    for(var fn in obj)
                    {
                        if(this.headerFilters.filterFields[fn])
                        {
                            var el = this.headerFilters.filterFields[fn];
                            this.headerFilters.setFieldValue(el,obj[fn]);
                            this.headerFilters.applyFilter(el, false);
                            bOne = true;
                        }
                    }
                    if(bOne && bReload)
                        this.headerFilters.storeReload();
                },
                getHeaderFilterField: function(fn)
                {
                    if(!this.headerFilters)
                        return;
                    if(this.headerFilters.filterFields[fn])
                        return this.headerFilters.filterFields[fn];
                    else
                        return null;
                },
                resetHeaderFilters: function(bReload)
                {
                    if(!this.headerFilters)
                        return;
                    if(arguments.length == 0)
                        var bReload = true; 
                    for(var fn in this.headerFilters.filterFields)
                    {
                        var el = this.headerFilters.filterFields[fn];
                        if(Ext.isFunction(el.clearValue)) 
                        {
                            el.clearValue();
                        } 
                        else 
                        {
                            this.headerFilters.setFieldValue(el, '');
                        }
                        this.headerFilters.applyFilter(el, false);
                    }
                    if(bReload)
                        this.headerFilters.storeReload();
                },
                applyHeaderFilters: function(bReload)
                {
                    if(arguments.length == 0)
                        var bReload = true;
                    this.headerFilters.applyFilters(bReload);
                }
            });
            
        },
        
        /**
         * @private
         * Configures filters and containers starting from grid ColumnModel
         * @param {Ext.grid.ColumnModel} cm The column model to use
         */
        configure: function(cm)
        {
            /*Filters config*/
            var filteredColumns = cm.getColumnsBy(function(cc){
                if(Ext.isObject(cc.filter) || Ext.isArray(cc.filter))
                    return true;
                else
                    return false;
            });
            
            /*Building filters containers configs*/
            this.fcc = {};
            for (var i = 0; i < filteredColumns.length; i++) 
            {
                var co = filteredColumns[i];
                var fca = co.filter;
                if(!Ext.isArray(fca))
                    fca = [fca];
                for(var ci = 0; ci < fca.length; ci++)
                {
                    var fc = Ext.apply({
                        filterName: ci > 0 ? co.dataIndex+ci : co.dataIndex
                    },fca[ci]);
                    Ext.apply(fc, {
                        columnId: co.id,
                        dataIndex: co.dataIndex,
                        hideLabel: Ext.isEmpty(fc.fieldLabel),
                        anchor: '100%'
                    });
                    
                    if(!this.cfgFilterInit && !Ext.isEmpty(fc.value))
                    {
                        this.filters[fc.filterName] = Ext.isFunction(fc.filterEncoder) ? fc.filterEncoder.call(this, fc.value) : fc.value;
                    }
                    delete fc.value;
                    
                    /*
                     * Se la configurazione del field di filtro specifica l'attributo applyFilterEvent, il filtro verrà applicato
                     * in corrispondenza di quest'evento specifico
                     */
                    if(fc.applyFilterEvent)
                    {
                        fc.listeners = {scope: this};
                        fc.listeners[fc.applyFilterEvent] = function(field){this.applyFilter(field);};
                        delete fc.applyFilterEvent;
                    }
                    else
                    {
                        //applyMode: auto o enter
                        if(this.applyMode === 'auto' || this.applyMode === 'change' || Ext.isEmpty(this.applyMode))
                        {
                            //Legacy mode and deprecated. Use applyMode = "enter" or applyFilterEvent
                            fc.listeners = 
                            {
                                change: function(field)
                                {
                                    var t = field.getXType();
                                    if(t=='combo' || t=='datefield'){ //avoid refresh twice for combo select 
                                    return;
                                    }else{
                                    this.applyFilter(field);
                                    }
                                },
                                specialkey: function(el,ev)
                                {
                                    ev.stopPropagation();
                                    if(ev.getKey() == ev.ENTER) 
                                        el.el.dom.blur();
                                },
                                select: function(field){this.applyFilter(field);},
                                scope: this    
                            };
                        }
                        else if(this.applyMode === 'enter')
                        {
                            fc.listeners = 
                            {
                                specialkey: function(el,ev)
                                {
                                    ev.stopPropagation();
                                    if(ev.getKey() == ev.ENTER) 
                                    {
                                        this.applyFilters();
                                    }
                                },
                                scope: this
                            };
                        }
                    }
                    
                    //Looking for filter column index
                    var containerCfg = this.fcc[fc.columnId];
                    if(!containerCfg)
                    {
                        containerCfg = {
                            cls: this.filterContainerCls,
                            border: false,
                            bodyBorder: false,
                            /*layout: 'vbox',
                            layoutConfig: {align: 'stretch', padding: this.padding},*/
                            labelSeparator: '', 
                            labelWidth: this.labelWidth,
                            layout: 'form',
                            style: {},
                            items: []
                        };
                        if(this.containerConfig)
                            Ext.apply(containerCfg, this.containerConfig);
                        this.fcc[fc.columnId] = containerCfg;
                    }
                    containerCfg.items.push(fc);
                }
            }
        },
        
        renderFilterContainer: function(columnId, fcc)
        {
            if(!this.filterContainers)
                this.filterContainers = {};
            //Associated column index
            var ci = this.grid.getColumnModel().getIndexById(columnId);
            //Header TD
            var td = this.grid.getView().getHeaderCell(ci);
            td = Ext.get(td);
            //Patch for field text selection on Mozilla
            if(Ext.isGecko)
                td.dom.style.MozUserSelect = "text";
            td.dom.style.verticalAlign = 'top';
            //Render filter container
            fcc.width = td.getWidth() - 3;
            var fc = new Ext.Container(fcc);
            fc.render(td);
            //Container cache
            this.filterContainers[columnId] = fc;
            //Fields cache    
            var height = 0;
            if(!this.filterFields)
                this.filterFields = {};
            var fields = fc.findBy(function(cmp){return !Ext.isEmpty(cmp.filterName);});
            if(!Ext.isEmpty(fields))
            {
                for(var i=0;i<fields.length;i++)
                {
                    var filterName = fields[i].filterName;
                    /*if(this.filterFields[filterName])
                    {
                        //Ext.destroy(this.filterFields[filterName])
                        delete this.filterFields[filterName];
                    }*/
                    this.filterFields[filterName] = fields[i];
                    height += fields[i].getHeight();
                }
            }
            
            return fc;
        },
        
        renderFilters: function()
        {
            if(!this.fcc)
                return;
            for(var cid in this.fcc)
            {
                this.renderFilterContainer(cid, this.fcc[cid]);
            }
            this.setFilters(this.filters);
            this.highlightFilters(this.isFiltered());
        },
        
        onRender: function()
        {
            this.renderFilters();
            if(this.isFiltered())
            {
                this.applyFilters(false);
            }
            this.fireEvent("render", this);
        },
        
        getFilterField: function(filterName)
        {
            return this.filterFields ? this.filterFields[filterName] : null;
        },
        
        /**
         * Sets filter values by values specified into fo.
         * @param {Object} fo Object with attributes filterName = value
         * @param {Boolean} clear If current values must be cleared. Default = false
         */
        setFilters: function(fo,clear)
        {
            this.filters = fo;
            
            if(this.filters && this.filterFields)
            {
                //Delete filters that doesn't match with any field
                for(var fn in this.filters)
                {
                    if(!this.filterFields[fn])
                        delete this.filters[fn];
                }
                
                for(var fn in this.filterFields)
                {
                    var field = this.filterFields[fn];
                    var value = this.filters[field.filterName];
                    if(Ext.isEmpty(value))
                    {
                        if(clear)
                            this.setFieldValue(field, '');
                    }
                    else
                        this.setFieldValue(field, value);
                }
            }
        },
        
        onColResize: function(index, iWidth){
            if(!this.filterContainers)
                return;
            var colId = this.grid.getColumnModel().getColumnId(index);
            var cnt = this.filterContainers[colId];
            if(cnt)
            {
                if(isNaN(iWidth))
                    iWidth = 0;
                var filterW = (iWidth < 3) ? 0 : (iWidth - 3);
                cnt.setWidth(filterW);
                //Thanks to ob1
                cnt.doLayout(false,true);
            }
        },
        
        /**
         * @private
         * Resize filters containers on grid resize
         * Thanks to dolittle
         */
        onResize: function() 
        {
            var n = this.grid.getColumnModel().getColumnCount();
            for(var i=0; i<n; i++) {
                var td = this.grid.getView().getHeaderCell(i);
                td = Ext.get(td);
                this.onColResize(i, td.getWidth());
            }
        },
        
        onColHidden: function(cm, index, bHidden){
            if(bHidden)
                return;
            var cw = this.grid.getColumnModel().getColumnWidth(index);
            this.onColResize(index, cw);
        },
        
        onReconfigure: function(grid, store, cm)
        {
            this.destroyFilters();
            this.configure(cm);
            this.renderFilters();
        },
        
        saveFilters: function(grid, status)
        {
            var vals = {};
            for(var name in this.filters)
            {
                vals[name] = this.filters[name];
            }
            status["gridHeaderFilters"] = vals;
            return true;
        },
       
        loadFilters: function(grid, status)
        {
            var vals = status.gridHeaderFilters;
            if(vals)
            {
                if(this.cfgFilterInit)
                {                    
                    if(this.filtersInitMode === 'merge')
                        Ext.apply(vals,this.filters);
                }
                else
                    this.filters = vals;
            }
        },
        
        isFiltered: function()
        {
            for(var k in this.filters)
            {
                if(/*this.filterFields && this.filterFields[k] && */!Ext.isEmpty(this.filters[k]))
                    return true;
            }
            return false;
        },
        
        highlightFilters: function(enable)
        {
            if(!this.highlightOnFilter)
                return;
            if(!this.filterContainers)
                return;
            if(!this.grid.getView().mainHd)
                return;
                
            var tr = this.grid.getView().mainHd.child('.x-grid3-hd-row');
            if(!Ext.isEmpty(this.highlightCls))
            {
                if(enable)
                    tr.addClass(this.highlightCls);
                else
                    tr.removeClass(this.highlightCls);
            }
            else
            {
                tr.setStyle('background-color',enable ? this.highlightColor : '');
            }
            /*for(var i=0; i < this.grid.getColumnModel().getColumnCount(); i++) 
            {
                var hc = Ext.get(this.grid.getView().getHeaderCell(i));
                if(!Ext.isEmpty(this.highlightCls))
                {
                    if(enable)
                        hc.addClass(this.highlightCls);
                    else
                        hc.removeClass(this.highlightCls);
                }
                else
                {
                    hc.setStyle('background-color',enable ? this.highlightColor : 'transparent');
                }
            }*/
            /*var color = enable ? this.highlightColor : 'transparent';
            for(var fn in this.filterContainers)
            {
                var fc = this.filterContainers[fn];
                if(fc.rendered)
                {
                    if(!Ext.isEmpty(this.highlightCls))
                    {
                        if(enable)
                            fc.getEl().addClass(this.highlightCls);
                        else
                            fc.getEl().removeClass(this.highlightCls);
                    }
                    else
                        fc.getEl().setStyle('backgroundColor',color);
                }
            }*/
        },
        
        getFieldValue: function(eField)
        {
            if(Ext.isFunction(eField.filterEncoder))
                return eField.filterEncoder.call(eField, eField.getValue());
            else
                return eField.getValue();
        },
        
        setFieldValue: function(eField, value)
        {
            if(Ext.isFunction(eField.filterDecoder))
                value = eField.filterDecoder.call(eField, value);
            eField.setValue(value);
        },
        
        applyFilter: function(el, bLoad)
        {
            if(arguments.length < 2)
                bLoad = true;
            if(!el)
                return;
                
            if(!el.isValid())
                return;
                
            if(el.disabled && !Ext.isDefined(this.grid.store.baseParams[el.filterName]))
                return;
            
            var sValue = this.getFieldValue(el);
            
            if(el.disabled || Ext.isEmpty(sValue))
            {
                delete this.grid.store.baseParams[el.filterName];
                delete this.filters[el.filterName];
            }
            else    
            {
                this.grid.store.baseParams[el.filterName] = sValue;
                this.filters[el.filterName] = sValue;
                
                if(this.ensureFilteredVisible)
                {
                    //Controllo che la colonna del filtro applicato sia visibile
                    var ci = this.grid.getColumnModel().getIndexById(el.columnId);
                    if((ci >= 0) && (this.grid.getColumnModel().isHidden(ci)))
                            this.grid.getColumnModel().setHidden(ci, false);
                }
            }
            
            //Evidenza filtri se almeno uno attivo
            this.highlightFilters(this.isFiltered());
            
            this.grid.fireEvent("filterupdate",el.filterName,sValue,el);
            
            if(bLoad)
                this.storeReload();
        },
        
        applyFilters: function(bLoad)
        {
            if(arguments.length < 1)
                bLoad = true;
            for(var fn in this.filterFields)
            {
                this.applyFilter(this.filterFields[fn], false);
            }
            if(bLoad)
                this.storeReload();
        },
        
        storeReload: function()
        {
            if(!this.grid.store.lastOptions)
                return;
            var slp = {start: 0};
            if(this.grid.store.lastOptions.params && this.grid.store.lastOptions.params.limit)
                slp.limit = this.grid.store.lastOptions.params.limit;
            this.grid.store.load({params: slp});
        },
        
        getFilterContainer: function(columnId)
        {
            return this.filterContainers ? this.filterContainers[columnId] : null; 
        },
        
        destroyFilters: function()
        {
            if(this.filterFields)
            {
                for(var ff in this.filterFields)
                {
                    Ext.destroy(this.filterFields[ff]);
                    delete this.filterFields[ff];
                }
            }
            
            if(this.filterContainers)
            {
                for(var ff in this.filterContainers)
                {
                    Ext.destroy(this.filterContainers[ff]);
                    delete this.filterContainers[ff];
                }
            }
            
        }
    });
    
    Attached Images
    Last edited by d.zucconi; 14 Oct 2011 at 7:57 AM. Reason: New thread for ExtJS 4 versions

  2. #2
    Ext User
    Join Date
    Jul 2007
    Location
    Florida
    Posts
    9,996
    Vote Rating
    5
    mjlecomte will become famous soon enough mjlecomte will become famous soon enough

      0  

    Default


    Wow, nice first post!?

  3. #3
    Ext JS Premium Member
    Join Date
    May 2007
    Posts
    64
    Vote Rating
    0
    MeDavid is on a distinguished road

      0  

    Default


    Looking nice. Contrary to other filter extensions you see the filter values at all times. Looking forward to some date from/to support

  4. #4
    Sencha Premium Member d.zucconi's Avatar
    Join Date
    Jun 2008
    Location
    Piacenza (Italy)
    Posts
    78
    Vote Rating
    4
    d.zucconi is on a distinguished road

      0  

    Default


    Quote Originally Posted by MeDavid View Post
    Looking forward to some date from/to support
    Well, I know... the "period" filter is a need for me too.
    To support this kind of filter I'm thinking to develop (in the future ) a simple widget that groups 2 DateField. The getValue() method of this widget would return an object (or the equivalent JSON string) with 2 attributes (ex. {begin: "20080720", end: "20080820"} or {begin: "", end: "20080820"}). Then you can add this widget into your header filters.

    I've already developed a similar widget to support "checkboxes filter" (see the attachment). This is only a simple (and, sorry, undocumented) example, but it works fine in my use-cases.
    Attached Files

  5. #5
    Ext User
    Join Date
    Jul 2008
    Posts
    4
    Vote Rating
    0
    Jets is on a distinguished road

      0  

    Default


    Nice!But have some bugs,when the cols hidden,you need to resize the ColumnModel.My English is not good,Sorry

  6. #6
    Sencha User
    Join Date
    Dec 2007
    Posts
    96
    Vote Rating
    0
    nanich is on a distinguished road

      0  

    Default need to show the filter field above the header label

    need to show the filter field above the header label


    hi,
    Thank you very much for this great plugin. As per my requirement i need to show the filter field up above the header label instead of downside that is there in the plugin that you've provided. I tried to do this

    Ext.get(headerDiv).createChild({id: "col-"+colCfg.id+"-filter-div", tag: "div"},Ext.get(headerDiv).dom.childNodes[0])

    When i did this, the filter fields are getting rendered as per my requirement. But the problems that i've got are as follows
    1. I could not able to see the header menu's icon which will come beside the header when we mouseover on it.
    2. When i try to move the column by drag & drop of column label, I could not able to see the header label in the flyout that will come along with the mouse.

    Please help in solving this problem. Thanks in advance.

  7. #7
    Ext User
    Join Date
    Feb 2009
    Posts
    5
    Vote Rating
    0
    ExtMike is on a distinguished road

      0  

    Default Example HTML

    Example HTML


    Hello,

    I wanted to test the GridHeaderFilters example (on Ext 2.2.1) and got stuck (I'm a beginner...). Can you please provide a ready-to-run example? I'm getting the error "sp is undefined" in ext-base.js

    Thanks!

  8. #8
    Sencha Premium Member d.zucconi's Avatar
    Join Date
    Jun 2008
    Location
    Piacenza (Italy)
    Posts
    78
    Vote Rating
    4
    d.zucconi is on a distinguished road

      0  

    Default


    Hi,

    I've updated code version on the first page of this post (1.0.0 12/1/09).
    I've removed the zip attachment and reported plugin code directly in the message.
    This is the latest version of my plugin and is the same version I'm currently using in my webapps.
    About your error is hard to say for me what could be the cause...
    A valid usage example is the grid code reported in the "Configuration example" on the first page... However you could post your code to check if I can help you directly with your problem

  9. #9
    Sencha - Community Support Team jsakalos's Avatar
    Join Date
    Apr 2007
    Location
    Slovakia
    Posts
    27,133
    Vote Rating
    322
    jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future

      0  

    Default


    Have you ever seen this? http://extjs.com/forum/showthread.php?p=33434 ?

    Could you please post link to a demo?

  10. #10
    Sencha Premium Member d.zucconi's Avatar
    Join Date
    Jun 2008
    Location
    Piacenza (Italy)
    Posts
    78
    Vote Rating
    4
    d.zucconi is on a distinguished road

      0  

    Default


    Quote Originally Posted by jsakalos View Post
    Could you please post link to a demo?
    Sorry, but at the moment I don't have an online example. I'll try to publish something ASAP.

film izle

hd film izle

film sitesi

takipci kazanma sitesi

takipci kazanma sitesi

güzel olan herşey

takipci alma sitesi

komik eğlenceli videolar