使用Jquery,Ajax+Struts+Spring+Ibatis写的一个无限级树,供大家参考一下

本文介绍了一个基于JSP的动态树状菜单系统实现方案,通过前后端交互完成树形结构的动态加载与展示。该系统利用了AJAX技术进行异步数据获取,结合Struts框架处理业务逻辑,以及iBatis ORM框架执行数据库操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先看看jsp页面,tree.jsp,Code如下:

<%@ page contentType="text/html;charset=UTF-8" %>
<%
String context = request.getContextPath();
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>树状菜单</title>
<link type="text/css" href="<%=context%>/css/tree/tree.css" rel="stylesheet" rev="stylesheet" />
<%@ include file="/common/commonTop.jsp"%>
<script type="text/javascript" src="<%=context%>/script/tree/tree.js"></script>
<script type="text/javascript">
function locationHref(functionID,functionUrl,forwardUrl,functionUrlParam){
if(selectHrefID!=""){
document.getElementById(selectHrefID+"_href").style.background="";
}
selectHrefID = functionID;
document.getElementById(functionID+"_href").style.background="#0CA4CF";
document.getElementById(functionID+"_href").target='mainFrame';
document.getElementById("functionUrl").value=functionUrl;
document.getElementById("functionUrlParam").value=functionUrlParam;
document.getElementById(functionID+"_href").href=forwardUrl+"?functionUrl="+functionUrl+"&functionUrlParam="+functionUrlParam;
}
</script>
</head>

<body leftmargin="10" topmargin="0">
<input type="hidden" id="functionUrl" value="">
<input type="hidden" id="functionUrlParam" value="">
<input type="hidden" name="action" id="action" value="treeQuery">
<input type="hidden" name="url" id="url" value="<%=context%>/admin/treeAction.do">
<table>
<tr>
<td>
<div id="selectStoreType" style="display: none">   
<select id="selectType"></select>
</div>
</td>
</tr>
<tr>
<td>
<div id="selectMsg"></div>
</td>
</tr>
<tr>
<td>
<div id="treemenu" style="width:100%; height:auto;">
<div id="tree" style="display: none" align="left">
   <img src="<%= context %>/images/ajax-loader.gif">请稍等...
</div>
</div>
</td>
</tr>
</table>
</body>
</html>


再就是javascript,tree.js,如下:

var selectTypeID = "";
$(document).ready(function(){
storeTypeAjax();
$("#selectType").change(function(){
$("#tree").html("   <img src=\"<%= context %>/images/ajax-loader.gif\">请稍等...");
selectTypeID = $("#selectType").val();
treeNodeAjax("0","tree",selectTypeID);
});
});

//用于控制超级链接的背景色
var selectHrefID = "";

//异步生成树
function treeNodeAjax(functionID,nodeID,storeTypeID){
$("#selectMsg").hide();
$("#"+nodeID).show();
$.ajax({
type: "post",//使用get方法访问后台
dataType: "javascript",//返回文本格式的数据
url: $("#url").val(),//要访问的后台地址
data: "action="+$("#action").val()+"&function_id="+functionID+"&store_type_id="+storeTypeID,//要发送的数据
complete :function(){$(nodeID).show();},//AJAX请求完成时显示提示
error:function(msg){alert('加载错误');},
success: function(msg){//msg为返回的数据,在这里做数据绑定
if(msg.indexOf("1003")!=-1){
$("#selectMsg").html("<font color=red>   "+msg+"</font>");
$("#selectMsg").show();
$("#"+nodeID).hide();
}else{
var msgarray = msg.split("|");
var htmlNode = "";
for(var i=0;i<msgarray.length;i++){
var msgelement = msgarray[i].split(",");
htmlNode += creatTreeNode(msgelement[0],msgelement[1],msgelement[2],msgelement[3],msgelement[4],msgelement[5],msgelement[6]);
}
$("#"+nodeID).html("<div id='"+msgelement[2]+"'><ul style=\"cursor: hand;\">"+htmlNode+"</ul></div>");
}
//alert($("#"+nodeID).html());
}
});
}

//异步生成树
function storeTypeAjax(){
$("#selectMsg").hide();
var selectObj = document.getElementById("selectType");
var options = new Option("请稍等...","");
selectObj.add(options)
$.ajax({
type: "post",//使用get方法访问后台
dataType: "javascript",//返回文本格式的数据
url: $("#url").val(),//要访问的后台地址
data: "action=storeTypeQuery",//要发送的数据
complete :function(){$("#selectStoreType").show();},//AJAX请求完成时显示提示
error:function(msg){alert('加载错误');},
success: function(msg){//msg为返回的数据,在这里做数据绑定
if(msg.indexOf("1003")!=-1){
$("#selectMsg").html("<font color=red>   "+msg+"</font>");
$("#selectMsg").show();
}else{
var msgarray = msg.split("|");
var selectTypeNode = "";
selectObj.options.length=0;
for(var i=0;i<msgarray.length;i++){
var msgelement = msgarray[i].split(",");
var options = new Option(msgelement[2],msgelement[0]);
selectObj.add(options);
}
selectTypeID = $("#selectType").val();
treeNodeAjax("0","tree",selectTypeID);
}
}
});
}


//生成树的结构
function creatTreeNode(function_id,function_name,parent_id,function_url,count,forward_url,function_url_param){
var htmlWrite = "";
if(count>0){
htmlWrite = "<li class=\"tree\" id='"+function_id+"_li' onclick=creatChildTreeNode('"+function_id+"','"+function_id+"')><a style=\"cursor: hand;\" id='"+function_id+"_href' onclick=\"locationHref('"+function_id+"','"+function_url+"','"+forward_url+"','"+function_url_param+"')\">"+function_name+"</a></li>";
}else{
htmlWrite = "<li><a style=\"cursor: hand;\" id='"+function_id+"_href' onclick=\"locationHref('"+function_id+"','"+function_url+"','"+forward_url+"','"+function_url_param+"')\">"+function_name+"</a></li>";
}
htmlWrite += "<div id='"+function_id+"' style=\"display: none\"><img src=\"<%= context %>/images/ajax-loader.gif\">请稍等...</div>";
return htmlWrite;
}

//生成子节点,并重新给定onclick事件
function creatChildTreeNode(functionID,nodeID,parentID){
document.getElementById(functionID+"_li").className="notree";
treeNodeAjax(functionID,nodeID,selectTypeID);
document.getElementById(functionID+"_li").onclick=new Function("hideLi('"+functionID+"')");
}

function hideLi(functionID){
document.getElementById(functionID+"_li").className="tree";
$("#"+functionID).hide();
document.getElementById(functionID+"_li").onclick=new Function("showLi('"+functionID+"')");
}

function showLi(functionID){
document.getElementById(functionID+"_li").className="notree";
$("#"+functionID).show();
document.getElementById(functionID+"_li").onclick=new Function("hideLi('"+functionID+"')");
}


StrutsAction代码如下,TreeAction.java:

package cn.action.tree;

import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;

import cn.bean.login.LoginBean;
import cn.dao.tree.TreeDao;

public class TreeAction extends DispatchAction {

private TreeDao treeDao;

public TreeDao getTreeDao() {
return treeDao;
}

public void setTreeDao(TreeDao treeDao) {
this.treeDao = treeDao;
}

Logger log = Logger.getLogger(this.getClass());

//查询树节点
public ActionForward treeQuery(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)throws Exception{
HttpSession session = request.getSession();
Object obj = session.getAttribute("userinfomation");
LoginBean loginBean = new LoginBean();
if(obj!=null){
loginBean = (LoginBean)obj;
}
String functionID = request.getParameter("function_id");
String storeTypeID = request.getParameter("store_type_id");
if(storeTypeID==null){
storeTypeID="3";
}
List list = this.treeDao.getTreeList(storeTypeID, functionID, loginBean.getFunction_ids());
StringBuffer mapsb = new StringBuffer();
response.setContentType("text/html;charset=UTF-8");
if(list.size()>0){
for(int i=0;i<list.size();i++){
Map map = (Map)list.get(i);
mapsb.append(map.get("function_id")+","+map.get("function_name")+","+map.get("parent_id")+","+map.get("function_url")+","+map.get("count")+","+map.get("forward_url")+","+map.get("function_url_param"));
if(i!=(list.size()-1)){
mapsb.append("|");
}
}
response.getWriter().print(mapsb.toString());
}else{
response.getWriter().print("没有对应的信息!ErrorCode:1003");
}
return null;
}

//查询树节点上方的商店类型
public ActionForward storeTypeQuery(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)throws Exception{
HttpSession session = request.getSession();
Object obj = session.getAttribute("userinfomation");
LoginBean loginBean = new LoginBean();
if(obj!=null){
loginBean = (LoginBean)obj;
}
List list = this.treeDao.getTreeStoreType(loginBean.getStore_id());
StringBuffer mapsb = new StringBuffer();
response.setContentType("text/html;charset=UTF-8");
if(list.size()>0){
for(int i=0;i<list.size();i++){
Map map = (Map)list.get(i);
mapsb.append(map.get("store_type_id")+","+map.get("store_type_name")+","+map.get("store_name"));
if(i!=(list.size()-1)){
mapsb.append("|");
}
}
response.getWriter().print(mapsb.toString());
}else{
response.getWriter().print("没有对应的信息!ErrorCode:1003");
}
return null;
}
}



下面是Dao,TreeDao.java:

package cn.dao.tree;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.baseservice.EnterpriseService;

public class TreeDao {

public EnterpriseService enterpriseService;

public EnterpriseService getEnterpriseService() {
return enterpriseService;
}

public void setEnterpriseService(EnterpriseService enterpriseService) {
this.enterpriseService = enterpriseService;
}

public List getTreeList(String store_type_id,String functionID,String function_ids){
Map paramMap = new HashMap();
List function_ids_list = new ArrayList();
paramMap.put("function_id", functionID);
paramMap.put("store_type_id", store_type_id);
String[] function_ids_array = function_ids.split(",");
for(int i=0;i<function_ids_array.length;i++){
function_ids_list.add(function_ids_array[i]);
}
paramMap.put("function_ids", function_ids_list);

return enterpriseService.getList("Tree.node", paramMap);
}

public List getTreeStoreType(String stroe_id){
Map paramMap = new HashMap();
paramMap.put("stroe_id", stroe_id);
return enterpriseService.getList("Tree.stroeType", paramMap);
}
}



Ibatis,sqlconfig.xml如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="Tree">
<select id="node" parameterClass="java.util.HashMap" resultClass="java.util.HashMap">
select t.*,(SELECT COUNT(1) FROM tab_function a WHERE a.parent_id = t.function_id
<iterate prepend=" and a.function_id in " property="function_ids" open="(" close=")" conjunction=",">
#function_ids[]#
</iterate>
) AS count
from tab_function t where 1=1 and t.store_type_id = #store_type_id# and t.parent_id = #function_id#
<iterate prepend=" and t.function_id in " property="function_ids" open="(" close=")" conjunction=",">
#function_ids[]#
</iterate>
</select>

<select id="stroeType" parameterClass="java.util.HashMap" resultClass="java.util.HashMap">
SELECT a.*, t.* FROM tab_store t INNER JOIN tab_store_type a ON t.store_type_id = a.store_type_id WHERE 1=1
<isNotEmpty prepend=" and " property="store_id">
t.store_id = #store_id#
</isNotEmpty>
</select>
</sqlMap>


StrutsConfig配置:

<action path="/admin/treeAction" type="org.springframework.web.struts.DelegatingActionProxy" scope="request" parameter="action">
</action>


Spring配置:

.....上面的就不写明了.....
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation" value="/WEB-INF/config/ibatis-config/sqlmap-config.xml"/>
<property name="dataSource" ref="dataSource"/>
</bean>

<bean id="enterpriseService" class="cn.baseservice.EnterpriseService">
<property name="sqlMapClient" ref="sqlMapClient"/>
</bean>
<bean id="treeDao" class="cn.dao.tree.TreeDao">
<property name="enterpriseService" ref="enterpriseService"/>
</bean>

<bean name="/admin/treeAction" class="cn.action.tree.TreeAction">
<property name="treeDao" ref="treeDao"/>
</bean>


目前树结构没有使用css进行美化,大致的效果图如下:

[img]http://dl.iteye.com/upload/attachment/277681/6e79a824-5b1e-3b3d-b954-a00edfcd4694.bmp[/img]

工程附件及数据结构如下,可用eclipse直接打开:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值