个性化主页设置,左边是一棵树,左边是一个portal.点击树加载到portal中去,实现了与数据库的交互.ccom.dzf.indexset = function(config) { Ext.apply(this,config); this.init();};Ext.extend(com.dzf.indexset, Ext.util.Observable, { init : function() { this.createWin(); }, createWin : function() { var proxy = this; var win = new Ext.Window({ height : 450, width : 800, items : [{ xtype : 'tabpanel', border : false, activeTab : 0, defaults : { height : 380 }, items : [{ title : '主页设置', layout : 'column', border : false, items : [{ columnWidth : .2, title : '模块列表', defaults : { height : 380 }, items : [this.getTree()] }, { xtype : 'portal', columnWidth : .8, id : 'portalset', defaults : { height : 380 } }] }, { title : '设置密码' }] }], buttons : [{ text : '确定', handler : function() { win.close(); var portal= Ext.getCmp(proxy.panelid); //portal.desto; items=portal.items.items[0].destroy();// for(var i=0;i<items.length;i++){ // var p=items[i].items.items; // items[i].doLayout(); for(var j=0;j<p.length;j++){ count++; } // } // portal.doLayout(); new com.dzf.index({ panelid : 'center-panel', margins : '35 5 5 5', style : 'padding:0px 10px 0px 10px' }); } }] }); win.show(); }, getTree : function() { var tree = new Ext.tree.TreePanel({ border : false, onlyLeafCheckable : false, checkModel : "multiple", id : 'tree', autoScroll : true, enableDD : false, containerScroll : true, rootVisible : false, loader : new Ext.tree.DWRTreeLoader({ dwrCall : indexportalService.getUserModule, getParams : function(node) { return {}; }, baseAttrs : { uiProvider : Ext.tree.TreeCheckNodeUI } }), tools : [{ id : 'refresh',// 根据id的不同会出现不同的按钮 handler : function() { var tree = Ext.getCmp('extExample-tree-checkboxTree'); tree.root.reload();// 让根节点重新加载 tree.body.mask('数据加载中……', 'x-mask-loading');// 给tree的body加上蒙版 tree.root.expand(true, false, function() { tree.body.unmask();// 全部展开之后让蒙版消失 indexportalService.getPortalColumns(com.dzf.indexset.prototype.BuildPortColumn); }); } }] }); var root = new Ext.tree.AsyncTreeNode({ text : '根', draggable : false }); tree.setRootNode(root); root.expand(true, false, function() { indexportalService.getPortalColumns(com.dzf.indexset.prototype.BuildPortColumn); });// root.loadComplete(true, false, function() { // indexportalService.getPortalColumns(com.dzf.indexset.prototype.BuildPortColumn); // }); treeCheckAction = function(node, checked) { var id = node.id; var title = node.text; var portlet = Ext.getCmp(id+"set"); if (checked) { if (portlet) { return; } var count=0; var portal= Ext.getCmp("portalset").items.items; for(var i=0;i<portal.length;i++){ var p=portal[i].items.items; for(var j=0;j<p.length;j++){ count++; } } if(count<=4){ var order = 0; var parent = Ext.getCmp("portalcolumn" + node.attributes.userid + node.attributes.modulecolumn + "set"); var panel = new Ext.ux.Portlet({ id : id+"set", title : title }); if (!parent) { parent = Ext.getCmp("portalset").items.items[0]; } parent.add(panel); parent.doLayout(); order = parent.items.items.length - 1; var params = { id : id, order : order, columnwidth : parent.columnWidth }; indexportalService.savePortlet(params); }else{ node.ui.checkbox.checked = false; Ext.MessageBox.alert("提示","你最多能选择5个!") } } else { com.dzf.indexset.prototype.removePorlet(portlet); } } tree.on("check", treeCheckAction, this); return tree; }, tools : [{ id : 'close', handler : function(e, target, panel) { com.dzf.indexset.prototype.removePorlet(panel); } }], removePorlet : function(panel) { // Ext.Msg.confirm('删除模块', '您确认要删除"' + panel.title + '"吗?', // function(btn, // text) { // if (btn == 'yes') { var id = panel.id; var columnid = panel.ownerCt.id; var params = { id : id, columnid : columnid }; // 发送删除数据的请求 indexportalService.removePorlet(params, function(data) { var json = Ext.util.JSON.decode(data); if (json.success) { var id = panel.id; var parent=panel.ownerCt; parent.remove(panel, true); parent.doLayout(); if(id.indexOf("set")>0) id=id.substring(0,id.indexOf("set")); Ext.getCmp("tree").getNodeById(id).ui.checkbox.checked = false; } else { Ext.Msg.alert('WebMessage', panel.title + '删除失败!'); } }); // } else { // return; // } // }); }, BuildPortColumn : function(data) { var jsonData = Ext.util.JSON.decode(data); for (var i = 0; i < jsonData.length; i++) { var columnid = jsonData[i].fuserprocolumn_id + "set"; var columnwidth = jsonData[i].fuserprocolumn_width / 100; var portal = Ext.getCmp("portalset"); var PortalColumn = new Ext.ux.PortalColumn({ id : columnid, columnWidth : columnwidth, style : 'padding:10px 0 10px 10px', defaults : { tools : com.dzf.indexset.prototype.tools, height : 60 } }); portal.add(PortalColumn); portal.doLayout(); } indexportalService .getPortalPortlet(com.dzf.indexset.prototype.BuildPortletSet); }, BuildPortletSet : function(data) { var jsonData = Ext.util.JSON.decode(data); for (var i = 0; i < jsonData.length; i++) { var columnid = jsonData[i].fuserprocolumn_id + "set"; var id = jsonData[i].modelcode+"set"; var title = jsonData[i].modelname; var order = jsonData[i].fuserprofile_order; var parent = Ext.getCmp(columnid); if (!parent) { parent = Ext.getCmp("portalset").items.items[0]; } var panel = new Ext.ux.Portlet({ id : id, title : title }); parent.add(panel); parent.doLayout(); if(id.indexOf("set")>0) id=id.substring(0,id.indexOf("set")); Ext.getCmp("tree").getNodeById(id).ui.checkbox.checked = true; } }})protal源码改了下 可以进行移动保存Ext.ux.Portlet = Ext.extend(Ext.Panel, { anchor : '100%', collapsible : true, draggable : true, cls : 'x-portlet' });Ext.reg('portlet', Ext.ux.Portlet);Ext.ux.PortalColumn = Ext.extend(Ext.Container, { layout : 'anchor', autoEl : 'div', defaultType : 'portlet', cls : 'x-portal-column' });Ext.reg('portalcolumn', Ext.ux.PortalColumn);Ext.ux.Portal = Ext.extend(Ext.Panel, { layout : 'column', autoScroll : true, cls : 'x-portal', defaultType : 'portalcolumn', initComponent : function() { Ext.ux.Portal.superclass.initComponent.call(this); this.addEvents({ validatedrop : true, beforedragover : true, dragover : true, beforedrop : true, drop : true }); }, initEvents : function() { Ext.ux.Portal.superclass.initEvents.call(this); this.dd = new Ext.ux.Portal.DropZone(this, this.dropConfig); }, beforeDestroy : function() { if (this.dd) { this.dd.unreg(); } Ext.ux.Portal.superclass.beforeDestroy.call(this); } });Ext.reg('portal', Ext.ux.Portal);Ext.ux.Portal.DropZone = function(portal, cfg) { this.portal = portal; Ext.dd.ScrollManager.register(portal.body); Ext.ux.Portal.DropZone.superclass.constructor.call(this, portal.bwrap.dom, cfg); portal.body.ddScrollConfig = this.ddScrollConfig;};Ext.extend(Ext.ux.Portal.DropZone, Ext.dd.DropTarget, { 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, px = 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) { this.lastCW = cw; } else if (this.lastCW != cw) { this.lastCW = cw; portal.doLayout(); this.grid = this.getGrid(); } // determine column var col = 0, xs = this.grid.columnX, cmatch = false; for (var len = xs.length; col < len; col++) { if (xy[0] < (xs[col].x + xs[col].w)) { cmatch = true; break; } } // no match, fix last index if (!cmatch) { col--; } // find insert position var p, match = false, pos = 0, c = portal.items.itemAt(col), items = c.items.items; for (var len = items.length; pos < len; pos++) { p = items[pos]; var h = p.el.getHeight(); if (h !== 0 && (p.el.getY() + (h / 2)) > xy[1]) { match = true; break; } } var overEvent = this.createEvent(dd, e, data, col, c, match && p ? pos : c.items.getCount()); if (portal.fireEvent('validatedrop', overEvent) !== false && portal.fireEvent('beforedragover', overEvent) !== false) { // make sure proxy width is fluid px.getProxy().setWidth('auto'); if (p) { px.moveProxy(p.el.dom.parentNode, match ? p.el.dom : null); } else { px.moveProxy(c.el.dom, null); } this.lastPos = { c : c, col : col, p : match && p ? 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; var 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) { dd.proxy.getProxy().remove(); dd.panel.el.dom.parentNode.removeChild(dd.panel.el.dom); if (pos !== false) { c.insert(pos, dd.panel); } else { c.add(dd.panel); } /** * 取得当前portlet在portal column中的索引 */ var index = 0; var portletId = dd.panel.id; if (pos != false) { var portlets = c.items; for (var i = 0; i < portlets.length; i++) { if (c.items.itemAt(i).id === portletId) { index = i; break; } } } else { if (pos.toString() == '0') { index = 0; } else { index = c.items.length - 1; } } c.doLayout(); //更新移动后的Portlet var params ={ id : dd.panel.id, columnid:c.id, forder : index }; indexportalService.movePortlet(params); 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; }, // internal cache of body and column coords getGrid : function() { var box = this.portal.bwrap.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.ux.Portal.DropZone.superclass.unreg.call(this); }});