ExtJs拖放当前面板并将其替换为拖动的面板

ExtJs拖放当前面板并将其替换为拖动的面板,extjs,Extjs,我有这样的面板设置(每个数字代表一个面板): 我想做的是,例如,我将面板1拖到面板6上,面板1应该在面板6上,而面板6应该在1上,如: 6 2 3 4 5 1 7 8 我该怎么做O 提前准备 我建议使用下面经过一些修改的功能来实现这一点 我的源代码在最新版本(4.0.7)中对门户示例进行了如下扩展: portal.html setConfig({enabled:true}); setPath('Ext.app','classes'); 外部要求([ “Ext.layout.container

我有这样的面板设置(每个数字代表一个面板):

我想做的是,例如,我将面板1拖到面板6上,面板1应该在面板6上,而面板6应该在1上,如:

6 2
3 4
5 1
7 8
我该怎么做O

提前准备

我建议使用下面经过一些修改的功能来实现这一点

我的源代码在最新版本(4.0.7)中对门户示例进行了如下扩展:

  • portal.html
  • 
    setConfig({enabled:true});
    setPath('Ext.app','classes');
    外部要求([
    “Ext.layout.container.*”,
    “Ext.resizer.Splitter”,
    “Ext.fx.target.Element”,
    “Ext.fx.target.Component”,
    “Ext.window.window”,
    “Ext.app.Portlet”,
    “Ext.app.PortalColumn”,
    “Ext.app.PortalPanel”,
    “Ext.app.Portlet”,
    “Ext.app.PortalDropZone”,
    “Ext.app.GridPortlet”,
    “Ext.app.ChartPortlet”
    ]);
    Ext.onReady(函数(){
    Ext.create('Ext.app.Portal');
    });
    
  • portal.js
  • Ext.define('Ext.app.Portal'{
    扩展:“Ext.container.Viewport”,
    用法:['Ext.app.PortalPanel','Ext.app.PortalColumn','Ext.app.GridPortlet','Ext.app.ChartPortlet'],
    getTools:function(){
    返回[{
    xtype:'工具',
    类型:'齿轮',
    处理程序:函数(e、目标、panelHeader、工具){
    var portlet=panelHeader.ownerCt;
    setLoading('Working…');
    Ext.defer(函数(){
    setLoading(false);
    }, 2000);
    }
    }];
    },
    initComponent:function(){
    var content=''+Ext.example.shortBogusMarkup+'';
    Ext.apply(本{
    id:“应用程序视口”,
    布局:{
    键入:“边框”,
    填充:“0 5”//从窗口边缘填充布局
    },
    项目:[{
    id:'应用程序标题',
    xtype:'框',
    地区:'北',
    身高:40,
    html:“外部门户”
    },{
    xtype:'容器',
    地区:'中心',
    布局:“边框”,
    项目:[{
    id:“应用程序选项”,
    标题:“选项”,
    地区:'西部',
    对,,
    宽度:200,
    最小宽度:150,
    最大宽度:400,
    斯普利特:是的,
    可折叠的:是的,
    布局:“手风琴”,
    布局配置:{
    动画:真实
    },
    项目:[{
    html:内容,
    标题:"导航",,
    autoScroll:是的,
    边界:错,
    iconCls:“导航”
    },{
    标题:“设置”,
    html:内容,
    边界:错,
    autoScroll:是的,
    iconCls:“设置”
    }]
    },{
    id:“应用程序门户”,
    xtype:'portalpanel',
    地区:'中心',
    项目:[{
    id:'col-1',
    项目:[{
    id:'portlet-1',
    标题:“网格Portlet”,
    工具:this.getTools(),
    项目:Ext.create('Ext.app.GridPortlet'),
    听众:{
    “关闭”:Ext.bind(this.onPortletClose,this)
    }
    },{
    id:'portlet-2',
    标题:“Portlet 2”,
    工具:this.getTools(),
    html:内容,
    听众:{
    “关闭”:Ext.bind(this.onPortletClose,this)
    }
    }]
    },{
    id:'col-2',
    项目:[{
    id:'portlet-3',
    标题:“Portlet 3”,
    工具:this.getTools(),
    html:''+Ext.example.bogusMarkup+'',
    听众:{
    “关闭”:Ext.bind(this.onPortletClose,this)
    }
    },{
    id:'portlet-4',
    标题:“股票Portlet”,
    工具:this.getTools(),
    项目:Ext.create('Ext.app.ChartPortlet'),
    听众:{
    “关闭”:Ext.bind(this.onPortletClose,this)
    }
    }]
    }]
    }]
    }]
    });
    this.callParent(参数);
    },
    onPortletClose:函数(portlet){
    this.showMsg(“'+portlet.title+'”已被删除);
    },
    showMsg:函数(msg){
    var el=Ext.get('app-msg'),
    msgId=Ext.id();
    this.msgId=msgId;
    el.update(msg.show();
    Ext.defer(this.clearMsg,3000,this[msgId]);
    },
    clearMsg:函数(msgId){
    if(msgId==this.msgId){
    Ext.get('app-msg').hide();
    }
    }
    });
    
  • PortalDropZone.js
  • Ext.define('Ext.app.PortalDropZone'{
    扩展:“Ext.dd.DropTarget”,
    构造函数:函数(门户、cfg){
    这
    
    6 2
    3 4
    5 1
    7 8
    
    Ext.define('Ext.app.Portal', {
    
        extend: 'Ext.container.Viewport',
    
        uses: ['Ext.app.PortalPanel', 'Ext.app.PortalColumn', 'Ext.app.GridPortlet', 'Ext.app.ChartPortlet'],
    
        getTools: function(){
            return [{
                xtype: 'tool',
                type: 'gear',
                handler: function(e, target, panelHeader, tool){
                    var portlet = panelHeader.ownerCt;
                    portlet.setLoading('Working...');
                    Ext.defer(function() {
                        portlet.setLoading(false);
                    }, 2000);
                }
            }];
        },
    
        initComponent: function(){
            var content = '<div class="portlet-content">'+Ext.example.shortBogusMarkup+'</div>';
    
            Ext.apply(this, {
                id: 'app-viewport',
                layout: {
                    type: 'border',
                    padding: '0 5 5 5' // pad the layout from the window edges
                },
                items: [{
                    id: 'app-header',
                    xtype: 'box',
                    region: 'north',
                    height: 40,
                    html: 'Ext Portal'
                },{
                    xtype: 'container',
                    region: 'center',
                    layout: 'border',
                    items: [{
                        id: 'app-options',
                        title: 'Options',
                        region: 'west',
                        animCollapse: true,
                        width: 200,
                        minWidth: 150,
                        maxWidth: 400,
                        split: true,
                        collapsible: true,
                        layout: 'accordion',
                        layoutConfig:{
                            animate: true
                        },
                        items: [{
                            html: content,
                            title:'Navigation',
                            autoScroll: true,
                            border: false,
                            iconCls: 'nav'
                        },{
                            title:'Settings',
                            html: content,
                            border: false,
                            autoScroll: true,
                            iconCls: 'settings'
                        }]
                    },{
                        id: 'app-portal',
                        xtype: 'portalpanel',
                        region: 'center',
                        items: [{
                            id: 'col-1',
                            items: [{
                                id: 'portlet-1',
                                title: 'Grid Portlet',
                                tools: this.getTools(),
                                items: Ext.create('Ext.app.GridPortlet'),
                                listeners: {
                                    'close': Ext.bind(this.onPortletClose, this)
                                }
                            },{
                                id: 'portlet-2',
                                title: 'Portlet 2',
                                tools: this.getTools(),
                                html: content,
                                listeners: {
                                    'close': Ext.bind(this.onPortletClose, this)
                                }
                            }]
                        },{
                            id: 'col-2',
                            items: [{
                                id: 'portlet-3',
                                title: 'Portlet 3',
                                tools: this.getTools(),
                                html: '<div class="portlet-content">'+Ext.example.bogusMarkup+'</div>',
                                listeners: {
                                    'close': Ext.bind(this.onPortletClose, this)
                                }
                            },{
                                id: 'portlet-4',
                                title: 'Stock Portlet',
                                tools: this.getTools(),
                                items: Ext.create('Ext.app.ChartPortlet'),
                                listeners: {
                                    'close': Ext.bind(this.onPortletClose, this)
                                }
                            }]
                        }]
                    }]
                }]
            });
            this.callParent(arguments);
        },
    
        onPortletClose: function(portlet) {
            this.showMsg('"' + portlet.title + '" was removed');
        },
    
        showMsg: function(msg) {
            var el = Ext.get('app-msg'),
                msgId = Ext.id();
    
            this.msgId = msgId;
            el.update(msg).show();
    
            Ext.defer(this.clearMsg, 3000, this, [msgId]);
        },
    
        clearMsg: function(msgId) {
            if (msgId === this.msgId) {
                Ext.get('app-msg').hide();
            }
        }
       });
    
        Ext.define('Ext.app.PortalDropZone', {
        extend: 'Ext.dd.DropTarget',
    
        constructor: function(portal, cfg) {
            this.portal = portal;
            Ext.dd.ScrollManager.register(portal.body);
            Ext.app.PortalDropZone.superclass.constructor.call(this, portal.body, cfg);
            portal.body.ddScrollConfig = this.ddScrollConfig;
        },
    
        ddScrollConfig: {
            vthresh: 50,
            hthresh: -1,
            animate: true,
            increment: 200
        },
    
        createEvent: function(dd, e, data, col, c, pos) {
            return {
                portal: this.portal,
                panel: data.panel,
                columnIndex: col,
                column: c,
                position: pos,
                data: data,
                source: dd,
                rawEvent: e,
                status: this.dropAllowed
            };
        },
    
        notifyOver: function(dd, e, data) {
            var xy = e.getXY(),
                portal = this.portal,
                proxy = dd.proxy;
    
            // case column widths
            if (!this.grid) {
                this.grid = this.getGrid();
            }
    
            // handle case scroll where scrollbars appear during drag
            var cw = portal.body.dom.clientWidth;
            if (!this.lastCW) {
                // set initial client width
                this.lastCW = cw;
            } else if (this.lastCW != cw) {
                // client width has changed, so refresh layout & grid calcs
                this.lastCW = cw;
                //portal.doLayout();
                this.grid = this.getGrid();
            }
    
            // determine column
            var colIndex = 0,
                colRight = 0,
                cols = this.grid.columnX,
                len = cols.length,
                cmatch = false;
    
            for (len; colIndex < len; colIndex++) {
                colRight = cols[colIndex].x + cols[colIndex].w;
                if (xy[0] < colRight) {
                    cmatch = true;
                    break;
                }
            }
            // no match, fix last index
            if (!cmatch) {
                colIndex--;
            }
    
            // find insert position
            var overPortlet, pos = 0,
                h = 0,
                match = false,
                overColumn = portal.items.getAt(colIndex),
                portlets = overColumn.items.items,
                overSelf = false;
    
            len = portlets.length;
    
            for (len; pos < len; pos++) {
                overPortlet = portlets[pos];
                h = overPortlet.el.getHeight();
                if (h === 0) {
                    overSelf = true;
                } else if ((overPortlet.el.getY() + (h / 2)) > xy[1]) {
                    match = true;
                    break;
                }
            }
    
            pos = (match && overPortlet ? pos : overColumn.items.getCount()) + (overSelf ? -1 : 0);
            var overEvent = this.createEvent(dd, e, data, colIndex, overColumn, pos);
    
            if (portal.fireEvent('validatedrop', overEvent) !== false && portal.fireEvent('beforedragover', overEvent) !== false) {
    
                // make sure proxy width is fluid in different width columns
                proxy.getProxy().setWidth('auto');
    
                if (overPortlet) {
                    proxy.moveProxy(overPortlet.el.dom.parentNode, match ? overPortlet.el.dom : null);
                } else {
                    proxy.moveProxy(overColumn.el.dom, null);
                }
    
                this.lastPos = {
                    c: overColumn,
                    col: colIndex,
                    p: overSelf || (match && overPortlet) ? pos : false
                };
                this.scrollPos = portal.body.getScroll();
    
                portal.fireEvent('dragover', overEvent);
                return overEvent.status;
            } else {
                return overEvent.status;
            }
    
        },
    
        notifyOut: function() {
            delete this.grid;
        },
    
        notifyDrop: function(dd, e, data) {
            delete this.grid;
            if (!this.lastPos) {
                return;
            }
            var c = this.lastPos.c,
                col = this.lastPos.col,
                pos = this.lastPos.p,
                panel = dd.panel,
                dropEvent = this.createEvent(dd, e, data, col, c, pos !== false ? pos : c.items.getCount());
    
            if (this.portal.fireEvent('validatedrop', dropEvent) !== false && this.portal.fireEvent('beforedrop', dropEvent) !== false) {
    
                // make sure panel is visible prior to inserting so that the layout doesn't ignore it
                panel.el.dom.style.display = '';
                /*
                 * Start customization
                 * Switch position of two panels when drop
                 */
                var sourceColumn = panel.ownerCt;
                var sourceRow = sourceColumn.items.indexOf(panel);
                if (pos !== false) {
                    var targetPanel = c.items.getAt(pos);
                    sourceColumn.insert(sourceRow, targetPanel);
                    c.insert(pos, panel);
                } else {
                    c.add(panel);
                }
                /*
                 * End of customization
                 */
                dd.proxy.hide();
                this.portal.fireEvent('drop', dropEvent);
    
                // scroll position is lost on drop, fix it
                var st = this.scrollPos.top;
                if (st) {
                    var d = this.portal.body.dom;
                    setTimeout(function() {
                        d.scrollTop = st;
                    },
                    10);
                }
    
            }
            delete this.lastPos;
            return true;
        },
    
        // internal cache of body and column coords
        getGrid: function() {
            var box = this.portal.body.getBox();
            box.columnX = [];
            this.portal.items.each(function(c) {
                box.columnX.push({
                    x: c.el.getX(),
                    w: c.el.getWidth()
                });
            });
            return box;
        },
    
        // unregister the dropzone from ScrollManager
        unreg: function() {
            Ext.dd.ScrollManager.unregister(this.portal.body);
            Ext.app.PortalDropZone.superclass.unreg.call(this);
        }
        });