Search code examples
extjsfilterextjs7

ExtJS 7 - Column filter issue with locked column


I encountered this bug where the column filter is incorrect if the grid has a locked column

Here's the fiddle: sencha fillde

Steps to reproduce: (Do not apply any filter)

  1. Open the "Email" column menu
  2. Open "Name" column menu (this is the locked column)
  3. Open "Phone" column menu (notice that the filter menu is incorrect, it is showing the filter for "Email" column).

For grid that has no 'locked' columns the filter menu is working fine, thanks for anyone who can help!


Solution

  • Okay, this one was a bit tricky. It turns out that for a locked grid, the Ext.grid.filters.Filters:onMenuCreate gets hit twice... one for each side of the grid's menu that shows. The problem is that in the onMenuCreate, the framework doesn't account for the 2 menus. It only cares about the last menu that gets created and destroys the previous menu's listeners. In onMenuBeforeShow, the framework does account for each side of the grid, so I extended this idea into an override. I would encourage you to create a Sencha Support ticket for this, and if you don't have access, let me know, so I can submit one. Fiddle here.

    Ext.override(Ext.grid.filters.Filters, {
        onMenuCreate: function (headerCt, menu) {
            var me = this;
    
            // TODO: OLD BAD CODE... this would destroy the first menu's listeners
            // if (me.headerMenuListeners) {
            //     Ext.destroy(me.headerMenuListeners);
            //     me.headerMenuListeners = null;
            // }
    
            // me.headerMenuListeners = menu.on({
            //     beforeshow: me.onMenuBeforeShow,
            //     destroyable: true,
            //     scope: me
            // });
    
            // Just like in the onMenuBeforeShow, we need to create a hash of our menus
            // and their listeners... if we don't, we remove the 1st menu's listeners
            // when the 2nd menu is created
            if (!me.headerMenuListeners) {
                me.headerMenuListeners = {};
            }
    
            var parentTableId = headerCt.ownerCt.id;
            var menuListener = me.headerMenuListeners[parentTableId];
            if (menuListener) {
                Ext.destroy(menuListener);
                me.headerMenuListeners[parentTableId] = null;
            }
    
            me.headerMenuListeners[parentTableId] = menu.on({
                beforeshow: me.onMenuBeforeShow,
                destroyable: true,
                scope: me
            });
        },
    
        destroy: function () {
            var me = this,
                filterMenuItem = me.filterMenuItem,
                item;
    
            // TODO: ADDING THIS AND REMOVING FROM THE Ext.destroy on the next line
            var headerMenuListeners = this.headerMenuListeners;
            Ext.destroy(me.headerCtListeners, me.gridListeners);
    
            me.bindStore(null);
            me.sep = Ext.destroy(me.sep);
    
            for (item in filterMenuItem) {
                filterMenuItem[item].destroy();
            }
    
            // TODO: ADDING THIS AND REMOVING FROM THE Ext.destroy on the next line
            for (item in headerMenuListeners) {
                headerMenuListeners[item].destroy();
            }
    
            this.callParent();
        }
    });