前几天项目中有个需求,需要在select 框中加载一个两层的树(树本身是无线级,但需求是根节点及根节点的下级节点)。
具体样式如图:
这里因为采用异步加载树,所以使用Ztree 进行开发,完成后效果如上图。
整个开发过程还是有点繁琐的,下边将所作的做一个整理。
引入ztree 插件省略。。。
界面html 代码,构建select 元素
js 渲染ztree组件:
$(document).ready(function() {
initStoreTree();
});
//请求数据
function initStoreTree(){
$.ajax({
method : 'post',
url : '${ctxPath}/store/management/getList',
data : {"pid" : 0 },
success : function(res) {
var zNodes = JSON.parse(res);
for ( var i in zNodes) {
zNodes[i].isParent = true;//默认都是父节点(都有子节点)
}
initSelectTree("PDEPT_KEY",zNodes);
}
})
}
//渲染组件 固定方法
function initSelectTree(id,zNodes) {
var setting = {
data: {
simpleData: {
enable: true
}
},
callback: {
onClick: onClick,//点击名称触发(选中)
onExpand:zTreeOnExpand//点击“+”出发(伸缩展开)
}
};
var html = '' +
'' +
'' +
'';
$("#" + id).append(html);
$("#" + id).append('
');
$("#" + id).bind("click", function () {
if ($(this).parent().find(".tree-content").css("display") !== "none") {
} else {
$(this).addClass("layui-form-selected");
var Offset = $(this).offset();
var width = $(this).width() - 2 - 15;
$(this).parent().find(".tree-content").css({
left: Offset.left + "px",
top: Offset.top + $(this).height() + "px",
height: 250 + "px",
}).slideDown("fast");
$(this).parent().find(".tree-content").css({
width: width,
});
$("body").bind("mousedown", onBodyDown);
}
});
$.fn.zTree.init($("#" + id + "Tree"), setting, zNodes);
hideMenu();
}
function zTreeOnExpand(event, treeId, treeNode) {
if(treeNode.level < 1){
getChildNodes(treeNode,null);
} else {
Dialog.warn("只需选定前两级库房名称!");
}
}
function onClick(event, treeId, treeNode) {
var zTree = $.fn.zTree.getZTreeObj("PDEPT_KEYTree");
var pName = treeNode.getParentNode().name;
if (zTree.setting.check.enable == true) {
zTree.checkNode(treeNode, !treeNode.checked, false)
assignment(treeId, zTree.getCheckedNodes(),pName);
} else {
assignment(treeId, zTree.getSelectedNodes(),pName);
hideMenu();
}
}
function hideMenu() {
$(".select-tree").removeClass("layui-form-selected");
$(".tree-content").fadeOut("fast");
$("body").unbind("mousedown", onBodyDown);
}
function assignment(treeId, nodes,pName) {
var names = "";
var ids = "";
for (var i = 0, l = nodes.length; i < l; i++) {
names += nodes[i].name + ",";
ids += nodes[i].id + ",";
}
if (names.length > 0) {
names = names.substring(0, names.length - 1);
ids = ids.substring(0, ids.length - 1);
}
treeId = treeId.substring(0, treeId.length - 4);
//if(pName != "" || pName !=null){
//为input组件设置属性 value/name/对应字段为王后台提交的字段
$("#" + treeId + "Show").attr("value", pName+"-"+names);//此处的pName 为父节点名称,这里选中子节点需要带出父节点名称,如不需要可以不做设置。
$("#" + treeId + "Show").attr("name", "storeName");
$("#" + treeId + "Hide").attr("value", ids);
//}
}
function onBodyDown(event) {
if ($(event.target).parents(".tree-content").html() == null) {
hideMenu();
}
}
function getChildNodes(treeNode,newnode) {
var treeObj = $.fn.zTree.getZTreeObj("PDEPT_KEYTree");
var param = 0;
if(treeNode != null){//子元素操作
if(treeNode.p_id != null){
param = treeNode.p_id;
}
}else{//顶级元素操作
if(param == 0 && newnode != null){//添加顶级节点
newnode.isParent = true;//默认都是父节点(都有子节点)
treeObj.addNodes(null, newnode, true);
return;
}
}
var parentZNode = treeObj.getNodeByParam("sid", treeNode.sid, null);//获取指定父节点
var childNodes = treeObj.transformToArray(treeNode);//获取子节点集合
//子节点已加载过一次,无需再次加载
if (childNodes.length > 1) {
if (newnode != null) {//有新写入的元素
if (childNodes.length == 2) {//长度为2 且有noChildPoint(暂无下级阶元)时需重新加载
for ( var i in childNodes) {
if (childNodes[i].name == noChildPoint) {
treeObj.removeNode(childNodes[i]); //移除"noChildPoint(暂无下级节点)"
}
}
}
newnode.isParent = true;//默认都是父节点(都有子节点)
treeObj.addNodes(parentZNode, newnode, false); //添加节点
}
return;
}
//子节点第一次加载
$.ajax({
method : 'post',
url : '${ctxPath}/store/management/getList',
data : {
"pid" : treeNode.sid
},
success : function(res) {
var data = JSON.parse(res);
if (data == null || data == '') {//无下级节点
data = [ {
sid : 'no',
p_id : treeNode.sid,
name : noChildPoint,
} ];
} else {//有下级节点
for ( var i in data) {
data[i].isParent = true;//默认都是父节点
}
}
treeObj.addNodes(parentZNode, data, false); //添加节点
}
})
}
最终展示效果: