打造遮罩弹出带有搜索框的zTree页面

版权声明:模糊查询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);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值