后台 树 节点 定义
menu_info { menu_id (0x500), // 本id menu_parent_id (0x501), //父亲id menu_title (0x502), menu_action (0x503), menu_nextId (0x504), //兄弟id menu_isleaf (0x507), // 是否叶子节点 menu_roles (0x508) }
关键是为了存放同级节点之间的顺序关系 ,而引入 兄弟节点 next ,这样的话,可以在处理拖放的时候,更新相应的 next 和 parent 就行了 ,没有使用 treeeditor,因为树节点的卫星数据太多了,还是window操作
后台只要处理 drop ,add ,del edit ,get 操作,返回 AsyncNode 对应数据,则ext 树自动界面变更,后台关键要维护好 链结构
/* 示例代码 , 全部使用 全局变量(不建议),请在产品中修改为局部变量 */ function initTree() { window.tree = new Ext.tree.TreePanel({ useArrows: true, autoScroll: true, animate: true, enableDD: true, containerScroll: true, border: false, // auto create TreeLoader dataUrl: 'menu/get-menus.jsp', listeners: { 'beforemovenode': function (tree, node, oldParent, newParent, index) { //alert(node.text + " before move from " + oldParent.text + " to " + newParent.text + " index " + index); //操作的遮罩层 if (!window.treeLoadMask) { window.treeLoadMask = new Ext.LoadMask(window.tree.body, { msg: "处理中" }); } window.treeLoadMask.show(); var oldC = (oldParent.childNodes); var indexI = oldC.indexOf(node); //alert(indexI); //(1) 拖放节点 的 下一个节点,父节点改变 var menuIdOwer = node.id; var menuNewParentId = newParent.id; //(2) 拖放前 拖放节点的上一个节点 的 下一个指向改变 var menuOldPreId = ''; var menuOldPreNext = ''; if (indexI != 0) { menuOldPreId = oldC[indexI - 1].id; } if (indexI + 1 != oldC.length) { menuOldPreNext = oldC[indexI + 1].id; } else { menuOldPreNext = 'node-1'; } var newC = newParent.childNodes; //(3) 拖放后 ,新的兄弟节点 指向也要改变 var menuNewNextId = ''; var menuNewPreId = ''; var menuNewPreNext = ''; if (newC.length == index) menuNewNextId = 'node-1'; else menuNewNextId = newC[index].id; if (index != 0) { menuNewPreId = newC[index - 1].id; menuNewPreNext = node.id; } var conn = new Ext.data.Connection(); // 发送异步请求 conn.request({ // 请求地址 url: 'menu/update-menus.jsp', method: 'post', params: { 'menuIdOwer': menuIdOwer, 'menuNewParentId': menuNewParentId, 'menuNewNextId': menuNewNextId, 'menuOldPreId': menuOldPreId, 'menuOldPreNext': menuOldPreNext, 'menuNewPreId': menuNewPreId, 'menuNewPreNext': menuNewPreNext }, // 指定回调函数 callback: callback }); //回调函数 function callback(options, success, response) { if (success) { try { var jsonObj = Ext.util.JSON.decode(response.responseText); } catch(e) {} if (jsonObj && jsonObj.success) {} else alert(response.responseText); } else { alert(response.responseText); } window.treeLoadMask.hide(); } }, 'contextmenu': function (n, ee) { if (!window.treerowcontextmenu_) { window.treerowcontextmenu_ = Ext.menu.MenuMgr.get({ id: 'treerowcontextmenu_-ctx', items: [{ text: '刷新子节点', iconCls: 'blist', handler: function () { if (!window.tree.getSelectionModel().getSelectedNode().leaf) window.tree.getSelectionModel().getSelectedNode().reload(); } }, { text: '添加标题', iconCls: 'blist', handler: function () { var node = window.tree.getSelectionModel().getSelectedNode(); if (node.leaf) { Ext.Msg.alert('禁止', '该节点不是目录'); return; } Ext.getCmp('add_menu_parent_id').setValue(node.id.substring(4)); var oldC = (node.childNodes); var next_id = -1; if (oldC && oldC.length != 0) next_id = oldC[0].id.substring(4); Ext.getCmp('add_menu_next_id').setValue(next_id); window.treeAddwin.cur_node = node; node.expand(false, true, function () { window.treeAddwin.show() }); } }, { text: '修改标题', iconCls: 'blist', handler: function () { var node = window.tree.getSelectionModel().getSelectedNode(); Ext.getCmp('edit_menu_id').setValue(node.id.substring(4)); Ext.getCmp('edit_menu_title').setValue(node.text); Ext.getCmp('edit_menu_action').setValue(node.attributes.href); Ext.getCmp('edit_menu_roles').setValue(node.attributes.menu_roles); window.treeEditwin.curNode = node; window.treeEditwin.show(); } }, { text: '删除节点', iconCls: 'blist', handler: function () { //操作的遮罩层 var node = window.tree.getSelectionModel().getSelectedNode(); node.expand(false, true, function () { if (node.firstChild || !node.parentNode) { alert('还有子节点呢'); return; } if (!confirm('确认删除?')) { return; } if (!window.treeLoadMask) { window.treeLoadMask = new Ext.LoadMask(window.tree.body, { msg: "处理中" }); } window.treeLoadMask.show(); var pre = node.previousSibling; var post = node.nextSibling; var pre_id = ''; var pre_next_id = ''; if (pre) { pre_id = pre.id.substring(4); if (post) pre_next_id = post.id.substring(4); else pre_next_id = -1; } var conn = new Ext.data.Connection(); // 发送异步请求 conn.request({ // 请求地址 url: 'menu/del-menu.jsp', method: 'post', params: { 'del_menu_id': node.id.substring(4), 'pre_id': pre_id, 'pre_next_id': pre_next_id }, // 指定回调函数 callback: callback }); //回调函数 function callback(options, success, response) { if (success) { try { var jsonObj = Ext.util.JSON.decode(response.responseText); } catch(e) {} if (jsonObj && jsonObj.success) { node.parentNode.removeChild(node); } else alert(response.responseText); } else { alert(response.responseText); } window.treeLoadMask.hide(); } }); } }] }); } window.tree.getSelectionModel().select(n); window.treerowcontextmenu_.showAt(ee.getXY()); ee.preventDefault(); } }, root: { nodeType: 'async', text: '(支持,右键,拖放)', draggable: false, id: 'node-1', singleClickExpand: true, leaf: false, expandable: true } }); /* window.treeEditer = new Ext.tree.TreeEditor( window.tree, {allowBlank: false}); window.treeEditer.on("complete", function(treeEditer, value, ovalue) { //alert(value); }); */ window.treeAddForm = new Ext.FormPanel({ //width: 500, //labelWidth:70, //width: 560, baseCls: 'x-plain', method: 'POST', autoHeight: true, autoWidth: true, bodyStyle: 'padding:0 10px 0;', url: 'menu/add-menu.jsp', //frame:true, //animCollapse:true, defaultType: 'textfield', items: [{ xtype: 'hidden', name: 'menu_parent_id', id: 'add_menu_parent_id' }, { xtype: 'hidden', name: 'menu_next_id', id: 'add_menu_next_id' }, { fieldLabel: '标题', allowBlank: false, name: 'menu_title', id: 'add_menu_title' }, { fieldLabel: '动作', name: 'menu_action', id: 'add_menu_action' }, { fieldLabel: '权限', allowBlank: false, name: 'menu_roles', id: 'add_menu_roles' }, { checked: true, fieldLabel: '类型', xtype: 'radio', boxLabel: '节点', name: 'menuIsLeaf', inputValue: '1', id: 'add_menuIsLeaf' }, { fieldLabel: '', xtype: 'radio', labelSeparator: '', boxLabel: '目录', name: 'menuIsLeaf', inputValue: '0' }], buttons: [{ text: '确定', handler: function () { if (treeAddForm.form.isValid()) { if (!window.treeLoadMask) { window.treeLoadMask = new Ext.LoadMask(window.tree.body, { msg: "处理中" }); } window.treeLoadMask.show(); treeAddForm.form.submit({ url: 'menu/add-menu.jsp', success: function (form, action) { var before = null; var oldC = (window.treeAddwin.cur_node.childNodes); if (oldC && oldC.length != 0) before = oldC[0]; var newNode = new Ext.tree.AsyncTreeNode({ leaf: Ext.getCmp('add_menuIsLeaf').getValue() == '1', text: Ext.getCmp('add_menu_title').getValue(), href: Ext.getCmp('add_menu_action').getValue(), id: 'node' + action.result.new_menu_id, nodeType: 'async', expandable: Ext.getCmp('add_menuIsLeaf').getValue() == '0' }); window.treeAddwin.cur_node.insertBefore(newNode, before); window.treeLoadMask.hide(); window.treeAddwin.hide(); }, failure: function (form, action) { Ext.Msg.alert('失败', action.result.error); window.treeLoadMask.hide(); window.treeAddwin.hide(); }, waitMsg: '添加中', waitTitle: '请等待' }); } else {} } }] }); window.treeAddwin = new Ext.Window({ //width : 500, //height : 300, layout: 'fit', title: '添加树结点', //frame:true, items: treeAddForm, bodyStyle: 'padding:5px;', closeAction: 'hide', renderTo: document.body }); window.treeEditForm = new Ext.FormPanel({ //width: 500, //labelWidth:70, //width: 560, baseCls: 'x-plain', method: 'POST', autoHeight: true, autoWidth: true, bodyStyle: 'padding:0 10px 0;', url: 'menu/edit-menu.jsp', //frame:true, //animCollapse:true, defaultType: 'textfield', items: [{ xtype: 'hidden', name: 'edit_menu_id', id: 'edit_menu_id' }, { fieldLabel: '标题', allowBlank: false, name: 'edit_menu_title', id: 'edit_menu_title' }, { fieldLabel: '动作', name: 'edit_menu_action', id: 'edit_menu_action' }, { fieldLabel: '权限', allowBlank: false, name: 'edit_menu_roles', id: 'edit_menu_roles' }], buttons: [{ text: '确定', handler: function () { if (treeEditForm.form.isValid()) { if (!window.treeLoadMask) { window.treeLoadMask = new Ext.LoadMask(window.tree.body, { msg: "处理中" }); } window.treeLoadMask.show(); treeEditForm.form.submit({ url: 'menu/edit-menu.jsp', success: function (form, action) { var node = window.treeEditwin.curNode; node.setText(Ext.getCmp('edit_menu_title').getValue()); node.attributes.menu_roles = Ext.getCmp('edit_menu_roles').getValue(); node.attributes.href = Ext.getCmp('edit_menu_action').getValue(); node.getUI().getAnchor().setAttribute('href', node.attributes.href); window.treeLoadMask.hide(); window.treeEditwin.hide(); }, failure: function (form, action) { Ext.Msg.alert('失败', action.result.error); window.treeLoadMask.hide(); }, waitMsg: '添加中', waitTitle: '请等待' }); } else {} } }] }); window.treeEditwin = new Ext.Window({ //width : 500, //height : 300, layout: 'fit', title: '修改树结点', //frame:true, items: treeEditForm, bodyStyle: 'padding:5px;', closeAction: 'hide', renderTo: document.body }); }