javascriptextjsextjs4extjs4.1extjs4.2

ExtJs - delay in rendering column list in table when adding dropdown from column list


I'm trying to make a drop down button with a list of columns in a table. I created this code, but the problem is that when the code is executed, there are no columns in this yet, so the array is empty. The button is generated but without any options. The solution is to add setTimeout, the data arrives, but the button does not appear because the application has already rendered the container in which it is located. Second thing, setTimeout is not a very good solution.

Ext.define('ExtModules.ToolbarItems.ManageColums', {
  extend: 'Ext.form.Panel',
  mixins: { formFields: 'ExtModules.Components.GenericForm' },

  manageColumns() {
      // this.getColumns is []
      const columnMenuItems = this.getColumns().map((column) => {
      console.log(column)
      return {
        xtype: 'menucheckitem',
        text: column.text,
        checked: true,
        handler: (item) => {
          const dataIndex = column.dataIndex;
          const columnInstance = this.getColumnManager().getHeaderByDataIndex(dataIndex);

          if (columnInstance) {
            columnInstance.setVisible(item.checked);
          }
        },
      };
    });
  
    return Ext.create('Ext.button.Button', {
      text: 'Columns',
      menu: Ext.create('Ext.menu.Menu', {
        items: columnMenuItems,
      }),
    });

  },
})

...

Ext.define('ExtModules.Helpers.ToolbarHelper', {
  mixins: {
    ...
    manageColumns: 'ExtModules.ToolbarItems.ManageColums',
    ...
  },
  requires: ['Ext.ux.exporter.Exporter'],

  setUpExtensionBar(extensions, position) {
    const extensionBar = Ext.create('Ext.toolbar.Toolbar', {
      layout: {
        type: 'hbox',
        pack: 'start',
        align: 'stretch',
      },
      // height: 40,
      dock: position || 'top',
      items: extensions,
    })
    this.addDocked(extensionBar)
  },
...

...

Ext.define('ExtModules.Base.DashboardModule', {
  mixins: {
    extensions: 'ExtModules.ToolbarItems.SettingsEditor',
    toolbarHelper: 'ExtModules.Helpers.ToolbarHelper',
  }, .....

my current use case

Ext.define('ExtModules.ToolbarItems.ManageColums', {
    xtype: 'managecolumns',
    
    manageColumns() {
      const button = {
        xtype: 'button',
        name: 'Manage',
        text: 'Manage Columns',
        handler: (btn, e) => {
          if (btn.menu.items.length === 0) {
            const menuItems = this.createList()

            btn.menu.removeAll()
            btn.menu.add(menuItems)
            btn.showMenu()
          }
        },
        menu: {
          xtype: 'menu',
          items: [],
        }
      };
      return button
    },

    createColumnMenuItems(button) {
      const menuItems = this.createList();
      const newMenu = Ext.create('Ext.menu.Menu', {
        items: this.createColumnMenuItems(menuItems),
      });
  
      button.setMenu(newMenu);
  },
  
  createList() {
    const columns = this.getColumnManager().getColumns();

    return columns.map((column) => ({
      xtype: 'menucheckitem',
      text: column.text,
      checked: true,
      cls: 'toolbar-helper__custom-checkbox-menu-item',
      handler: (item) => {
        const dataIndex = column.dataIndex;
        const columnInstance = this.getColumnByDataIndex(dataIndex);
  
        if (columnInstance) {
          columnInstance.setVisible(item.checked);
        }
      },
    }));
  },
  getColumnByDataIndex(dataIndex) {
    const columnManager = this.getColumnManager();
    const targetColumn = columnManager.getColumns().find((column) => column.dataIndex === dataIndex);
  
    return targetColumn;
  },
  
  getColumnManager() {
    return this.getHeaderContainer().getHeaderAtIndex(0);
  },
})

/* toolbar.js
Ext.define('ExtModules.Helpers.ToolbarHelper', {
  mixins: {
    ...
    manageColumns: 'ExtModules.ToolbarItems.ManageColumns',
  },
  requires: ['Ext.ux.exporter.Exporter'],
*/

Is anyone able to help me with this? I don't really have any idea how to fix it


Solution

  • Please check the below sample based on your use case,

    Ext.define('ExtModules.Store.SampleStore', {
        extend: 'Ext.data.Store',
        fields: ['id', 'name', 'age'],
        data: [{
            id: 1,
            name: 'John',
            age: 30
        }, {
            id: 2,
            name: 'Jane',
            age: 25
        }],
    });
    
    Ext.define('ExtModules.Grid.SampleGrid', {
        extend: 'Ext.grid.Panel',
        store: 'ExtModules.Store.SampleStore',
        id: 'SampleGrid',
        columns: [{
            text: 'ID',
            dataIndex: 'id',
            flex: 1
        }, {
            text: 'Name',
            dataIndex: 'name',
            flex: 1
        }, {
            text: 'Age',
            dataIndex: 'age',
            hidden: true,
            flex: 1
        }, {
            text: 'Email',
            dataIndex: 'email',
            hidden: true,
            flex: 1
        }],
    });
    
    Ext.define('ExtModules.ToolbarItems.ManageColumns', {
        extend: 'Ext.panel.Panel',
        xtype: 'managecolumns',
        initComponent() {
            Ext.apply(this, {
                items: [{
                    xtype: 'button',
                    text: 'Columns',
                    menu: this.createColumnMenu(),
                }, ],
            });
            this.callParent(arguments);
        },
        createColumnMenu() {
            return Ext.create('Ext.menu.Menu', {
                items: this.createColumnMenuItems(),
            });
        },
        createColumnMenuItems() {
            const columns = this.columns || [];
            return columns.map((column) => {
                return {
                    xtype: 'menucheckitem',
                    text: column.text,
                    checked: !column.hidden, // Set initial value based on column visibility
                    handler: (item) => {
                        const dataIndex = column.dataIndex;
                        const columnInstance = this.getColumnByDataIndex(dataIndex);
                        if (columnInstance) {
                            columnInstance.setVisible(item.checked);
                        }
                    },
                };
            });
        },
    
        getColumnByDataIndex(dataIndex) {
            const grid = Ext.getCmp('SampleGrid');
            const columnManager = grid.getColumnManager();
            const targetColumn = columnManager.getColumns().find((column) => column.dataIndex === dataIndex);
    
            return targetColumn;
        },
    
        getColumnManager() {
            return Ext.getCmp('SampleGrid').getHeaderContainer().getHeaderAtIndex(0); // Adjust 'yourGridId'
        },
    });
    
    Ext.application({
        name: 'MyApp',
    
        launch() {
            var sampleStore = Ext.create('ExtModules.Store.SampleStore');
            var sampleGrid = Ext.create('ExtModules.Grid.SampleGrid', {
                store: sampleStore,
            });
            var manageColumnsToolbar = Ext.create('ExtModules.ToolbarItems.ManageColumns', {
                columns: sampleGrid.columns,
            });
    
            Ext.create('Ext.container.Viewport', {
                layout: 'fit',
                items: [{
                    xtype: 'panel',
                    items: [sampleGrid, manageColumnsToolbar],
                }],
            });
        },
    });