纵有疾风起
人生不言弃

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 {        width: 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;    }

 

踩过的坑

jstree树形菜单插图

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

解决答案: 

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

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

correct_state属性:

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

 

文章转载于:https://www.cnblogs.com/kxdblog/p/4738281.html

原著是一个有趣的人,若有侵权,请通知删除

未经允许不得转载:起风网 » jstree树形菜单

分享到: 生成海报
avatar

评论 抢沙发

评论前必须登录!

立即登录   注册

切换注册

登录

忘记密码 ?

切换登录

注册

我们将发送一封验证邮件至你的邮箱, 请正确填写以完成账号注册和激活