ExtJs下拉并用拖动面板替换当前面板

时间:2011-12-05 09:49:34

标签: extjs

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

1 2
3 4
5 6
7 8

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

6 2
3 4
5 1
7 8

我该怎么做? :o

提前Ty!

1 个答案:

答案 0 :(得分:1)

我建议使用Sencha Portal功能,并在下面进行一些修改,以实现此目的。

我的源代码扩展了最新版本(4.0.7)中的门户网站示例,如下所示:

  1. portal.html
  2. <html>
    <head>   
        <link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />
        <link rel="stylesheet" type="text/css" href="portal.css" />
    
        <script type="text/javascript" src="../../builds/ext-core.js"></script>
        <script type="text/javascript" src="../../ext-all-debug.js"></script>
        <!-- shared example code -->
        <script type="text/javascript" src="../shared/examples.js"></script>
        <!--
            <script type="text/javascript" src="classes.js"></script> 
         -->
    
    
        <script type="text/javascript" src="portal.js"></script>
        <script type="text/javascript">
            Ext.Loader.setConfig({enabled:true});
            Ext.Loader.setPath('Ext.app', 'classes');
    
            Ext.require([
                '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(function(){
                Ext.create('Ext.app.Portal');
            });
        </script>
    </head>
    <body>
        <span id="app-msg" style="display:none;"></span>
    </body>
    </html>
    
    1. portal.js
    2. 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();
              }
          }
         });
      
      1. PortalDropZone.js
      2.     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);
            }
            });