zoukankan      html  css  js  c++  java
  • jstree树形菜单

    final 用于声明属性、方法和类,分别表示属性不可变,方法不可重写,类不可继承。
    其实可以参考用easyui的tree 和 ztree
    参考:
      https://www.jstree.com/demo/
      https://www.jstree.com/plugins/

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>菜单配置页面</title>
        <!-- css代码 -->
        <link rel="stylesheet" type="text/css" href="/css/bootstrap.min.css">
         <!-- <link rel="stylesheet" type="text/css" href="/css/default/style.min.css"> -->
        <style type="text/css">
        .demo {
             250px;
            margin: 0 17px 17px 0;
            float: left;
            border: 1px solid #ebebeb;
            height: 197px;
        }
        
        .last {
            margin-right: 0;
        }
        </style>
        <!-- 引入外部js -->
        <script type="text/javascript" src="/js/fe/jquery-2.1.4.min.js"></script>
        <script type="text/javascript" src="/js/fe/bootstrap.min.js"></script>
          <script type="text/javascript" src="/js/fe/jquery.jstree.js"></script>
        <script type="text/javascript" src="/js/fe/jquery.hotkeys.js"></script>
        <script type="text/javascript" src="/js/fe/jquery.cookie.js"></script>
         <script type="text/javascript" src="/js/fe/jstree.min.js"></script>
        <!-- js代码 -->
        <script type="text/javascript">
        // jQuery(document).ready(function() {
    
            $(function() {
                var selectRole = "";
                // 初始化jstree
                $("#menuTreeContainer").jstree({
                        "core": {
                            "strings": {
                                loading: "Loading ..."
                            }
                        },
                        "json_data": {
                            "ajax": {
                                "dataType": 'json',
                                // 使用ajax加载数据,如果和data同时使用则只在打开未加载的子节点时起作用
                                "url": "/config/queryAllMenuNodes.json",
                                "async": false,
                                "success": function(data) {
                                    if (data.success) {
                                        return  _callBack(data.content);
                                    }
                                }
                            }
                        },
                        "ui" : {
                            "initially_select" : []
                             },
                        "themes": {
                            "icons": false
                        },
                        "plugins": ["themes", "json_data", "ui","search"]
                    })
                    .bind("loaded.jstree", function(e, data) {
                        //初始打开第一个叶子节点所在目录
                         $("#menuTreeContainer").jstree("open_all");      
                    })
                    .bind("select_node.jstree", function(e, data) {
                        $("#currentPath").val(data.rslt.obj.data("path"));
                        $("#currentNode_id").val(data.rslt.obj.data("id"));
                        $("#currentNode_name").val(data.rslt.obj.data("name"));
                        $("#currParentPath").val(data.rslt.obj.data("parentPath"));
                    });
    
            });
    
        // });
    
    
        function _callBack(data) {
            var res = [],
                expIds = [],
                attr = {};
            jQuery.each(data, function(i) {
                var childData = data[i].children;
                if (!childData || jQuery.trim(childData).length == 0) {
                    childData = "";
                }
                // var state = "open";
                var href = "";
                var image = "";
                res.push({
                    "attr": {
                        "id": data[i].id
                    },
                    "data": {
                        "title": data[i].name
                    },
                    "children": _callBack(data[i].children),
                    "metadata": {
                        "id": data[i].id,
                        "name": data[i].name,
                        "parentId": data[i].parentId,
                        "path": data[i].path,
                        "parentPath": data[i].parentPath
                    },
                    // "state": state,
                    "icon": image
                });
    
            });
    
            return res;
        };
    
    
        function menuCreate() {
            var ref = $('#menuTreeContainer').jstree(true),
                sel = ref.get_selected();
            if (!sel.length) {
                return false;
            }
            sel = sel[0];
            sel = ref.create_node(sel, {
                "type": "file"
            });
            if (sel) {
                ref.edit(sel);
            }
        };
    
        function menuRename() {
            var ref = $('#menuTreeContainer').jstree(true),
                sel = ref.get_selected();
            if (!sel.length) {
                return false;
            }
            sel = sel[0];
            ref.edit(sel);
        };
    
    
        //打开/关闭所有节点
       var openAllNode = function(e) {
            $("#menuTreeContainer").jstree("open_all");
        }
    
        var hideAllNode = function(e) {
             $("#menuTreeContainer").jstree("close_all");
        }
    
        function showParentPath() {
            jQuery.ajax({
                dataType: 'json',
                type: 'POST',
                async: false,
                url: 'getMenuParentPath.json',
                data: param,
                success: function(data) {
                    if (data.success) {
                        _.each(data.content, function(v) {
                            jQuery("select[name=add-columnsecuritylevel-select]").append("<option value='" + v.code + "'>" + v.code + "</option>");
                            jQuery("select[name=modify-columnsecuritylevel-select]").append("<option value='" + v.code + "'>" + v.code + "</option>");
                        });
                    } else {
                        alert(data.message);
                    }
                }
            });
      }
    
      var modifyMenu =  function() {
    
        var nodeParentPath = $("#currParentPath").val(),
            nodeParentId=$("#currentNode_id").val(),
            nodeName=$("#currentNode_name").val();
    
            $("#nodeOpera_parentId").val($("#currentNode_id").val());
            $("#nodeOpera_parentPath").val($("#currentPath").val());
    
             jQuery.ajax({
                dataType: 'json',
                type: 'POST',
                url: 'modifyMenuTree.json',
                data: {
                    "nodeParentId":nodeParentId,
                    "nodeName":nodeName,
                    "nodeParentPath":nodeParentPath,
                    "type":"type"
                  },
                success: function(data) {
                    if (data.success) {
                       alert("修改成功");
                    } else {
                        alert(data.message);
                    }
                }
            });
      };
    
      var delMenuNode =  function() {
    
         var  nodeId=$("#currentNode_id").val();
    
              jQuery.ajax({
                dataType: 'json',
                type: 'POST',
                url: 'delMenuNode.json',
                data: {
                    "nodeId":nodeId,
                  },
                success: function(data) {
                    if (data.success) {
                        $("#menuTreeContainer").jstree("close_all");
                         $("#menuTreeContainer").jstree("open_all");
                       alert("删除成功");
                      
                    } else {
                        alert(data.message);
                    }
                }
            });
      };
    
        var addSubNode =  function() {
    
            $("#nodeOpera_path").val($("#currentPath").val() +"-"+ $("#nodeOpera_name").val());
            $("#nodeOpera_parentPath").val($("#currentPath").val());
             var nodeName = $("#nodeOpera_name").val();
            var nodeParentId = $("#currentNode_id").val();
            var nodePath=$("#nodeOpera_path").val();
             var parentPath = $("#nodeOpera_parentPath").val();
            alert("nodeName"+nodeName);
            alert("nodeParentId"+nodeParentId);
            alert("nodePath"+nodePath);
            alert("parentPath"+parentPath);
    
              jQuery.ajax({
                dataType: 'json',
                type: 'POST',
                url: 'addMenuSubNode.json',
                data: {
                    "nodeName":nodeName,
                    "nodeParentId":nodeParentId,
                    "nodePath":nodePath,
                    "parentPath":parentPath
                  },
                success: function(data) {
                    if (data.success) {
                        $("#menuTreeContainer").jstree("close_all");
                        $("#menuTreeContainer").jstree("open_all");
                       alert("增加子目录成功");
                      
                    } else {
                        alert(data.message);
                    }
                }
            });
      };
    
    var setValue = function(){
         var nodeName =  jQuery("#nodeOpera_name").val();
         jQuery("#nodeOpera_parentPath").val(tableName);
    }
    
      var addRootNode =  function() {
    
        $("#nodeOpera_parentId").val("0");
        $("#nodeOpera_parentPath").val("菜单");
    
        $("#nodeOpera_path").val($("#nodeOpera_name").val());
        var nodeName = $("#nodeOpera_name").val();
        var nodeParentId = $("#nodeOpera_parentId").val();
        var nodePath=$("#nodeOpera_path").val();
        var parentPath = $("#nodeOpera_parentPath").val();
    
        if(!nodeName || jQuery.trim(nodeName).length == 0) {
            alert("节点名称不能为空");
            return;
        }
    
            jQuery.ajax({
                dataType: 'json',
                type: 'POST',
                url: 'addMenuRootNode.json',
                data: {
                    "nodeName":nodeName,
                    "nodeParentId":nodeParentId,
                    "nodePath":nodePath,
                    "parentPath":parentPath
                  },
                success: function(data) {
                    if (data.success) {
                        $("#menuTreeContainer").jstree("close_all");
                        $("#menuTreeContainer").jstree("open_all");
                       alert("增加根目录成功");
                      
                    } else {
                        alert(data.message);
                    }
                }
            });
    
      }
    
    
    
      var searchMenu =  function(e) {  
        var searchContent = $("#treeSearchInput").val();
        alert("条件:" + searchContent);
        $("#menuTreeContainer").jstree("search",searchContent);
      };
    
        </script>
    </head>
    
    <body>
        <!-- HTML布局 -->
        <div class="main-container warp">
                <div class="col-md-4 col-sm-8 col-xs-8" style="float:bottom">
                    <button type="button" class="btn btn-success btn-sm" onclick="menuCreate();">Create</button>
                    <button type="button" class="btn btn-warning btn-sm" onclick="menuRename();">Rename</button>
                    <button type="button" class="btn btn-danger btn-sm" onclick="menuDelete();"> Delete</button>
                </div>
                <div>
                    <form onsubmit="return false">
                        <input id="treeSearchInput" type="search" maxlength="20" class="input-medium search-query" />
                        <input id="SearchSubmit" class="btn" type="submit" onclick ="searchMenu()" value="搜索" />
                    </form>
                </div>
                <div id="menuTreeContainer" class="fh-leftList demo last" style="font-size:15px;backgroud: #ffffff"></div>
            </div>
            <div class="span8" style="float:left">
                <form class="form-horizontal">
                    <div class="control-group">
                        <div id="nodeOpera_buttons" class="controls">
                            <input type="button" class="btn" id="nodeOpera_add_root" onclick="addRootNode()" value="新增根目录" />
                            <input type="button" class="btn" id="nodeOpera_add_sub" onclick="addSubNode()" value="新增子目录" />
                            <input type="button" class="btn" id="nodeOpera_modify" onclick="modifyMenu()" value="保存修改" />
                            <input type="button" class="btn" id="nodeOpera_delete" onclick="delMenuNode()" value="删除目录" />
                             <input type="button" class="btn" onclick="openAllNode()" value="全部展开" />
                             <input type="button" class="btn" onclick="hideAllNode()" value="全部隐藏" />
                        </div>
                    </div>
                    <div id="currentNode" style="">
                        <input type="hidden" id="currentNode_parentId" />
                        <div class="control-group">
                            <p style="font-size: 20px;color: red;" class="controls validateTips" id="validateTips_modify"></p>
                        </div>
                        <div class="control-group">
                            <label class="control-label">序号</label>
                            <div class="controls">
                                <input type="text" id="currentNode_id" readonly="readonly" maxlength="9" />
                            </div>
                        </div>
                        <div class="control-group">
                            <label class="control-label">名称</label>
                            <div class="controls">
                                <input type="text" id="currentNode_name" maxlength="20" />
                            </div>
                        </div>
                        <div class="control-group">
                            <label class="control-label">挂载菜单点</label>
                            <div class="controls">
                            <input type="text" id="currParentPath" maxlength="20" />
                            </div>
                        </div>
                          <div class="control-group">
                            <label class="control-label">当前路径</label>
                            <div class="controls">
                            <input type="text" id="currentPath" maxlength="20" />
                            </div>
                        </div>
                    </div>
                </form>
    
                <div id="nodeOpera_data" style="">
                   <!--  <input type="hidden" id="nodeOpera_parentId" />
                    <p class="validateTips" id="validateTips_add" style="color: red;"></p> -->
                    <label>父节点ID</label><input type="text" id="nodeOpera_parentId" maxlength="500" /><br>
                    <label>父节点路径</label><input type="text" id="nodeOpera_parentPath" onlyNumber="true" maxlength="9" /><br>
                    <label>名称</label><input type="text" id="nodeOpera_name" onkeyup="setValue()"/><br>
                    <label>所在路径</label><input type="text" id="nodeOpera_path" maxlength="20" /><br>
                    
                  
                </div>
    
            </div>
        </div>
    </body>
    
    </html>
    

    后台构造函数

        private List<TreeKey> convertTree(List<MdMenuTree> rst) {
            List<TreeKey> treeAttrs = new ArrayList<TreeKey>();
            for (MdMenuTree menuTree : rst) {
                TreeKey node = new TreeKey();
                node.setId(menuTree.getId());
                node.setName(menuTree.getName());
                node.setParentPath(menuTree.getParentPath());
                node.setParentId(menuTree.getParentId());
                node.setPath(menuTree.getPath());
                treeAttrs.add(node);
            }
            return treeAttrs;
        }
    
        private List<TreeKey> loadTree(List<TreeKey> treeAttrs, long parentId) {
    
            List<TreeKey> nodeList = new ArrayList<TreeKey>();
            for (TreeKey node2 : treeAttrs) {
                if ((parentId == node2.getParentId())) {
                    List<TreeKey> childNodes = loadTree(treeAttrs, node2.getId());
                    node2.setChildren(childNodes);
                    nodeList.add(node2);
                }
            }
    
            return nodeList;
        }
    

     

    踩过的坑

    会无线循环下去,我的初步想法是去掉那个虚线的图标,或者在虚线那个“+”和“-”上加个控制事件,但是,这个办法行不通

    解决答案: 

    根节点有 state='closed' 属性。

    去掉那个state="closed"(注意,改成open是不行的),否则这个节点会被视为还有子节点,jstree会再次调用你的ajax配置的url以加载子节点的数据。 你也可以修改你的url的服务器实现,根据父节点的id返回不同的元素以实现逐级打开的效果。 并设置correct_state标志以实现节点状态的自动更正。

    correct_state属性:

      如果设定为true,对于ajax返回的空的反馈结果,将被转换为子节点,而不再显示为打开样式。

  • 相关阅读:
    F. Maximum White Subtree 树形dp*换根
    D
    E
    两圆相交板子
    lucass定理
    高精度求组合数
    康托展开与康托逆展开
    FFT变换
    Codeforces Round #625 Div. 1 Problem C
    E.Multiply Pollard_rho质因数分解
  • 原文地址:https://www.cnblogs.com/kxdblog/p/4738281.html
Copyright © 2011-2022 走看看