Добавить пользовательскую кнопку в выпадающие меню заголовка столбца {EXTJS 4}

Я хочу кнопку в выпадающем меню заголовка столбца сетки в extjs4. так что я могу добавить или удалить столбцы, которые связаны в базе данных. The button in red area is the one i'm looking for...

Любая помощь будет оценена ... Спасибо..:)

 sha27 апр. 2012 г., 15:06
Скрытие / отображение столбцов уже реализовано в подменю «Столбцы». Что именно вы пытаетесь достичь?
 sha27 апр. 2012 г., 15:59
Добавление столбцов по желанию может быть слишком сложным. Почему вы не добавили их все изначально и отметили, что некоторые из них скрыты? Таким образом, пользователь может просто проверить / снять галочку, используя стандартный интерфейс
 sha27 апр. 2012 г., 16:17
Вы тогда напутали :) Насколько я знаю, стандартного способа сделать это не существует. Вам нужно будет углубиться в код ExtJs, выяснить, где и как они создают это меню, и добавить туда свою собственную логику.
 NarayaN27 апр. 2012 г., 16:12
Сэр, я понимаю риск .... У меня есть около 13 столбцов, из которых 5 отображаются, а остальные уже скрыты. Владелец компании хочет создать новые столбцы по собственному желанию. Это что-то вроде операции Excel на сетках extjs .. :)
 NarayaN27 апр. 2012 г., 15:30
Сэр, я пытаюсь поставить пользовательскую кнопку, подобную этой, с именем & quot; Добавить новый столбец & quot; Который откроет окно для добавления нового столбца в базу данных .....

Ответы на вопрос(4)

Я взял ответ @ nobbler и создал плагин для этого:

Ext.define('Ext.grid.CustomGridColumnMenu', {
    extend: 'Ext.AbstractPlugin',
    init: function (component) {
        var me = this;

        me.customMenuItemsCache = [];

        component.headerCt.on('menucreate', function (cmp, menu) {
            menu.on('beforeshow', me.showHeaderMenu, me);
        }, me);
    },

    showHeaderMenu: function (menu) {
        var me = this;

        me.removeCustomMenuItems(menu);
        me.addCustomMenuitems(menu);
    },

    removeCustomMenuItems: function (menu) {
        var me = this,
            menuItem;

        while (menuItem = me.customMenuItemsCache.pop()) {
            menu.remove(menuItem.getItemId(), false);
        }
    },

    addCustomMenuitems: function (menu) {
        var me = this,
            renderedItems;

        var menuItems = menu.activeHeader.customMenu || [];

        if (menuItems.length > 0) {
            if (menu.activeHeader.renderedCustomMenuItems === undefined) {
                renderedItems = menu.add(menuItems);
                menu.activeHeader.renderedCustomMenuItems = renderedItems;
            } else {
                renderedItems = menu.activeHeader.renderedCustomMenuItems;
                menu.add(renderedItems);
            }
            Ext.each(renderedItems, function (renderedMenuItem) {
                me.customMenuItemsCache.push(renderedMenuItem);
            });
        }
    }
});

Вот как вы его используете (customMenu в колонке config позволяет вам определить ваше меню):

Ext.define('MyGrid', {
    extend: 'Ext.grid.Panel',
    plugins: ['Ext.grid.CustomGridColumnMenu'],
    columns: [
        {
            dataIndex: 'name',
            customMenu: [
                {
                    text: 'My menu item',
                    menu: [
                        {
                            text: 'My submenu item'
                        }
                    ]
                }
            ]
        }
    ]
});

Принцип работы этого плагина также решает проблему, с которой столкнулись другие реализации. Поскольку пользовательские пункты меню создаются только один раз для каждого столбца (кэширование уже отредактированной версии), он не забудет, проверялась ли она ранее или нет.

 10 нояб. 2016 г., 15:02
Все еще работает в Ext JS 6.
 NarayaN26 сент. 2013 г., 16:19
ценю ваши усилия, человек ... Большое спасибо
Решение Вопроса

Пару месяцев назад у меня была такая же проблема. Мне удалось решить эту проблему путем расширенияExt.grid.header.Container (Я переопределилgetMenuItems метод). Однако недавно я нашел другое решение, которое требует меньше кодирования: просто добавьте пункт меню вручную после создания виджета сетки.

Я выложу второе решение здесь:

Ext.create('Ext.grid.Panel', {
    // ...
    listeners: {
        afterrender: function() {
            var menu = this.headerCt.getMenu();
            menu.add([{
                text: 'Custom Item',
                handler: function() {
                    var columnDataIndex = menu.activeHeader.dataIndex;
                    alert('custom item for column "'+columnDataIndex+'" was pressed');
                }
            }]);           
        }
    }
});

Вотдемонстрация. & # X200B;

UPDATE

Вотдемонстрация для ExtJs4.1.

 16 июн. 2012 г., 09:58
@ Джордж, это так. Обновил мой ответ (когда вы переключаетесь на другую версию extjs, вы также должны включить соответствующий css).
 NarayaN28 апр. 2012 г., 14:22
Да, вы правы, сэр. Дело в том, что я использую диаграммы Bryntum с сеткой слева и представлением диаграммы с правой стороны. Я использовал слушателей для всего приложения, что неправильно. Я разберусь с оставшейся вещью. Но большое спасибо. Я рад вам за ваше драгоценное время ... Спасибо ... :)
 31 авг. 2012 г., 11:33
Если столбцы порядка изменены (путем перетаскивания), этого дополнительного пункта меню больше не будет. В этом случае меню заголовка создается заново. Пункты меню должны быть добавлены в «menucreate». обработчик, предложенный @chemoish
 28 апр. 2012 г., 14:15
@NarayaN, в моем случаеthis == grid, В твоем случаеthis == something-else, Вы должны заменитьthis со ссылкой на сетку. Одним из возможных способов является создание сетки, присвоение ее некоторой переменной. А затем выполните все манипуляции с использованием этой переменной (как в этомdemo). Дело в том, что вы должны иметь возможность доступа к ссылке на сетку.
 NarayaN28 апр. 2012 г., 13:52
да, я видел демонстрацию, и она отлично работает ...... Но когда я применил к своей сетке, я получаю эту ошибку под названием "Uncaught TypeError: Невозможно вызвать метод" getMenu & apos; из неопределенного & quot; ... Нужно ли включать плагин или что-то .....

Для людей, которые хотели бы иметь не только один «стандарт» меню столбца, но есть отдельный столбец, как я, может использовать следующее

initComponent: function ()
{
    // renders the header and header menu
    this.callParent(arguments);

    // now you have access to the header - set an event on the header itself
    this.headerCt.on('menucreate', function (cmp, menu, eOpts) {
        menu.on('beforeshow', this.showHeaderMenu);
    }, this);
},

showHeaderMenu: function (menu, eOpts)
{
    //define array to store added compoents in
    if(this.myAddedComponents === undefined)
    {
        this.myAddedComponents = new Array();
    }

    var columnDataIndex = menu.activeHeader.dataIndex,
        customMenuComponents = this.myAddedComponents.length;

    //remove components if any added
    if(customMenuComponents > 0)
    {
        for(var i = 0; i < customMenuComponents; i++)
        {
            menu.remove(this.myAddedComponents[i][0].getItemId());
        }

        this.myAddedComponents.splice(0, customMenuComponents);
    }

    //add components by column index
    switch(columnDataIndex)
    {
        case 'xyz': this.myAddedComponents.push(menu.add([{
                            text: 'Custom Item'}]));

                break;
    }
}
 NarayaN26 сент. 2013 г., 16:19
ценю ваши усилия, человек ... Большое спасибо
 10 нояб. 2016 г., 15:02
Все еще работает в Ext JS 6.

Из того, что я видел, вы должны избегать последующего события.

Контекст:

Приложение, которое я создаю, использует магазин с динамической моделью. Я хочу, чтобы в моей сетке была настраиваемая модель, извлекаемая с сервера (поэтому я могу иметь настраиваемые столбцы для своей настраиваемой сетки).

Поскольку заголовок недоступен для изменения (поскольку магазин перезагружается и уничтожает существующее меню, которое я изменил - используя приведенный выше пример). Альтернативное решение с таким же эффектом может быть выполнено так:

Ext.create('Ext.grid.Panel', {
    // ...

    initComponent: function () {
        // renders the header and header menu
        this.callParent(arguments);

        // now you have access to the header - set an event on the header itself
        this.headerCt.on('menucreate', function (cmp, menu, eOpts) {
            this.createHeaderMenu(menu);
        }, this);
    },

    createHeaderMenu: function (menu) {
        menu.removeAll();

        menu.add([
            // { custom item here }
            // { custom item here }
            // { custom item here }
            // { custom item here }
        ]);
    }
});
 NarayaN30 июл. 2012 г., 11:57
Спасибо за ответ. Я проверил это, и он тоже работает .....
 01 февр. 2013 г., 22:08
Исправление: если вы используете блокируемую сетку, есть два headerCts, которые могут быть достигнуты с помощьюthis.lockedGrid.headerCt или жеthis.normalGrid.headerCt, this в данном случае это объект сетки.
 12 нояб. 2014 г., 19:27
Кроме того, я отмечу, что вы можете отвечать на это событие изнутри контроллера, что может быть более подходящим для вашей организации кода в зависимости от того, насколько динамичны пользовательские элементы меню, используя ComponentQuery."grid headercontainer". docs
 01 февр. 2013 г., 21:39
Иногда ExtJS не встретит вас на полпути, и вам придется делать это быстро и грязно :) Я не мог заставить this.headerCt работать с моим классом пользовательской сетки, поэтому я в конечном итоге использовалthis.down('headercontainer');
 23 авг. 2012 г., 09:12
@NarayaN Да, я быстро обнаружил, что может потребоваться несколько часов, чтобы найти "правильное" сообщение. решение большинства проблем ExtJS4. Иногда мне даже приходится изменять файлы ядра. Но не сдавайтесь, соглашаясь на быстрое и грязное!

Ваш ответ на вопрос