3

Is it possible to show combobox (better if it will be extjs combo) in the tab's title?

I have created an example on jsfiddle but there are such issues:
1. It is not possible to show combo's options list (mouse click don't work)
2. Tab's height is incorrect (I guess this can be fixed by applying height to the combo).

Sample code:

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'}
    ]
});
Andron
  • 6,413
  • 4
  • 43
  • 56

2 Answers2

3

Answer for your questions:

  1. the Tabpanel component is preventDefault the event at tab click, so we need to modify the onStripMouseDown method.

  2. if we define something in the title property, then the extjs will put it in the span.x-tab-strip-text html element which has a special style. So we need to append our combobox after this element in the tab.

The code:

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);
        }
    },
});
Alexander.Berg
  • 2,225
  • 1
  • 17
  • 18
  • Thanks for the answer. I like idea to add a combo dynamically (as it must be), but I don't like to change default private extjs method ;). I've created your example [here](http://jsfiddle.net/andron/4Evqr/) - it works in Chrome, but not in FF (latest 23). – Andron Sep 03 '13 at 14:44
  • BTW I have created another example that covers almost all I need. Please check it [here](http://jsfiddle.net/andron/GYxq8/2/). But I dislike additional css rules (in my case we use a custom theme) and additional div wrappers generation. I'll update answer soon. – Andron Sep 03 '13 at 14:50
0

Thanks for @Alexander.Berg answer, this works correctly (example is 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
            });
        }
    }
});
Andron
  • 6,413
  • 4
  • 43
  • 56