博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
利用ajax,巧妙的sql语句组合,轻松做出不错的树型菜单
阅读量:4652 次
发布时间:2019-06-09

本文共 5633 字,大约阅读时间需要 18 分钟。

我们的某个项目中,在设计报表时候,考虑到做报表的树型分类,同时考虑到分类下存在子分类和报表并存,使用原有项目中jtree功能已经达不到这要求,因此,考虑蛮久,还是自己写一个吧.

注意: 前提需知: 本项目所包含技术: j2ee,structs2.0,spring,ibatis,(数据库是oracle,这和数据库没关系)

为保密起见,本例只贴出关键位置,不会暴露完全的设计流程,朋友如果你看到这里,请原谅.但是完全不会影响到阅读理解.

先发几张效果图,有兴趣就继续往下看

1.-----------------------------------------------

2.-----------------------------------------------
3.----------------------------------------------
(看到这里你就知道了,分类中有可能存在子分类,而同时又存在报表)
好,废话少说,开始讲解步骤吧,

<1> 首先,你要设计好数据库的结构,结构必须是合理的   ,下面发几张图,可以着图去理解,我也不会多说了,蝙蝠有限.

报表分类表(或者理解为"树"):
大体说一下: ID:节点ID(唯一) , PARENT_ID:父级ID,NAME:节点文字,这三个必备,其他是无关紧要的.

报表表(关联到报表分类表,注意外键) :
关联两个表进行查询:

下面是ibatis的SQL语句(如果没有ibatis知识的朋友,请自行学习了再看,不然怎么也说不清楚):
注意:唯一的参数 :=#parentId#
    <!-- 查询单个报表分类的子分类 -->
    <select id="loadSortTypeByParentId" parameterClass="java.lang.String"
     resultClass="java.util.HashMap">
     select "text",
        "parentId",
        "nodeId",
        "count",
        case("parentId")
            when '-' then 'minus_m.gif'
            else 'plus_m.gif' end
        as "report_Icon",
        case("parentId")
            when '-' then 'hfile.gif'
            else 'fold.gif' end
        as "report_Img"
    from (
       select a.NAME as "text",
                a.PARENT_ID AS "parentId",
                a.ID AS "nodeId",
                nvl(b.nodeCount, 0) AS "count"
           from RPT_CODE_REPORT_TYPE a
           Left Outer Join (
                select PARENT_ID, count(ID) nodeCount
                from RPT_CODE_REPORT_TYPE
                where IS_VALID = 1
                group by PARENT_ID) b
          On a.ID = b.PARENT_ID
       where a.PARENT_ID =#parentId#
       union
       select a.report_name as "text",
                '-' as "parentId",
                TO_CHAR(a.id) as "nodeId",
                0 AS "count"
       from RPT_INFO_REPORT a
         Inner join RPT_CODE_REPORT_TYPE b On b.ID = a.REPORT_TYPE_CODE
       where b.ID =#parentId#
   ) order by "nodeId" desc
</select>
相关的JAVA部分就省略了,大体意思我可以说一下.
我这里是在struct2.0的action (ReportInfoAction) 里定义一个方法 : public String reportListLoad()
这个方法大体是这样:
public String reportListLoad(){
      //开始加载ibatis
      //**************************
      /*这是struts2.0的新特性,通过相关配置,它会自动找到相关JSP页面*/
     return "loadNodeTree";
}
因为java的技术太多,
你可能是用一般的JSP编程,在这里你可以定义一个自己的javaBean来操作你的ibatis;
你可能是用传统的servlet,同样你也可以在你所定义的servlet里加再你的ibatis(当然你也可以更完美的分离代码) ;
或者你会使用的是webwork,总之,道理是一样的.
如果你对这些技术半懂不懂,那以上等于我白说,如果你是JAVA开发者,我说了这些估计你认为是废话.嘿嘿.

看看JSP页面吧:

首先一个ViewTree.jsp :
这个是一个比较重要的JS定义函数(中间用到了ajax发送方式):
<script type="text/javascript" src="/prototype/prototype.js"></script>
<script language="JavaScript">
/*
* 创建树型类
* 编写:莫小明
* 时间:2008年7月9号
* 实现:树型目录
* 解决了:
* 同以节点下即存在子节点,又存在报表
*/
var BuilderTree=function()
{
//初始创建
this.innitBuilder=function()
{
     //在加载完毕时创建
    window.οnlοad=function(){
     var id="divTrees_009.001";
     var nodeTree=document.createElement("div");
     nodeTree.setAttribute("id",id);
   nodeTree.style.display="none";
     $("tree").appendChild(nodeTree);
     b.builderTree(id,id,id.replace("divTrees_",""));
}
}
/* 创建子节点
   * 参数 openCloseObj :关闭打开子节点
   * 参数 loadObj:加载加载条的对象
   * 参数 nodeId:子节点的编号
   */
this.builderTree=function(openCloseObj,loadObj,nodeId)
{
   //判断是否是报表
if($("type_"+nodeId))
{
   if($("type_"+nodeId).innerHTML.indexOf("hfile.gif")>0)
   {
    //alert("是报表,报表ID="+nodeId);
     //在右边打开报表
     var url="ReportInfo.action?view=tree&id="+nodeId;
    //具体打开位置:从最上边查找,top下的mainFrame
    //mainFrame下的v_mainFrame
   top.mainFrame.v_mainFrame.location.replace(url);
     return;
   }
}
var url = 'ReportInfo!LoadNodeTrees.action';
var id = nodeId;
if(id=="") return ;
var params = 'parentId=' + id;
//如果当前的打开的
if(Element.visible(openCloseObj))
{
   if($("icon_"+id))
   {
     $("icon_"+id).innerHTML=$("icon_"+id).innerHTML.replace("minus_m.gif","plus_m.gif");
     $("type_"+id).innerHTML=$("type_"+id).innerHTML.replace("folderopen.gif","fold.gif");
   }
   Element.hide(openCloseObj);
   return ;
}
else
{
   Element.show(openCloseObj);
}
     this.__loading(loadObj);
     //创建Aajx对象
      var __ajax = new Ajax.Request(url,{
         method: 'get',
       parameters: params,
       onComplete: function __callback(request)
          { /*执行具体的回调函数*/   
          var result=request.responseText;
          //判断是否有结果
          if(result.length<5)
          { //确认没有子节点以及相关报表,关闭之
          Element.hide(openCloseObj);
          $("icon_"+id).innerHTML=$("icon_"+id).innerHTML.replace("plus_m.gif","minus_m.gif");
                                 return ;
          }
          else
          {
            if($("icon_"+id))
          { //关闭图标设置为展开图标
              $("icon_"+id).innerHTML=$("icon_"+id).innerHTML.replace("plus_m.gif","minus_m.gif");
           $("type_"+id).innerHTML=$("type_"+id).innerHTML.replace("fold.gif","folderopen.gif");
              //
          }
          }
          //存放结果
          $("divTrees_"+id).innerHTML=result;
          }});
}
//显示加载条
this.__loading=function(obj)
{
    //alert(obj);
var img="&nbsp;&nbsp;<img src=\"../resources/img/loading.gif\" border=\"0\" />&nbsp;加载中...";
$(obj).style.display="";
$(obj).innerHTML=img;    
}
}
var b=new BuilderTree();b.innitBuilder();
</script>
</head>
<body>
<div align="center"><img src="img/treeTile.gif" border="0" /></div>
<br/><div id="tree"></div>
这里是ajax发送请求后在structs2.0的action里控制返回的JSP页面:
该页面没什么特殊,除了自己定义的标签外,和其他的标签没什么两样,
如果你觉得不舒服,完全可以改造成自己的普通JSP标签.
(注意里面所调用的JS函数)

<%@ page contentType="text/html;charset=utf-8" language="java"%>
<%@ taglib prefix="b" uri="/bonc-tags"%>
<b:gBody value="sortList">
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
    <td width="2%" id="icon_<b:gd value='nodeId'/>" style="cursor:hand"
        onClick=b.builderTree("p_<b:gd value='nodeId'/>","divTrees_<b:gd value='nodeId'/>","<b:gd value='nodeId'/>")
    ><img src="../resources/img/alai_tree/<b:gd value='report_Icon'/>"></td>
    <td width="98%" id="type_<b:gd value='nodeId'/>"><img src="../resources/img/alai_tree/<b:gd value='report_Img'/>">&nbsp;
    <a onClick=b.builderTree("p_<b:gd value='nodeId'/>","divTrees_<b:gd value='nodeId'/>","<b:gd value='nodeId'/>") href="javascript:void(0)" ><b:gd value="text"/></a>
    </td>
</tr>
<tr id="p_<b:gd value='nodeId'/>" style="display:none">
    <td></td>
    <td id="divTrees_<b:gd value='nodeId'/>">&nbsp;</td>
</tr>
</table>
</b:gBody>
就这样完了........ 也许不能帮你什么忙,也许这方法你早用过.但是我还是发到blog上,因为我也要记录自己的知识,如果你反馈你有更好的解决方案,我会对比,进一步改造.嘿嘿.

原帖地址:

转载于:https://www.cnblogs.com/Overbord/archive/2012/08/09/2630315.html

你可能感兴趣的文章