后台树节点定义
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
});
}
本文介绍了一种基于ExtJS的后台树形结构实现方法,通过定义树节点的数据结构和操作方式,实现了节点的拖拽、添加、编辑和删除等功能。文章详细展示了如何利用JavaScript和ExtJS框架来维护树形结构的一致性和正确性。
146

被折叠的 条评论
为什么被折叠?



