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;
- }
踩过的坑
会无线循环下去,我的初步想法是去掉那个虚线的图标,或者在虚线那个“+”和“-”上加个控制事件,但是,这个办法行不通
解决答案:
根节点有 state='closed' 属性。
去掉那个state="closed"(注意,改成open是不行的),否则这个节点会被视为还有子节点,jstree会再次调用你的ajax配置的url以加载子节点的数据。 你也可以修改你的url的服务器实现,根据父节点的id返回不同的元素以实现逐级打开的效果。 并设置correct_state标志以实现节点状态的自动更正。
correct_state属性:
如果设定为true,对于ajax返回的空的反馈结果,将被转换为子节点,而不再显示为打开样式。
jstree树形菜单的更多相关文章
- jsTree树形菜单分类
这里我演示的jsTree是基于ABP框架 ,展示部分代码,话不多说首先看效果如: 1:引入JS <link href="/jstree/themes/default/style.css ...
- 实用的树形菜单控件tree
jQuery plugin: Treeview 这个插件能够把无序列表转换成可展开与收缩的Tree. jQuery plugin: Treeview jQuery jstree jsTree ...
- html树形菜单控件
html树形菜单控件 链接 http://www.ithao123.cn/content-713974.html jQuery plugin: Treeview 这个插件能够把无序 ...
- 在Bootstrap开发框架中使用bootstrapTable表格插件和jstree树形列表插件时候,对树列表条件和查询条件的处理
在我Boostrap框架中,很多地方需要使用bootstrapTable表格插件和jstree树形列表插件来共同构建一个比较常见的查询界面,bootstrapTable表格插件主要用来实现数据的分页和 ...
- 【转】html树形菜单控件
Query plugin: Treeview 这个插件能够把无序列表转换成可展开与收缩的Tree. 主页:http://bassistance.de/jQuery-plugins/jquery-pl ...
- jQuery 树形菜单
树形菜单 在 jQuery easyu中其左侧的主菜单使用的是 easyui 中的 tree 组件,不是太熟悉,不过感觉不是太好用. 比如 easyui 中的 tree 需要单击分叉节点前的小三角,才 ...
- JS树形菜单
超全的JS树形菜单源代码共享(有实例图) 树形菜单是很常用的效果,常用在管理软件当中,但是一套树形菜单已经不能满足需求,所以如果能有一套比较全面的树形菜单JS特效代码,将会非常方便,下面懒人萱将超全的 ...
- 简单实用的二级树形菜单hovertree
原创 hovertree是一个仿京东的树形菜单jquery插件,暂时有银色和绿色两种. 官方网址:http://keleyi.com/jq/hovertree/欢迎下载使用 查看绿色效果:http:/ ...
- Vue.js 递归组件实现树形菜单
最近看了 Vue.js 的递归组件,实现了一个最基本的树形菜单. 项目结构: main.js 作为入口,很简单: import Vue from 'vue' Vue.config.debug = tr ...
随机推荐
- 【转】Robust regression(稳健回归)
Robust regression(稳健回归) 语法 b=robustfit(X,y) b=robustfit(X,y,wfun,tune) b=robustfit(X,y,wfun,tune,con ...
- spring之p命名空间注入
<bean id="personId" class="com.itheima.f_xml.c_p.Person" p:pname="禹太璞&qu ...
- 网易云免费OSS服务用做Markdown图床或博客图片外链
我使用据说是Windows下最好用的Markdown编辑器“MarkdownPad2”(个人感觉还是Visual Code+Markdown插件666)写Markdown,在贴图方面遇到一个问题,于是 ...
- python中的协程及实现
1.协程的概念: 协程是一种用户态的轻量级线程.协程拥有自己的寄存器上下文和栈. 协程调度切换时,将寄存器上下文和栈保存到其他地方,在切换回来的时候,恢复先前保存的寄存器上下文和栈. 因此,协程能保留 ...
- python中的函数对象与闭包函数
函数对象 在python中,一切皆对象,函数也是对象 在python语言中,声明或定义一个函数时,使用语句: def func_name(arg1,arg2,...): func_suite 当执行流 ...
- 弥补wxpython无背景图片缺陷
思路: 通过设置Panel的背景样式为wx.BG_STYLE_CUSTOM: self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM) 绑定Panel的背景事情: sel ...
- 51NOD 1705 七星剑 [DP 期望的线性性质]
传送门 题意: 七颗星,第$i$课星用第$j$个宝石有$p[i][j]$的概率成功,失败将为$g[i][j]$颗星: 第$j$个宝石化费$c[j]$ 求最小期望化费 $MD$本来自己思路挺对的看了半天 ...
- POJ 2007 Scrambled Polygon [凸包 极角排序]
Scrambled Polygon Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 8636 Accepted: 4105 ...
- C# 使用反射获取界面并传参
// 通过反射创建类库中的实例 try { // 通过反射,获取模块 Assembly assembly = Assembly.LoadFrom(AppDomain.CurrentDomain.Bas ...
- 关于@Override
首先,来了解一下“重载”和“覆写”的区别: 重载: (1)方法重载是让类以统一的方式处理不同类型数据的一种手段.多个同名函数同时存在,具有不同的参数个数/类型.重载Overloading是一个类中多态 ...