【问题标题】:How to place combobox in the tab's title?如何在选项卡的标题中放置组合框?
【发布时间】:2026-01-10 18:05:02
【问题描述】:

是否可以在标签的标题中显示组合框(最好是 extjs 组合)?

我创建了an example on jsfiddle,但是有这样的问题:
1.无法显示combo的选项列表(鼠标点击不起作用)
2. Tab的高度不正确(我想这可以通过对组合应用高度来解决)。

示例代码:

new Ext.TabPanel({
    renderTo: 'tab-with-combo',
    activeTab: 0,
    items:[
        {
            title: 'First tab ' +
                '<select>' +
                    '<option>Option 1</option>' +
                    '<option>Option 2</option>' +
                '</select>'},
        {title: 'Second tab'}
    ]
});

【问题讨论】:

    标签: extjs combobox extjs3 tabpanel


    【解决方案1】:

    回答您的问题:

    1. Tabpanel组件是preventDefault标签点击事件,所以我们需要修改onStripMouseDown方法。

    2. 如果我们在title 属性中定义了一些东西,那么extjs 会将它放在具有特殊样式的span.x-tab-strip-text html 元素中。所以我们需要在选项卡中的这个元素之后附加我们的组合框。

    代码:

    new Ext.TabPanel({
        renderTo : 'tab-with-combo',
        activeTab : 0,
        items : [{
                title : 'First tab ',
                listeners : {
                    afterrender : function (panel) {
                        //the needed tabEl
                        var tabEl = panel.findParentByType('tabpanel').getTabEl(panel);
                        var tabStripInner = Ext.fly(tabEl).child('span.x-tab-strip-inner', true);
                        //we need that for have the combobox in the same line as the text
                        Ext.fly(tabStripInner).child('span.x-tab-strip-text', true).style.float = 'left';
                        //create the combobox html element
                        var combo = document.createElement("select");
                        var opt1 = document.createElement("option");
                        opt1.innerHTML = 'Option 1';
                        var opt2 = document.createElement("option");
                        opt2.innerHTML = 'Option 2';
                        combo.appendChild(opt1);
                        combo.appendChild(opt2);
                        combo.style.float = 'left';                 
                        //add the combobox to the tab
                        tabStripInner.appendChild(combo);
                    }
                }
            }, {
                title : 'Second tab'
            }
        ],
    
        //this is the tab's click handler
        onStripMouseDown : function (e) {
            if (e.button !== 0) {
                return;
            }
            var t = this.findTargets(e);
            if (t.close) {
                //preventDefault needed to move here
                e.preventDefault();
                if (t.item.fireEvent('beforeclose', t.item) !== false) {
                    t.item.fireEvent('close', t.item);
                    this.remove(t.item);
                }
                return;
            }
            if (t.item && t.item != this.activeTab) {
                this.setActiveTab(t.item);
            }
        },
    });

    【讨论】:

    • 感谢您的回答。我喜欢动态添加组合的想法(必须如此),但我不喜欢更改默认的私有 extjs 方法;)。我已经创建了您的示例 here - 它适用于 Chrome,但不适用于 FF(最新 23)。
    • 顺便说一句,我创建了另一个示例,几乎涵盖了我需要的所有内容。请检查它here。但我不喜欢额外的 css 规则(在我的例子中,我们使用自定义主题)和额外的 div 包装器生成。我会尽快更新答案。
    【解决方案2】:

    感谢@Alexander.Berg 的回答,这可以正常工作(例如here):

    var comboId = Ext.id();
    new Ext.TabPanel({
        cls: 'tab-panel-with-combo',
        renderTo: 'tab-with-combo',
        activeTab: 0,
        items:[
            {
                title: '<div class="tab-title" style="float: left; padding-right: 5px;">First tab with a long name</div> ' +
                       '<div style="float: right;" id="' + comboId + '" ></div>',
                closable: true,
                html: 'Content of the first tab'
            },
            {
                title: '<div class="tab-title">Second tab</div>',
                closable: true,
                html: 'Content of the second tab'
            }
        ],
        listeners: {
            afterrender: function() {
                var store = new Ext.data.ArrayStore({
                    fields: ['abbr', 'case_name'],
                    data : [
                        ['one',   'Case #1'],
                        ['two',   'Case #2'],
                        ['three', 'Case #3']
                    ]
                });
    
                new Ext.form.ComboBox({
                    store: store,
                    displayField:'case_name',
                    editable: false,
                    typeAhead: false,
                    selectOnFocus:false,
                    mode: 'local',
                    forceSelection: true,
                    triggerAction: 'all',
                    emptyText:'Select a case...',
                    renderTo: comboId
                });
            }
        }
    });
    

    【讨论】: