1

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!

  • Have you reported this to Sencha Support? This is definitely a bug, and it feels like some sort of reference issue. `Ext.grid.filters.Filters:onMenuBeforeShow` is supposed to fire every time the menu gets clicked, but it seems like that's not always the case when you show one of the menus first. – incutonez Aug 19 '20 at 04:32

1 Answers1

0

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();
    }
});
incutonez
  • 3,241
  • 9
  • 43
  • 92
  • 1
    Thanks for the detailed explanation, the override works on my end! I don't have access to sencha support , if you don't mind please submit a ticket for this defect. – master.jeuss Aug 19 '20 at 06:52
  • I created a Sencha Support thread for this, and apparently a bug was already logged into their system as EXTJS-28785. – incutonez Aug 19 '20 at 19:26