版权声明:模糊查询js代码部分引用原生zTree官方代码,任何商业应用请联系zTree官方。
先上一下效果图:
技术要求:点击input标签或者打开遮罩层按钮时,弹出zTree页面;zTree页面中在关键字后面的input输入框输入搜索信息后,zTree关键字高亮显示,并关闭其他子节点!
zTree版本要求:
ztree v3.5.19.1及以上,使用到getPath()方法
ztree.exhide扩展,使用到hideNode()方法
1. CSS、jQuery等底层框架选择:
CSS部分:bootstrap3x,部分CSS用到了layui的样式、zTree样式采用metroStyle
jQuery:jQuery3.3.1
2.代码:
2.1 html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- Bootstrap core CSS -->
<link rel="icon" href="js/bootstrap/favicon.ico">
<link rel="stylesheet" href="js/bootstrap/css/bootstrap.css">
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<link href="js/bootstrap/assets/css/ie10-viewport-bug-workaround.css" rel="stylesheet">
<link rel="stylesheet" href="js/zTree_v3/css/metroStyle/metroStyle.css">
<link rel="stylesheet" href="js/layui/css/modules/layer/default/layer.css">
<script src="js/jquery-3.3.1.js"></script>
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Just for debugging purposes. Don't actually copy these 2 lines! -->
<!--[if lt IE 9]>
<script src="js/bootstrap/assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
<script src="js/bootstrap/assets/js/ie-emulation-modes-warning.js"></script>
<script src="js/bootstrap/js/bootstrap.js"></script>
<!-- Just to make our placeholder images work. Don't actually copy the next line! -->
<script src="js/bootstrap/assets/js/vendor/holder.min.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="js/bootstrap/assets/js/ie10-viewport-bug-workaround.js"></script>
<script src="js/zTree_v3/js/jquery.ztree.core.js"></script>
<script src="js/zTree_v3/js/jquery.ztree.exhide.js"></script>
<!-- 引入zTree 模糊查询JS文件 -->
<script src="js/js/fuzzySearch.js"></script>
<style>
.col-center-block {
/** -ms代表ie内核识别码
* -moz代表火狐内核识别码
* -webkit代表谷歌内核识别码
* -o代表欧朋【opera】内核识别码
*/
position: absolute;
top: 50%;
-webkit-transform: translateY(-50%);
-moz-transform: translateY(-50%);
-ms-transform: translateY(-50%);
-o-transform: translateY(-50%);
transform: translateY(-50%);
}
.treeShowHideButton {
position: absolute;
right: 8px;
top: 2px;
font-size: 12px;
color: #333;
z-index: 3;
}
.treeShowHideButton label {
cursor: pointer;
}
.treeSearchInput {
padding: 13px 0 0 20px;
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
font-size: 14px;
line-height: 1.42857143;
color: #333;
}
.treeSearchInput label {
padding: 5px 0 3px 0;
font-size: 13px;
font-weight: normal;
vertical-align: middle;
display: inline-block;
max-width: 100%;
margin-bottom: 5px;
font-weight: 700;
}
.treeSearchInput input {
width: 145px;
vertical-align: middle;
line-height: 24px;
height: 26px;
border: 1px solid #bbb;
padding: 0 4px;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
.treeSearchInput button {
border: 1px solid #bbb;
vertical-align: middle;
height: 26px;
height: 26px\9;
font-size: 13px;
background: #efefef;
padding: 0 8px;
}
.treeSearchInput .btn {
border-radius: 3px;
-webkit-box-shadow: none;
box-shadow: none;
border: 1px solid transparent;
}
.layui-layer-content {
height: 306px;
position: relative;
}
.layui-layer-title {
font-weight: bold;
font-size: 15px;
background: #fff;
height: 45px;
line-height: 45px;
padding: 0 80px 0 20px;
border-bottom: 1px solid #eee;
color: #333;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
border-radius: 2px 2px 0 0;
}
</style>
<script>
var zTreeObj;
// zTree 的参数配置,深入使用请参考 API 文档(setting 配置详解)
var setting = {
check: {
enable: true//checkbox
},
view: {
nameIsHTML: true, //允许name支持html
selectedMulti: false
},
edit: {
enable: false,
editNameSelectAll: false
},
// 回调定义
callback:{
// 鼠标点击事件的回调函数
onClick:zTreeOnClick
},
// zTree data格式定义
data:{
keep:{
leaf:true,
parent:true
},
key:{
isParent:"treeLeaf"
},
simpleData:{
enable:true,
idKey:"id",
pIdKey:"pId",
rootPid:"0"
}
}
};
// zTree 的数据属性,深入使用请参考 API 文档(zTreeNode 节点数据详解)
var nodes = [
{id:1, pId:0, name: "父节点1"},
{id:11, pId:1, name: "子节点1"},
{id:12, pId:1, name: "子节点2","treeLeaf":"true"}
];
//zTree 节点单击回调函数
function zTreeOnClick(event, treeId, treeNode) {
alert(treeNode.tId + ", " + treeNode.name);
};
$(function () {
//input标签打开遮罩层
$("#demoInput").on("click" , function () {
// 其实就是调用了 打开遮罩层 按钮的鼠标单击事件
$("#demoButton").click();
});
//关闭按钮
$("#closeBtn").on("click" , function () {
// 调用 activeClose 标签的 鼠标单击事件
$("#activeClose").click();
});
//搜索框
// $("#searchInput").bind("input" , zTreeSearch);
$("#searchBtn").on("click" , function () {
fuzzSearch('treeDemo','#searchInput',null,true); //初始化模糊搜索方法
});
//zTree加载
zTreeObj = $.fn.zTree.init($("#treeDemo"), setting, nodes);
zTreeObj.expandAll(true);
fuzzSearch('treeDemo','#searchInput',null,true); //初始化模糊搜索方法
});
</script>
</head>
<body>
<div class="container-fluid text-center">
<h2>遮罩层DEMO</h2>
<!-- 按钮触发模态框 -->
<input type="text" id="demoInput"/>
<button class="btn btn-primary btn-lg" id="demoButton" data-toggle="modal" data-target="#myModal">
打开遮罩层
</button>
<!-- 模态框(Modal) -->
<div class="col-lg-4 col-lg-offset-4 col-sm-6 col-sm-offset-3 col-xs-8 col-xs-offset-2 container col-center-block modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog" >
<div class="modal-content" style="width: 300px;height: 400px">
<!-- Top 标题-->
<div class="layui-layer-title" style="cursor: move">
zTree 遮罩弹出 Demo
</div>
<span class="layui-layer-setwin">
<!-- <a class="layui-layer-min" href="javascript:;">
<cite></cite>
</a>
<a class="layui-layer-ico layui-layer-max" href="javascript:;"></a>-->
<a class="layui-layer-ico layui-layer-close layui-layer-close1" id="closeBtn" href="javascript:void(0);"></a>
</span>
<!-- Middle 内容区-->
<div class="layui-layer-content">
<div class="treeSearchInput" id="search" style="display: block">
<label for="searchInput">关键字:</label>
<input type="text" id="searchInput" maxlength="50" class="empty"/>
<button class="btn" id="searchBtn" >搜索</button>
</div>
<div id="treeDemo" class="ztree"></div>
</div>
<div class="modal-footer layui-layer-btn">
<button type="button" class="btn btn-default" data-dismiss="modal" id="activeClose">关闭
</button>
<button type="button" class="btn btn-primary">
提交更改
</button>
</div>
</div>
<!-- /.modal-content -->
</div>
</div>
</body>
</html>
2.2 zTree模糊查询js代码:
/**
*
* @param zTreeId ztree对象的id,不需要#
* @param searchField 输入框选择器
* @param isHighLight 是否高亮,默认高亮,传入false禁用
* @param isExpand 是否展开,默认合拢,传入true展开
*/
function fuzzSearch(zTreeId, searchField, isHighLight, isExpand){
//get the ztree object by ztree id
var zTreeObj = $.fn.zTree.getZTreeObj(zTreeId);
//get the key of the node name
var nameKey = zTreeObj.setting.data.key.name;
isHighLight = isHighLight===false?false:true;//default true, only use false to disable highlight
isExpand = isExpand?true:false; // not to expand in default
zTreeObj.setting.view.nameIsHTML = isHighLight; //allow use html in node name for highlight use
var metaChar = '[\\[\\]\\\\\^\\$\\.\\|\\?\\*\\+\\(\\)]'; //js meta characters
var rexMeta = new RegExp(metaChar, 'gi');//regular expression to match meta characters
// keywords filter function
function ztreeFilter(zTreeObj,_keywords,callBackFunc) {
if(!_keywords){
_keywords =''; //default blank for _keywords
}
// function to find the matching node
function filterFunc(node) {
if(node && node.oldname && node.oldname.length>0){
node[nameKey] = node.oldname; //recover oldname of the node if exist
}
zTreeObj.updateNode(node); //update node to for modifications take effect
if (_keywords.length == 0) {
//return true to show all nodes if the keyword is blank
zTreeObj.showNode(node);
zTreeObj.expandNode(node,isExpand);
return true;
}
//transform node name and keywords to lowercase
if (node[nameKey] && node[nameKey].toLowerCase().indexOf(_keywords.toLowerCase())!=-1) {
if(isHighLight){ //highlight process
//a new variable 'newKeywords' created to store the keywords information
//keep the parameter '_keywords' as initial and it will be used in next node
//process the meta characters in _keywords thus the RegExp can be correctly used in str.replace
var newKeywords = _keywords.replace(rexMeta,function(matchStr){
//add escape character before meta characters
return '\\' + matchStr;
});
node.oldname = node[nameKey]; //store the old name
var rexGlobal = new RegExp(newKeywords, 'gi');//'g' for global,'i' for ignore case
//use replace(RegExp,replacement) since replace(/substr/g,replacement) cannot be used here
node[nameKey] = node.oldname.replace(rexGlobal, function(originalText){
//highlight the matching words in node name
var highLightText =
'<span style="color: whitesmoke;background-color: darkred;">'
+ originalText
+'</span>';
return highLightText;
});
zTreeObj.updateNode(node); //update node for modifications take effect
}
zTreeObj.showNode(node);//show node with matching keywords
return true; //return true and show this node
}
zTreeObj.hideNode(node); // hide node that not matched
return false; //return false for node not matched
}
var nodesShow = zTreeObj.getNodesByFilter(filterFunc); //get all nodes that would be shown
processShowNodes(nodesShow, _keywords);//nodes should be reprocessed to show correctly
}
/**
* reprocess of nodes before showing
*/
function processShowNodes(nodesShow,_keywords){
if(nodesShow && nodesShow.length>0){
//process the ancient nodes if _keywords is not blank
if(_keywords.length>0){
$.each(nodesShow, function(n,obj){
var pathOfOne = obj.getPath();//get all the ancient nodes including current node
if(pathOfOne && pathOfOne.length>0){
//i < pathOfOne.length-1 process every node in path except self
for(var i=0;i<pathOfOne.length-1;i++){
zTreeObj.showNode(pathOfOne[i]); //show node
zTreeObj.expandNode(pathOfOne[i],true); //expand node
}
}
});
}else{ //show all nodes when _keywords is blank and expand the root nodes
var rootNodes = zTreeObj.getNodesByParam('level','0');//get all root nodes
$.each(rootNodes,function(n,obj){
zTreeObj.expandNode(obj,true); //expand all root nodes
});
}
}
}
//listen to change in input element
$(searchField).bind('input propertychange', function() {
var _keywords = $(this).val();
searchNodeLazy(_keywords); //call lazy load
});
var timeoutId = null;
var lastKeyword = '';
// excute lazy load once after input change, the last pending task will be cancled
function searchNodeLazy(_keywords) {
if (timeoutId) {
//clear pending task
clearTimeout(timeoutId);
}
timeoutId = setTimeout(function() {
if (lastKeyword === _keywords) {
return;
}
ztreeFilter(zTreeObj,_keywords); //lazy load ztreeFilter function
// $(searchField).focus();//focus input field again after filtering
lastKeyword = _keywords;
}, 500);
}
}
来源:CSDN
作者:mr_foxsand
链接:https://blog.csdn.net/mr_foxsand/article/details/104087657