先说几个要点:
- 需求是实现树的拖拽,并且只能是兄弟节点之间的拖拽,而且如果不能拖拽时,要不显示出能拖拽标识;默认展开第一个父级节点(这里的数据结构是:一级分类--父级分类--叶子节点)
-
beforeDrag: 用于捕获节点被拖拽之前的事件回调函数,并且根据返回值确定是否允许开启拖拽操作。
-
beforeDrop:用于捕获节点拖拽操作结束之前的事件回调函数,并且根据返回值确定是否允许此拖拽操作。
-
onDrop:用于捕获节点 拖拽操作结束 的事件回调函数。
5.onAsyncSuccess:用于捕获异步加载正常结束的事件回调函数。
- 以上(beforeDrag,beforeDrop,onDrop,onAsyncSuccess, prev,next)的callback执行顺序:
beforeDrag > dropNext、dropPrev > beforeDrop > onDrop
var _zTree = {
tree: null,
beforeDrag: function(treeId, treeNodes){
for(var i = 0, l = treeNodes.length; i < l; i++){
if(treeNodes[i].drag === false){
return false;
}else if(treeNodes[i].parentTId && treeNodes[i].getParentNode().childDrag === false){
return false;
}
}
return true;
},
beforeDrop: function(treeId, treeNodes, targetNode, moveType){
var moveNode = treeNodes[0];
switch(moveType){
case 'prev':
case 'next':
if(moveNode.pId == targetNode.pId){
return true;
}
break;
}
return false;
},
zTreeOnDrop: function(event, treeId, treeNodes, targetNode, moveType){
var moveNode = treeNodes[0];
//这里控制一下,一级分类以及父级节点不能拖动(只有叶子节点可以)
if(moveNode.level > 1){
//确认移动之后,将其父级id记录下来
if(targetNode && moveNode.pId == targetNode.pId){
_orderSet.editAC.push(targetNode.pId);
_orderSet.editAC = _orderSet.editAC.distinct();
}
}
},
zTreeOnAsyncSuccess: function(event, treeId, treeNode, msg){
if(treeNode.isParent){
//isAC: 父级节点没有该属性,叶子节点才有该属性,这里需要默认展开一下第一个父级节点
_zTree._firstExpand(treeNode, treeNode.isAC ? false : true);
}
},
_firstShow: function(){
var nodes = this.tree.getNodes();
if(nodes && nodes.length > 0){
//展开所有第一次取回的节点
for(var i = 0; i < nodes.length; i++){
//默认展开第一个节点
this._firstExpand(nodes[i], true);
}
}
},
/**
* 展开节点
* @param node
* @param isRoot
* @private
*/
_firstExpand: function(node, isRoot){
var children = node.children;
if(children && children.length > 0 && isRoot){
this._firstExpand(children[0], false);
}
//展开没有展开的节点
if(!node.open){
this.tree.expandNodeOnly(node, true);
}
},
dropPrev: function(treeId, nodes, targetNode){
var moveNode = nodes[0];
//这里控制一下,一级分类以及父级节点不能拖动(只有叶子节点可以)
if(moveNode.level > 1){
//支持同一个父级节点下进行节点的拖拽排序,不可跨分类排序
if(moveNode.pId == targetNode.pId){
return true;
}
}
return false;
},
dropNext: function(treeId, nodes, targetNode){
var moveNode = nodes[0];
//这里控制一下,一级分类以及父级节点不能拖动(只有叶子节点可以)
if(moveNode.level > 1){
//支持同一个父级节点下进行节点的拖拽排序,不可跨分类排序
if(moveNode.pId === targetNode.pId){
return true;
}
}
return false;
},
};
setting: {
edit: {
drag: {
isCopy: false,
autoExpandTrigger: true,//拖拽时父节点自动展开是否触发 onExpand 事件回调函数。
prev: _zTree.dropPrev,//拖拽到目标节点时,设置是否允许移动到目标节点前面的操作。
inner: false,//拖拽到目标节点时,设置是否允许成为目标节点的子节点。[setting.edit.enable = true 时生效]拖拽目标是 根 的时候,不触发 prev 和 next,只会触发 inner
next: _zTree.dropNext//拖拽到目标节点时,设置是否允许移动到目标节点后面的操作。
},
enable: true,//设置 zTree 是否处于编辑状态,设置为true才能被拖拽
showRemoveBtn: false,
showRenameBtn: false
},
data: {
simpleData: {
enable: true
}
},
//异步加载
async: {
enable: true,//设置 zTree 是否开启异步加载模式
url: '*****/Tree.do?',//Ajax 获取数据的 URL 地址。
autoParam: ['catID', 'isAC'],//异步加载时需要自动提交父节点属性的参数。可以设置提交时的参数名称,例如 server 只接受 zId : ["id=zId"]
dataType: 'json'//Ajax 获取的数据类型。
},
callback: {
beforeDrag: _zTree.beforeDrag,//用于捕获节点被拖拽之前的事件回调函数,并且根据返回值确定是否允许开启拖拽操作
beforeDrop: _zTree.beforeDrop,//用于捕获节点拖拽操作结束之前的事件回调函数,并且根据返回值确定是否允许此拖拽操作。
onDrop: _zTree.zTreeOnDrop,//用于捕获节点 拖拽操作结束 的事件回调函数。
onAsyncSuccess: _zTree.zTreeOnAsyncSuccess//用于捕获异步加载正常结束的事件回调函数。
}
}
var _order = {
zNodes: [],
editAC: [],
init: function(){
this.initTree();
},
initTree: function(){
//获取数据
var _that = this;
$.ajax({
url: '********/Tree.do?',
async: false,
dataType: 'json',
success: function(data){
var _tree = $.fn.zTree.init($('#cTree'), _that.setting, data);
_zTree.tree = _tree || $.fn.zTree.getZTreeObj('cTree');
_zTree._firstShow();
}
});
},
};
(function(){
_orderSet.init();
})();
网友评论