Show window in tabpanel

extjsextjs-mvcextjs4

I am working on extjs4, my case is:
Extjs mvc is used to build my application, viewport is the toppest container of my application, west region is a tree, center region is a tabpage container, when click the tree item, a new page with certain content will be created. then in this page, I popup a model window, this model window just mask the page, not the whole viewport, so that I can still click the tree item to open another new page.
I have achieved this, but there is a problem, if I have already open a model window in a tab, and I switch to a another tab then return back, the model window is hidden, but I still want that window to show if I haven't closed it. Can anyone help me, is there a better way except using ifram in tabpage?

app.js:

Ext.application({
    name: 'SysOpv',
    appFolder: '/Js/AppSysOpv/app',
    autoCreateViewport: true,
    controllers: [
        'Category',
        'Band'
    ]
});

Viewport:

Ext.define('SysOpv.view.Viewport', {
    extend: 'Ext.container.Viewport',
    layout: 'fit',

    initComponent: function() {
        this.items = {
            dockedItems: [{
                dock: 'top',
                xtype: 'toolbar',
                height: 80,
                items: [ 
                    { xtype: 'component', html: 'setup' }
                ]
            }],
            layout: {
                type: 'hbox',
                align: 'stretch'
            },
            items: [{ 
                width: 250, 
                xtype: 'categorytree'
            }, {
                id: 'maintabpanel',
                flex: 1,                
                xtype: 'tabpanel'
            }]        
        };

        this.callParent(arguments);
    }
});

Tree View:

Ext.define('SysOpv.view.category.Tree', {
    extend: 'Ext.tree.Panel',
    alias: 'widget.categorytree',
    title: 'setup',
    rootVisible: false,
    useArrows: true,
    hideHeaders: true,    
    columns: [{
        flex: 1,
        xtype: 'treecolumn',
        text: 'Name',
        dataIndex: 'name'
    }],
    store: 'Category',

    initComponent: function() {
        this.callParent(arguments);
    }
});

Window View:

Ext.define('SysOpv.view.edit.Band', {
    extend: 'Ext.window.Window',
    alias: 'widget.editband',
    title: 'Setup',
    layout: 'fit',
    constrain: true,
    modal: true,  

    initComponent: function() {
        this.items = [{
            xtype: 'form',
            bodyPadding: 10,
            items: [{
                xtype: 'textfield',
                name: 'name',
                fieldLabel: 'Name'
            }]
        }];

        this.buttons = [{
            text: 'Save',
            action: 'save'
        }, {
            text: 'Cancel',
            scope: this,
            handler: this.close
        }];

        this.callParent(arguments);
    }
});

Tree Controller:

Ext.define('SysOpv.controller.Category', {
    extend: 'Ext.app.Controller',
    models: [ 'Category' ],
    stores: [ 'Category' ],
    views: [ 'category.Tree' ],

    init: function() {
        this.control({
            'categorytree': {
                itemdblclick: this.onTreeItemdblclick
            }
        });
    },

    onTreeItemdblclick: function (tree, record, item, index, e, eOpts) {
        var mainTabs = Ext.getCmp('maintabpanel');
        var tabId = record.get('id');

        if (mainTabs) {
            var checkTab = mainTabs.getComponent(tabId);
            if (checkTab) {
                mainTabs.setActiveTab(checkTab);
            } else {
                var controller;
                var list;

                switch (tabId) {
                    case '0101':
                        list = Ext.widget('listband');
                        break;
                }                   

                if (list)
                {
                    var tabPage = mainTabs.add({
                        id: record.get('id'),
                        title: record.get('name'),
                        closable: true,
                        layout: 'fit',
                        items: [ list ]
                    }); 

                    mainTabs.setActiveTab(tabPage); 
                }              
            }
        }        
    }
});

Module Controller:

Ext.define('SysOpv.controller.Band', {
    extend: 'Ext.app.Controller',
    models: [ 'Band' ],
    stores: [ 'Band' ],
    views: [ 'list.Band', 'edit.Band' ],

    init: function() {
        this.control({
            'listband button[action=edit]': {
                click: this.onEdit
            }
        });
    },

    onEdit: function(button, e, eOpts) {

        var edit = Ext.widget('editband');
        var list = button.up('gridpanel');

        if (list.getSelectionModel().hasSelection()) {
            var record = list.getSelectionModel().getLastSelected();
            // I use renderTo here but have no effect, 
            // so I search in the google find a way to show the window in tab, 
            // and not mask all the viewport.
            button.up('#0101').add(edit);
            edit.down('form').loadRecord(record);
            edit.show();
        } else {
            console.log('Not selected');
        }
    }
});

Best Answer

Below is example solution:

Ext.create('Ext.TabPanel', {
    renderTo: 'container',
    items: [
        { 
            title: 'Tab 1',
            itemId: 'tab1',
            items: [
                { xtype: 'button', text: 'Show window', handler: function(){
                    var tab = this.up('#tab1'); // Find tab
                    var win = Ext.widget('editband'); // Find window
                    this.up('tabpanel').showWindow(tab, win);
                } }
            ]
        },
    ],
    showWindow: function(tab, w){
        tab.add(w);
        tab.popup = w;
        w.on('close', function() { // clean up after window close
            delete this.popup;
        }, tab, { single: true });
        w.show();
    },
    listeners: {
        tabchange: function(panel, tab) {
            if (tab.popup !== undefined) { // show window after tab change
                tab.popup.show();
            }
        }
    }
});

Basically I've created event handler for tabchange event in which I re-show window. Working sample: http://jsfiddle.net/aCxYU/1/

Related Topic