先上效果图
首先说说jquery-treeview 这个插件,这里有官方的demo http://jquery.bassistance.de/treeview/demo/ 用法很简单
我们只需要组织好相应的html标签就好了,例如:
<div id="treeContainer"> <ul> <li>父节点 <ul> <li>子节点1</li> <li>子节点2</li> </ul> </li> </ul> </div>
然后简单的调用 $("#treeContainer ul").Treeview(); 就能生成一颗js树
那么接下来,我们就要想办法来组织这些标签,我自己是在后台使用freemarker来动态生成的。
至于系统栏目表的结构,就是一个引用自身的表,
例如 t_menu表有字段 id name parent 这三个字段
那么相应的数据有可能是这样的
id name parentId
1 系统管理 0(或者NULL)
2 系统日志 1
3 用户管理 1
4 文章管理 0(或者NULL)
5 文章分类 4
这个大家应该一看就知道是一个无限级树形结构.
那么使用hibernate后,我们首选需要查询出所有的顶级菜单和相应的子菜单列表
hql = "from t_menu where parentId = 0"
由于hibernate可以级联查询出所有子菜单的数据,所以,我们可以很方便的拿到一个list,它的数量为2(2个顶级菜单)
然后把这个list对象传给freemarker的上下文,就可以用freemarker的宏来递归产生html标签(我上面的例子和对象只是简单举例,下面的模板内容是我实际项目的编码,所以看起来会和上面举的例子的不一致,不过过程都一样的,理解了都一样的,就是迭代菜单名,然后判断是否还有子菜单,有就递归调用宏.)
<#-- 定义宏buildCheckbox --> <#macro buildCheckbox purviewItem> <#if purviewItem= 1> <input type="checkbox" name="purview" value ="1" >查看 <#elseif purviewItem = 2> <input type="checkbox" name="purview" value ="2" >添加 <#elseif purviewItem = 3> <input type="checkbox" name="purview" value ="3" >修改 <#elseif purviewItem = 4> <input type="checkbox" name="purview" value ="4" >删除 </#if> </#macro> <#-- 定义宏buildNode --> <#macro buildNode child parent> <li id="${parent.MPkid}" parentId="${parent.MParentId}">${parent.MItem} <#if child?? && child?size gt 0> <ul> <#list child as t> <#-- 递归调用宏buildNode --> <@buildNode child=t.children parent=t/> </#list> </ul> <#else> <#-- 如果是叶子节点 --> <#list parent.options as purviewItem> <#-- 循环调用宏buildCheckbox --> <@buildCheckbox purviewItem=purviewItem/> </#list> <#-- <input type="checkbox" name="purview" value ="1" >查看 <input type="checkbox" name="purview" value ="2" >添加 <input type="checkbox" name="purview" value ="3" >修改 <input type="checkbox" name="purview" value ="4" >删除--> </#if> </li> </#macro> <ul> <#list rootMenus as root> <#-- 循环调用宏buildNode --> <@buildNode child=root.children parent=root/> </#list> </ul>
就这样,就能够产生一个无限级树的js菜单所需要的html标签了,接着只需要在页面简单的调用 $("#treeContainer ul").Treeview(); 就好了.
另一方面,至于如何授权(遍历js树),就有很多方法了,我是这么实现的
工具:用到json2.js和google gson这个库来将json对象转换成java对象
页面代码,遍历树,组织json对象,用于提交到服务器
//定义rolePurview对象 var rolePurview = function(jewelryRole, jewelryMenu, opQuery){ this.jewelryRole = jewelryRole; this.jewelryMenu = jewelryMenu; this.opQuery = opQuery; } //定义集合对象,用于递归时地址传递 var rolePurviews = {str: '{ "rolePurviews":['}; //授权 function save(){ //迭代所有根节点 $("li[parentId='0']").each(function(){ var $this = $(this); var menu = $this.attr('id'); var options = []; //判断根目录下的所有叶子节点是否有进行选择的,有就进行递归遍历 if($this.find("input:checked").length > 0){ recursiveTree($this,rolePurviews); } }); //如果所有checkbox都没有选择 if(rolePurviews.str.length == 18){ rolePurviews.str += ','; } rolePurviews.str = rolePurviews.str.substring(0,rolePurviews.str.length-1)+"]}"; //alert(rolePurviews.str); roleServiceDWR.roleAuthorizationDwr(purview,operations[1],role,rolePurviews.str,{ callback:function(data){ if(data == 0){ sucInfoHandler("角色授权成功!",back); }else{ sucInfoHandler("角色授权失败!",emptyPurviews); } } }); } //递归遍历js树 function recursiveTree(node,rolePurviews){ var options = []; var sdataObj; var jsonText; var nodeId = node.attr('id'); //如果不是叶子节点,且其下的叶子节点有被选择的. if(node.find("ul").length > 0 && node.find("input:checked").length > 0){ sdataObj = new rolePurview(role,nodeId,options); jsonText = JSON.stringify(sdataObj); rolePurviews.str+=jsonText+","; node.find("li[parentId="+nodeId+"]").each(function(){ //递归 return recursiveTree($(this),rolePurviews); }) }else if(node.find("ul").length == 0 && node.find("input:checked").length > 0){ //如果是叶子节点,且有被选择的 node.find("input:checked").each(function(){ options.push($(this).val()); }) sdataObj = new rolePurview(role,nodeId,options); jsonText = JSON.stringify(sdataObj); rolePurviews.str+=jsonText+","; } }
然后 服务器里,只需要简单的调用google gson的反射方法,就能够拿到一个list对象,里面装好了每个栏目的相应权限.
Gson gson = new Gson(); ListRolePurview r = gson.fromJson(jsonStr, ListRolePurview.class);
1 楼
jjxboy
2010-09-06
能不能给个源码啊,谢谢了!
jack(a)win-liutan.com
jack(a)win-liutan.com
2 楼
jjxboy
2010-09-14
你是我看得云里雾里的,能不能给个完整一点的demo看看啊?谢谢了!
3 楼
chenxiang105
2010-09-25
给个源码崇拜下.....win.sb@hotmail.com
4 楼
┿┅мīSS
2010-10-22
chenxiang105 写道
给个源码崇拜下.....win.sb@hotmail.com
已发送.
5 楼
┿┅мīSS
2010-10-22
jjxboy 写道
能不能给个源码啊,谢谢了!
jack(a)win-liutan.com
jack(a)win-liutan.com
已发送
6 楼
kangmint74
2010-12-28
给个完整源码吧 815697415@qq.com 谢谢
7 楼
用手踢球
2011-03-24
能不能给个源码?