今天遇到需求给ztree加搜索功能,要求搜到的展开,没搜到的隐藏
核心js,下面2个function就实现了功能
function copyForestTreeNodeChildrenToAnotherForest(srcForest,tgtForest){
if(!srcForest){
throw "Source Forest not empty!";
}
let j = 0;
for(let i=0;iif(!srcForest[i]||!srcForest[i].name)continue;
tgtForest[j] = {};
tgtForest[j].name = srcForest[i].name;
if(!!srcForest[i].children
&& srcForest[i].children.length>0){
tgtForest[j].children = [];
copyForestTreeNodeChildrenToAnotherForest(srcForest[i].children,tgtForest[j].children);
}
j++;}
}function ztreeForestNodesFilterByNameFuzzily(nodes,searchedNodes,searchingMsg){
if(!nodes||nodes.length==0){
throw "Searching nodes are not empty!";
}
let j = 0;
for(let i=0;iif(!nodes[i]||!nodes[i].name)continue;// filter name empty node;
let tempNode = {};
// firstly,if name contains msg,into the list for output.
if(nodes[i].name.toLowerCase().indexOf(searchingMsg.toLowerCase()) >-1){
tempNode.name = nodes[i].name;
}if(nodes[i].children && nodes[i].children.length>0){
tempNode.children = [];
ztreeForestNodesFilterByNameFuzzily(nodes[i].children,tempNode.children,searchingMsg);
}
if(!!tempNode.children&&tempNode.children.length > 0){
tempNode.open = true;
// if children and father's name empty,it must have father node;
if(!tempNode.name){
tempNode.name = nodes[i].name;
}
}// if nodes[i] contains children and the children are not
// satisfy searching condition,
// keeping its children to the list for output,but not expanded.
if(!!nodes[i].children
&&nodes[i].children.length>0
&&!!tempNode.children
&&tempNode.children.length <= 0){
tempNode.open = false;
copyForestTreeNodeChildrenToAnotherForest(nodes[i].children,tempNode.children);
}if(!!tempNode.children
&&tempNode.children.length <= 0){
tempNode.children = null;
}if(!!tempNode.name){
searchedNodes[j] = tempNode;
j++;
}
}
}
然后对接后端,发现上面两个js只能使用ztree型的数据源,但是后端给我们的是json型的数据源
如果没有转换数据源,那么会造成这种结果,识别不出来目录,全变成文件了
那么使用下面这个函数转换一下就行了,注意name是数据源内容,pid是parent,注意结合自己项目更改一下。
//树数据源扁平结构转嵌套
function FlatToNested(data, opt) {
opt = opt || {};
var idFiled = opt.idFiled || 'id';
var textFiled = opt.textFiled || 'name'; //修改
var parentField = opt.parentField || 'pid'; //修改
var i, l, zTreeNode = [], tmpMap = [];
if (!data) return zTreeNode;
for (i = 0, l = data.length; i < l; i++) tmpMap[data[i][idFiled]] = data[i];
for (i = 0, l = data.length; i < l; i++) {
if (tmpMap[data[i][parentField]] && data[i][idFiled] != data[i][parentField]) {
if (!tmpMap[data[i][parentField]]['children'])
tmpMap[data[i][parentField]]['children'] = [];
data[i]['text'] = data[i][textFiled];
tmpMap[data[i][parentField]]['children'].push(data[i]);
} else {
data[i]['text'] = data[i][textFiled];
zTreeNode.push(data[i]);
}
}
return zTreeNode;
}
然后我们就可以对接后端了,定义一个全局变量zTreeNode接收后端的json转换的ztree型数据源
var zTreeNode
function loadNodeData(){
$.ajax({
url: "../dataLabel/queryAllDataCatsTree.action?ran="+Math.random(),
dataType: "json",
type: "get",
success: function (data) {
var t = $("#dataCatsTree");
$.fn.zTree.init(t, setting, data);
//把后端传来的json数据源转换为ztree型数据源
zTreeNode = FlatToNested(data, 0);
var t = $("#dataCatsTree");
$.fn.zTree.init(t, setting, data);
}
});
}
然后在html里面加搜索的input框。
最后写oninput的js事件
//输入框改变事件,执行搜索
function ztree_search_nodes(){
var searchingMsg = $("#searchBox").val();
var treeObj = $.fn.zTree.getZTreeObj("dataCatsTree");
treeObj.destroy();
if(!searchingMsg){
$.fn.zTree.init($("#dataCatsTree"), setting, zTreeNode);
}
else{
var searchedNodes = [];
ztreeForestNodesFilterByNameFuzzily(zTreeNode,searchedNodes,searchingMsg);
$.fn.zTree.init($("#dataCatsTree"), setting, searchedNodes);
}
}
效果
最后奉上ztree数据源转json格式的代码(如果要用的话)