Tree:
easyui tree的异步加载实现很简单,easyui的中文API文档中有实例(http://api.btboys.com/easyui/)——创建异步树形菜单,就是在tree node 元素中要有一个id属性,同时还需要state的属性(state为'closed'的时候,点击节点时会自动请求,并且将id作为参数Post到后台),只加载一次。
远程异步加载:
http://www.cnblogs.com/CoreCaiNiao/archive/2010/08/20/1804387.html
$(function(){ $('#tt2').tree({ checkbox: false, url: '/common/GetGoupJsonByPid.ashx?pid=0', onBeforeExpand:function(node,param){ $('#tt2').tree('options').url = "/common/GetGoupJsonByPid.ashx?pid=" + node.id; //只加载一次。 }, onClick:function(node){ alert(node.id); } }); });
例子:
JSP:
<script type="text/javascript" src="<%=request.getContextPath()%>/js/app/sysManagement/sysMenu.js" charset="UTF-8"></script> <html> <style> #editForm{} #editForm input{width:300px;} #editForm select{width:300px;} </style> <body> <div id="treeMenu" class="easyui-menu" style="width:120px;"></div> <div class="easyui-layout" data-options="fit:true,border:false" style="width: 100%; height: 100%;"> <div data-options="region:'north',border:false,title:'菜单管理', iconCls: 'icon-tip'" style="height:55px"> <div id="toolbar" class="easyui-toolbar" style="margin-top:5px;"> <a class="easyui-linkbutton" data-options="plain: true, iconCls: 'ope-add'" onclick="javascript:addBrothers()">新增同级</a> <a class="easyui-linkbutton" data-options="plain: true, iconCls: 'ope-add'" onclick="javascript:addChildren();">新增下级</a> <a class="easyui-linkbutton" data-options="plain: true, iconCls: 'ope-remove'" onclick="javascript:removeMenu();">删除</a> <a class="easyui-linkbutton" data-options="plain: true, iconCls: 'ope-save'" onclick="javascript:saveOrUpdateMenu();">保存</a> </div> </div> <div data-options="region:'center',border:false" > <div class="easyui-layout" data-options="fit:true,border:false" style="width: 100%; height: 100%;"> <div region="west" data-options="split:true,border:true,minWidth: 150, maxWidth: 500" style="width:230px;"> <ul id="tree"></ul> </div> <div data-options="region:'center',border:false" > <div style="margin:5px;"> <form name="editForm" method="post" id="editForm" class="easyui-SuperEditForm"> <input id="id" name="id" type="hidden"/> <input id="supId" name="supId" type="hidden"/> <table class="tableForm_L" width="100%" border="0" cellpadding="0" cellspacing="1"> <tr> <th width="15%"> 菜单名 <span class="red">*</span> </th> <td width="85%"> <input type="text" name="menuName" id="menuName" class="easyui-validatebox" data-options="required:true,validType:'length[1,200]'" /> </td> </tr> <tr> <th width="15%"> 链接URL <span class="red">*</span> </th> <td width="85%"> <input type="text" name="menuUrl" id="menuUrl" class="easyui-validatebox" data-options="required:true"/> </td> </tr> <tr> <th width="15%"> 顺序ID </th> <td width="85%"> <input type="text" name="orderId" id="orderId" class="easyui-validatebox" /> </td> </tr> <tr> <th width="15%"> 是否启用 <span class="red">*</span> </th> <td width="85%"> <select id="enabledFlag" name="enabledFlag" class='easyui-combobox' data-options="required:true,panelHeight:'auto',editable:false,readonly:false"> <option value="Y">是</option> <option value="N">否</option> </select> </td> </tr> <tr> <th width="15%">备 注</th> <td colspan="3"> <textarea cols="100" rows="13" height='auto' name="remark" id="remark"></textarea> </td> </tr> </table> </form> </div> </div> </div> </div> </div> </body> </html>
sysMenu.js
var $editForm; var $tree; var hasNew = false; $(function() { $tree = $("#tree"); $editForm = $("#editForm"); $tree.tree({ url : root + 'sysMenu/listMenus.do?pid=-1', iconCls : 'icon-save', checkbox : false, lines : true, animate : true, onBeforeExpand : function(node, param) { $tree.tree('options').url = root + "sysMenu/listMenus.do?pid=" + node.id; // 只加载一次 }, onLoadSuccess : function(node, data) { }, onSelect : function(node) { if (node.id == -1) return; if(node.id.indexOf('newNode') != -1){ var pidStr = node.id; var pid = pidStr.split("newNode")[1]; $editForm.find("input").val(""); $("#supId").val(pid); $("#remark").val("").text(""); $("#menuName").val(node.text); }else{ $tree.tree('expand',node.target) getMenuDetail(node.id); } } }); }); function getMenuDetail(id){ $.ajax({ url: root + "sysMenu/getMenuDetail.do?id="+id, type: "GET", dataType: "json", async:false, success: function (data, textStatus, XMLHttpRequest) { if(data != null){ $("#id").val(data.id); $("#supId").val(data.supId); $("#menuName").val(data.menuName); $("#menuUrl").val(data.menuUrl); $("#orderId").val(data.orderId); $('#enabledFlag').combobox('setValue', data.enabledFlag); $("#remark").val(data.remark).text(data.remark); }else{ $.messager.alert('提示','获取菜单详情失败!','error'); } } }); } function saveOrUpdateMenu(){ if (!$editForm.form('validate')) return; var selected = $tree.tree('getSelected'); if(selected == null) $.messager.alert('提示','请选择一个节点','info'); var formData=$editForm.serializeArray(); var sysMenu = {}; $.each(formData,function(i,field){ sysMenu[field.name] = field.value; }); $.ajax({ url:root+'sysMenu/saveOrUpdateMenu.do', data: sysMenu, type: "post", async:false, success: function (data, textStatus, XMLHttpRequest) { if(data != null){ $.messager.alert('提示','保存成功!','info',function(){ hasNew = false; var selected = $tree.tree('getSelected'); var parent = $tree.tree('getParent',selected.target); $tree.tree('reload',parent.target); }); }else{ $.messager.alert('提示','保存失败!','error'); } } }); } function removeMenu(){ var selected = $tree.tree('getSelected'); if(selected == null){ $.messager.alert('提示','请选择一个节点','info'); return; } if(selected.id.indexOf('newNode') != -1){ $tree.tree('remove',selected.target); hasNew = false; }else{ $.messager.confirm('提示', "确认删除节点'"+selected.text+"'?", function(r){ if (r){ $.ajax({ url : root + "sysMenu/removeMenu.do?id="+selected.id, type: 'GET', timeout: 60000, success : function(data, textStatus, jqXHR){ if('SUCCESS' == data){ hasNew = false; $tree.tree('remove',selected.target); $.messager.alert('提示','删除成功!','info'); }else{ $.messager.alert('提示','删除失败!','error'); } } }); } }); } } function addBrothers(){ if(!validate()) return; var selected = $tree.tree('getSelected'); var parent = $tree.tree('getParent',selected.target); addNewNode(parent); } function addChildren(){ if(!validate()) return; var children = $tree.tree('getSelected'); addNewNode(children); } function addNewNode(parent){ var data = {}; data.id = "newNode"+parent.id; //onSelect时的node节点不含pid,所以需要加上 data.pid = parent.id; data.text = "新建节点"; data.state = "open"; var d = new Array(); d.push(data); var param = {}; param.parent = parent.target; param.data = d; $tree.tree('append',param); var node = $tree.tree('find', data.id); $tree.tree('select', node.target); } function validate(){ var selected = $tree.tree('getSelected'); if(selected == null){ $.messager.alert('提示','请选择一个节点','info'); return false; } var text = selected.text; if(selected.id == -1){ $.messager.alert('提示','根节点不可新增节点','info'); return false; } if (selected.id.indexOf('newNode') != -1 || hasNew) { $.messager.alert("提示", "请保存或删除新增节点后再新增!", "info"); return false; } hasNew = true; return true; }
Controller:
// =================================================================菜单管理================================ @RequestMapping(value = "sysMenu/listMenus.do", method = {RequestMethod.GET,RequestMethod.POST}) @ResponseBody public List<MenuTree> listMenus(@RequestParam(required=false) long pid) { logger.debug(" listMenus begin [pid] = " + pid); List<MenuTree> result = null; try { result = sysMenuDS.listMenus(pid); } catch(Exception e) { logger.error("listMenus error :" + e.getMessage()); e.printStackTrace(); } logger.debug(" listMenus end .."); return result; } /** * 获取配额详情 * @param id * @param parentId * @return */ @RequestMapping(value = "sysMenu/getMenuDetail", method = RequestMethod.GET) @ResponseBody public SysMenu getMenuDetail(Long id) { logger.debug("getMenuDetail begin [id] = " + id); SysMenu menu = null; try { menu = sysMenuDS.getMenuDetail(id); } catch(Exception e) { logger.error("getMenuDetail error :" + e.getMessage()); e.printStackTrace(); } logger.debug("getMenuDetail end .."); return menu; } @RequestMapping(value = "sysMenu/saveOrUpdateMenu", method = RequestMethod.POST) @ResponseBody public String saveOrUpdateMenu(SysMenu menu){ logger.debug("saveOrUpdateMenu begin .."); try { sysMenuDS.saveOrUpdateMenu(menu); } catch(Exception e) { logger.error("saveOrUpdateMenu error :" + e.getMessage()); e.printStackTrace(); } logger.debug("saveOrUpdateMenu end .."); return Constants.RESULT_SUCCESS; } @RequestMapping(value = "sysMenu/removeMenu", method = RequestMethod.GET) @ResponseBody public String removeMenu(long id){ logger.debug("removeMenu begin .."); try { sysMenuDS.removeMenu(id); } catch(Exception e) { logger.error("removeMenu error :" + e.getMessage()); e.printStackTrace(); } logger.debug("removeMenu end .."); return Constants.RESULT_SUCCESS; }
Service:
@Service("iSysMenu") public class SysMenuDS implements ISysMenu { private static final Logger logger = LoggerFactory.getLogger(SysMenuDS.class); @Autowired private ISysMenuDao menuDao; /** * 菜单列表 */ @Override public List<MenuTree> listMenus(long pid) { if(pid == 0l) return new ArrayList<MenuTree>(); List<SysMenu> menus = menuDao.findByParentId(pid); List<MenuTree> trees = convertCollectionToMenuTree(menus); if(pid == -1){ trees = addRoot(trees); } return trees; } /** * 获取详情 */ @Override public SysMenu getMenuDetail(Long id) { if(id == 0l) return null; SysMenu menu = menuDao.findByMenuId(id); return menu; } /** * 保存或修改菜单 */ @Override public void saveOrUpdateMenu(SysMenu menu) { if(menu.getId() != null){ SysMenu m = menuDao.findByMenuId(menu.getId()); m.setMenuName(menu.getMenuName()); m.setMenuUrl(menu.getMenuUrl()); m.setOrderId(menu.getOrderId()); m.setEnabledFlag(menu.getEnabledFlag()); m.setRemark(menu.getRemark()); ObjectUtil.setUpdatedBy(m); menu = m; }else{ ObjectUtil.setCreatedBy(menu); } menuDao.save(menu); } @Override public void removeMenu(long id) { if(hasChildren(id)){ menuDao.deleteChildrenById(id); } menuDao.remove(id); } /** * 添加根节点 * @param children * @return */ private List<MenuTree> addRoot(List<MenuTree> children) { List<MenuTree> result = new ArrayList<MenuTree>(); MenuTree root = new MenuTree(); root.setId(String.valueOf(-1l)); root.setPid(String.valueOf(-1l)); root.setText("菜单管理"); root.setChecked(false); root.setIconCls(""); root.setState("open"); root.setChildren(children); result.add(root); return result; } public boolean hasChildren(long id){ List<SysMenu> children = menuDao.findByParentId(id); if(children != null && children.size() > 0){ return true; } return false; } public MenuTree convertToMenuTree(SysMenu menu){ MenuTree tree = new MenuTree(); tree.setId(String.valueOf(menu.getId())); tree.setPid(String.valueOf(menu.getSupId())); tree.setText(menu.getMenuName()); if(hasChildren(menu.getId())){ tree.setState("closed"); }else{ tree.setState("open"); } return tree; } public List<MenuTree> convertCollectionToMenuTree(List<SysMenu> ls){ List<MenuTree> trees = new ArrayList<MenuTree>(); if(ls == null || ls.size() == 0) return trees; for(SysMenu menu : ls){ trees.add(convertToMenuTree(menu)); } return trees; } }
相关CSS:
.icon-tip { background: url('icons/tip.png') no-repeat; } .tree-folder-open { background: url('images/tree_folder_open.gif') no-repeat; } .tree-folder { display: inline-block; background: url('images/tree_folder.gif') no-repeat; width: 16px; height: 18px; vertical-align: middle; } .tree-node-selected { background: url('images/tree_selected_bg.png') left bottom no-repeat; height: 26px; line-height: 26px; }
效果图:
相关推荐
**jsTree 中文文档概述** jsTree 是一个流行的JavaScript库,用于在网页上创建交互式的树状视图。它主要用于组织结构化的数据,如文件系统、数据库目录或自定义项目结构。jsTree 支持多种操作,包括点击、拖放、...
标题提到的"tree(c++ tree容器)"是一个第三方实现,旨在为C++开发者提供一个类似于STL接口的树容器,方便用户在项目中构建和操作树形数据。 这个源码库的亮点在于它的用法与C++标准库中的其他容器类似,如vector和...
设备树(Device Tree)在嵌入式Linux系统中扮演着至关重要的角色,它是一种数据结构,用于描述硬件配置,使得操作系统内核能够更好地理解和管理硬件资源。`device-tree-xlnx-master_tree_devicetree2018.3_`这个标题...
**jsTree API详解** jsTree 是一个流行的JavaScript库,用于创建、操作和展示交互式的HTML树状视图。它提供了一套丰富的API,使得开发者能够方便地实现树形结构的各种功能,如添加、删除、修改节点,以及节点的移动...
【速度树(SpeedTree)教程】 SpeedTree是一款广泛应用于游戏开发、影视特效、虚拟现实以及建筑设计等领域的高级树木和植被渲染软件。它以其强大的建模功能、高效的渲染技术和逼真的动态效果而闻名。本教程是专门...
其中,PowerTree作为一款专注于配电网络(PDN)设计的工具,正受到越来越多设计工程师和电源完整性工程师的青睐。它不仅提供了基于原理图的电源早期视图,还有助于优化PDN的设计与性能。本文将系统地介绍PowerTree...
TreeTagger是一款由德国图宾根大学的Philippe Schmid教授开发的著名自然语言处理工具,主要用于对文本进行词性标注、实体识别和句法分析。这个软件在学术界和工业界都得到了广泛的应用,特别是在语言学研究和信息...
在Flex中,Tree组件是用于显示层次结构数据的控件,而"flex带复选框的tree"(Flex CheckboxTree)则是对Tree组件的一种扩展,增加了复选框功能,用户可以对树形结构的节点进行选择或全选操作,常用于权限管理、配置...
在移动设备上,为了有效地展示层次结构数据,如文件系统、组织架构或导航菜单,"手机端js tree"成为了一种实用的解决方案。这个技术基于JavaScript,专为智能手机和平板电脑等移动端设备设计,提供了可自定义的树形...
SPeedtree 7.14 for Unity是一款专为Unity引擎设计的高级植被渲染插件,它为游戏开发者提供了强大的自然环境构建工具。在Unity这个广泛使用的跨平台游戏开发框架中,SPeedtree能够帮助设计师们创建出栩栩如生、细节...
在Element UI库中,`el-tree` 是一个强大的组件,用于构建可交互的树形结构数据展示。在实际开发中,我们经常需要处理用户选择的节点,并可能需要独立展示这些选中节点,甚至允许用户在独立的树结构中进行删除操作。...
**Ajax Tree技术详解** 在网页开发中,树形结构(Tree)是一种常见的数据展示方式,尤其在管理和组织层级数据时非常实用。Ajax Tree是利用Ajax技术动态加载和更新树节点,提供用户友好的交互体验。它允许用户在不...
Excel中的TreePlan是一款强大的建模插件,专用于创建和分析决策树模型。在商业智能、项目管理和风险管理等领域,决策树是一种常用的分析工具,它通过图形化的方式展示各种可能的决策路径及其结果,帮助用户在不确定...
【EasyTree的使用教程】 EasyTree 是一个轻量级的前端组件,专用于构建和展示树型结构数据。它在Web应用中广泛用于组织和管理层次化的信息,如目录结构、组织架构或权限管理等。这个教程将详细介绍如何使用经过修改...
**jsTree:构建前端树形结构的利器** jsTree 是一个强大的 JavaScript 库,专用于在 Web 页面上创建交互式的树形结构。它基于纯 JavaScript 编写,无需依赖其他库,因此对于初学者和有经验的开发者来说,都是一个...
`Tree` 命令是 Windows 操作系统中一个实用的 DOS 命令,它允许用户以图形化的树状结构来查看指定驱动器或路径的文件夹结构。这种直观的展示方式对于理解和管理文件系统非常有帮助。下面将详细解释 `Tree` 命令的...
### KD-Tree基本教程知识点概览 #### 一、引言与背景介绍 - **教程来源**:本教程来源于Andrew W. Moore博士论文的一部分——《Efficient Memory-based Learning for Robot Control》,该章节专用于KD-Tree及其在...
《TableTree:构建表格树形结构的实现与应用》 在数据展示中,有时我们需要将层级关系的数据以表格的形式呈现,这时,表格树形结构(TableTree)就显得尤为重要。它将传统二维表格与树状结构相结合,既保留了表格的...
JavaScript Tree是一种交互式的前端UI组件,它以树形结构展示数据,常用于网站或应用程序的导航、目录组织或数据层级展示。"Checkbox Tree"是这种树结构的一个扩展,它在每个节点上添加了复选框,允许用户进行多选...
i-Tree的五大核心产品包括:i-Tree Eco、i-Tree Streets、i-Tree Hydro、i-Tree Vue和i-Tree Species Selector。 1. i-Tree Eco:它能提供整个城市森林的概况分析,通过使用来自社区随机分布样区的现场数据和当地每...