Ajax动态加载目录树(jquery-treeview)

本文介绍如何利用Ajax、jQuery和treeview插件动态加载目录树节点数据。通过点击节点从数据库获取子节点信息,环境为Struts1、Hibernate3.0和jQuery。在Struts中配置数据源,并展示生成JSON数据的Java代码,以及如何在treeview中处理点击事件以返回当前路径。

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

需求:

   动态加载目录树节点数据。即:树的初始状态为根节点树,当点击其中一个节点时,再从数据库中获取当前节点的子节点。

环境:

   Struts1+Hibernate3.0+jQuery+treeview

解决方案:

1.我自己的项目需求是:获取linuxFTP目录,以动态加载的方式取得该FTP上的所有目录及文件生成js树,点击文件获取该文件在FTP上的路径,目录不能点击。

2.准备工作:

 

<link rel="stylesheet" href="css/jquery.treeview.css" />

<link rel="stylesheet" href="css/screen.css" />

<script src="js/jquery.js" type="text/javascript"></script>

<script src="js/jquery.cookie.js" type="text/javascript"></script>

<script src="js/jquery.treeview.js" type="text/javascript"></script>

<script src="js/jquery.treeview.async.js" type="text/javascript"></script>

 

以上各引用文件可以从网上下载的treeview 包里得到,下载地址:http://jquery.bassistance.de/treeview/jquery.treeview.zip。注意js文件的引用顺序,黄色部分是异步加载必须的js文件。具体应用时根据自己情况决定,上面的文件不一定全得有。以下是我的jsp的代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<%@ include file="/general/common.jsp" %>

<head>

<%

  response.setHeader("Cache-Control","no-cache");

  response.setHeader("Pragma","no-cache");

  response.setDateHeader("Expires",0);

%>

<link rel="stylesheet" href="css/jquery.treeview.css" />

 

<script src="javascript/jquery.treeview.js" type="text/javascript"></script>

<script src="javascript/jquery.treeview.async.js" type="text/javascript"></script>

<script type="text/javascript">

    $(document).ready(function(){

       $("#black").treeview({         

           url: "source.do"

       })

    });

   

function returnID(Path)

{

 if(Path!="undefined")

  document.getElementById("Path").value=Path;

  else document.getElementById("Path").value="";

}

</script>

</head>

<body>

 

<h1><bean:message key="ProgramMediacontent.SourceFileName"/></h1>

<br/>

<br/>

<br/>

<table align="center">

<tr align="left">

 

  <td width="60%" valign="top">

   <ul id="black" class="filetree treeview-famfamfam"></ul>

  </td>

 

  <td width="40%" valign="bottom" align="center">

   <div class="content_panel" id="div_function_panel">

    <center>

     <bean:message key="Content.ListFile"/><bean:message key="Colon" bundle="common"/>

      <input id="Path" style="overflow-x:visible;width:60;" type="text"></input>

      <br/>

        <div style="text-align:center "  class="buttons">

          <button type="button" onclick="return onSubmit();"><bean:message key="Button.OK" bundle="common"/> </button>

          <button type="button" onclick="return back2list();"><bean:message key="Button.Cancel" bundle="common"/></button>

        </div>

   </center>

  </div>

 </td>

 

</tr>

</table>

 

<script type="text/javascript">

function onSubmit()

{

     var Path = document.getElementById("Path").value;

     var myString = new Array();

     myString[0]=Path;

     return return2parent(btn.ok,myString); 

}

 

function back2list()

{   

   return return2parent(btn.back);

 

}

</script>

</body>

</html>

我自己的公用文件里已经有jqueryjs了,所以没有引用treeview自带的文件,jquery.cookie.js说是用来保存树的状态的,但我用后就觉得很不爽。因为我要在父页面选择一个FTP服务器,然后在上面这个dialog页面里显示其目录结构,加上jquery.cookie.js,后无论选择哪个服务器,新弹出的页面中的树总是第一次生成树的内容(这里可能表达的不是很清楚,说白了就是不刷新)。无奈去掉它,再加上jsp页面禁用缓存的经典代码,问题解决。

上面是完整的代码,为了给大家一个整体感觉,但其实生成树所用的代码只有一行:

<ul id="black" class="filetree treeview-famfamfam"></ul>

把标签与treeview连接的js如下:

<script type="text/javascript">

    $(document).ready(function(){

       $("#black").treeview({         

           url: "source.do"

       })

    });

</script>

看起来很简单。<ul>是要节点生成的位置,id随便取,与上面js一致就行,classtreeview自带的样式(自带了三种)。Js中的urljs树获得数据的数据源,可以是php页面、jsp页面或者是从后台action传递过来的数据。但因为treeviewJquery的插件,所以无论哪种方式,传递时都必须用json串来通讯。

Struts中配置数据源与页面关联:

   <action

    path="/source"

    scope="request"

   type="com.blossom.cmportal.view.content.ListFTPFileAction" validate="false">       

   </action>

 

一个jsp页面数据源的例子如下:source.jsp

<%

 String text="[{/"text/": /"计算机学院/",/"expanded/": false,/"children/":[{/"text/": /"软件工程/",/"children/":[{/"text/":/"Java/"},{/"text/":/"C++/"}]},{/"text/": /"网络工程/",/"children/":[{/"text/":/"Cisco/"}]},{/"text/": /"计算机应用/",/"children/":[{/"text/":/"多媒体应用/",/"id/":/"dmt/",/"hasChildren/":true}]}]},{/"text/": /"金融学院/",/"id/":/"jr/",/"hasChildren/":true}]";

String para=request.getParameter("root");

if("source".equals(para)){

    System.out.println("Success");

    out.print(text);

}

else if("jr".equals(para))

{

    String jr="[{/"text/": /"证券/",/"expanded/": true,/"children/":[{/"text/": /"银河证券/"},{/"text/": /"长江证券/"}]},{/"text/": /"银行/"},{/"text/": /"保险/"},{/"text/": /"股市/"}]";

    out.print(jr);

}

else if("dmt".equals(para)){

    String dmt="[{/"text/": /"视频编解码/",},{/"text/": /"MaltLab/"},{/"text/": /"SecondLife/"}]";

    out.print(dmt);

}

%>

jsp页面就只有这些代码,其他的什么都不要带。有些乱,但如果了解json,上面代码很容易理解。

如果只是想简单的测试一下,上面的两个jsp已经可以形成树了,另外就是要注意css/js/imagesjsp页面的路径,根据自己情况配置好。

我的项目要求数据必须是从后台获取,所以我的treeviewURLsource.do(我用的struts1),这个根据自己项目写。

以下是Action代码:

package com.blossom.cmportal.view.content;

 

import java.io.PrintWriter;

 

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import org.apache.struts.action.ActionForm;

import org.apache.struts.action.ActionForward;

import org.apache.struts.action.ActionMapping;

 

import com.blossom.cmportal.service.mam.business.MediaServerService;

import com.blossom.cmportal.service.mam.vo.MediaServer;

import com.blossom.cmportal.view.general.CommonAction;

import com.blossom.cmportal.view.general.FTPFileMenuGetter;

 

public class ListFTPFileAction extends CommonAction {

       private static final Log log = LogFactory.getLog(ListFTPFileAction.class);

 

       @Override

       public ActionForward execute(ActionMapping mapping, ActionForm form,

                     HttpServletRequest request, HttpServletResponse response)

                     throws Exception {

              log.info("Enter ListFTPFileAction Class");

              FTPFileMenuGetter ftptest = new FTPFileMenuGetter();

              response.setHeader("Cache-Control", "no-cache");

              response.setContentType("text/json;charset=UTF-8");

              response.setCharacterEncoding("UTF-8");

              PrintWriter out = response.getWriter();

              String root = request.getParameter("root");

              String json = null;

              String ID = request.getSession().getAttribute("ID").toString();

              MediaServerService service = new MediaServerService();

              MediaServer vo = service.queryByID(ID);

              ftptest.login(vo.getServerip(), vo.getServerport(), vo.getUsername(),

                            vo.getPassword());

              if (root.equals("source"))

                     json = ftptest.listfile(vo.getServerroot());

              else

                     json = ftptest.listfile(root);

              out.print(json);

              out.flush();

              out.close();

              ftptest.close();

              log.info("Quit ListFTPFileAction Class");

              return null;

       }

 

}

 以上代码有我取FTP数据的内容,所以看起来乱了点。其实形成树后台要传递的内容主要就是:

              response.setHeader("Cache-Control", "no-cache");

              response.setContentType("text/json;charset=UTF-8");//注意这里是text/json

              response.setCharacterEncoding("UTF-8");

              PrintWriter out = response.getWriter();

              String root = request.getParameter("root");//treeview定义了一个root变量,初次访问时固定值为“source”,再次访问时将用你当前所选节点的id来赋值给root,这些都可以配置,但为了简便,我没有改。想自己配置的就自己看treeview的源代码,不多,很容易看懂。

if (root.equals("source"))  //如果是第一次访问,则只传递FTP根目录下的所有目录及文件

                     json = ftptest.listfile(vo.getServerroot());

              else

                     json = ftptest.listfile(root); //否则,把当前所选目录的路径返回赋值给root(其实就是ul标签的id属性值,为实现项目功能,我把目录路径作为了标签的id

              out.print(json); //json串返回给页面

              out.flush();

              out.close();

 

以下是我把FTP目录结构包装成json串的代码,主要是让大家看一下怎样组织json串。

Java生成json要用到以下jar包:

commons-collections-3.1.jarcommons-lang-2.0.jar commons-logging-1.1.1.jarcommons-net-2.0.jar ezmorph-1.0.4.jar json-lib-2.1-jdk13.jar,共六个。

各种Java数组或者listjson的代码网上随便就能找到,以下仅供参考。

    public String listfile(String path)

    {

       FTPFile[] ftpfiles=getFiles(path);//取得了一个文件数组

       int i;

       int k;

       if(path.equals("/")) k=0;

       else k=2;

       JSONArray baseArray = new JSONArray();   

       for(i=k;i<ftpfiles.length;i++)

       {  

           JSONObject baseObject = new JSONObject();

           String name=null;

           try {

              name = new String(ftpfiles[i].getName().trim().getBytes("ISO8859-1"),"UTF-8");

           } catch (UnsupportedEncodingException e) {             

              e.printStackTrace();

           }

           if(ftpfiles[i].isDirectory())

           {

                if(path.equals("/"))

                    baseObject.put("id",path+name );

                else baseObject.put("id",path+"/"+name );

                baseObject.put("classes", "folder");

               baseObject.put("hasChildren", true);

           }

           else

           {

               if(path.equals("/"))

                baseObject.put("path",path+name );

               else baseObject.put("path", path+"/"+name);

               baseObject.put("classes", "file");

           }

           baseObject.put("text",name );          

           baseArray.add(baseObject);     

       }

       String json =null;

       if(baseArray!=null)

         json= baseArray.toString();

       else json="[]";

       System.out.println(json);

       return json;

    }

上面的大概意思就是取得当前目录下所有目录及文件,自定义属性”path””classes”treeview中自带的样式所需属性,”text”属性是节点要显示的名称,其实这些就是ul/li标签的属性。

至于要在js树上加上链接,及返回参数等等动作就要改jquery.treeview.async.js文件的代码了,以下是我修改的部分代码,大家可以参考下载的源码对比一下。

function load(settings, root, child, container) {

    $.getJSON(settings.url, {root: root}, function(response) {

       function createNode(parent) {     

       if((this.id+"")!="undefined")     

          var current = $("<li/>").attr("id", this.id ).html("<span>" + this.text + "</span>").appendTo(parent);

       else      

          var current = $("<li/>").attr("id", this.id||"").html("<span><a href=/"javascript:returnID('"+this.path+"');/" >" + this.text + "</a></span>").appendTo(parent);

      

           if (this.classes) {

              current.children("span").addClass(""+this.classes);

             

           }

           if (this.expanded) {

              current.addClass("open");

           }

           if (this.hasChildren || this.children && this.children.length) {

              var branch = $("<ul/>").appendTo(current);

              if (this.hasChildren) {

                  current.addClass("hasChildren");

                  createNode.call({

                     text:"placeholder",

                     id:"placeholder",

                     children:[]

                  }, branch);

              }

              if (this.children && this.children.length) {

                  $.each(this.children, createNode, [branch])

              }

           }

       }

       $.each(response, createNode, [child]);

        $(container).treeview({add: child});

    });

}

上面的大概意思就是,属性为目录的节点都有id属性,而属性为文件的节点没有id属性但多了一个返回当前路径的链接。页面上接收传递回的pathjs代码如下:

function returnID(Path)

{

 if(Path!="undefined")

  document.getElementById("Path").value=Path;

  else document.getElementById("Path").value="";

}

 

+++++++++++++++++++++++++++++++++++

到这里,整个目录树就算是完成了。生成的树与treeview示例中的树一样。

3.上面是分开来说,可能第一次接触这东西会觉得很乱。那么总体来讲一下整个过程就是:

从主页面通过struts配置的action跳转到dialog页面,dialog页面加载完成后执行jquery脚本语言,(根据url)去struts配置中寻找source.do并执行相应的action,该action返回封装好的json串给jsp页面(通过out输出),jsp页面所加载的treeview的代码在接收到数据后形成正确的树结构。

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值