学习使用jquery以来,一直没找到一棵简单并且支持异步加载的树,无奈只有自己扩展一下。jquery官方ui的treeView功能单一且不够小巧。偶然发现SimpleTree 插件发现它小巧而且支持拖拽很方便扩展,于是在simpleTree基础上做了json格式数据异步加载和树上使用的图片路径自适应的扩展。做的较为粗糙,请大家指点!
因为实在实际项目中使用,下面的例子是基于struts2的,除struts2环境还需要struts-json插件jsonPlugin ,对于直接使用servlet仅需要使用jsonlib中的静态方法将java List转换为json字符串。
修改后树的初始化方式
$(document).ready(function(){ simpleTreeCollection = $('#simpleTree').simpleTree({ autoclose: true, animate:true, dataType:"json", url:"tree!demoTest.action" }); });
<body>
<ul id="simpleTree" class="simpleTree">
</ul>
</body>
修改后的初始化树的默认选项的代码
TREE.option = { drag: true, animate: false, autoclose: false, speed: 'fast', afterAjax: false, afterMove: false, afterClick: false, afterDblClick: false, // added by Erik Dohmen (2BinBusiness.nl) to make context menu cliks available afterContextMenu: false, docToFolderConvert:false, //***added by Bluespring to enable json dataType*** dataType:"json", //value is json or html async:true, jsonWrap:{//if your dataType of json differ from following default type,you can wrap it id:"id",//node id parentId:"parentId",//parent node id text:"text",//node text isfolder:"isfolder",//indication node whether or not folder, value is true or false,if not need, set it to null for nothing to do attrs:"attrs"//addition data for special action to customize function,if not need, set it to null for nothing to do }, url:null, //if null,will use simple tree default setting. if not null,simpleTree defalut setting will be cover parm:{},//parameters for ajax request, always add or overwrite a key/value(key:jsonWrap.id,value:folder id) when expand folder responseDataName:"nodes",//if your java nodeList name differ from "nodes", set it as your nodeList name treeName:"tree" };
E文不好注释有点乱,请大家别介意。代码中的jsonWrap选项是转换器,有了它我们就不必在后台封装特定对象的List传出来,只有返回List中的对象具有对应于id、parentId、text的属性就可以。当然如果你界面上自定制的功能需要用到额外的数据的话,必须的在后台自己封装如下的对象的List
package util.tree.bean;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class SimpleTreeNode {
private Object id;
private String text;
private Object parentId;
/**
* 仅用于需要异步读取数据的文件夹节点。当节点有子节点时,该属性不起作用。节点永远为文件夹节点
*/
private boolean isFolder=false;
private HashMap<String, Object> attrs=new HashMap<String,Object>();
public SimpleTreeNode(Object id, String text,Object parentId){
this.id=id;
this.text=text;
this.parentId=parentId;
}
public SimpleTreeNode(Object id, String text, Object parentId,boolean isFolder){
this.id=id;
this.text=text;
this.parentId=parentId;
this.isFolder=isFolder;
}
public SimpleTreeNode(Object id, String text, Object parentId,boolean isFolder,HashMap<String,Object> attrs){
this.id=id;
this.text=text;
this.parentId=parentId;
this.isFolder=isFolder;
this.attrs=attrs;
}
public void addAttribute(String key,Object value){
this.attrs.put(key, value);
}
public Object getId() {
return id;
}
public void setId(Object id) {
this.id = id;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Object getParentId() {
return parentId;
}
public void setParentId(Object parentId) {
this.parentId = parentId;
}
public boolean isFolder() {
return isFolder;
}
public void setFolder(boolean isFolder) {
this.isFolder = isFolder;
}
public HashMap<String, Object> getAttrs() {
return attrs;
}
public void setAttrs(HashMap<String, Object> attrs) {
this.attrs = attrs;
}
}
js端使用异步数据生成树节点代码
//***added by Bluespring for auto imgPath*** //get js path var jsPath = ""; var js = $("script[src]").get(); for (var i = js.length; i > 0; i--) { if (js[i - 1].src.indexOf("tree.js") > -1) { jsPath = js[i - 1].src.substring(0, js[i - 1].src.lastIndexOf("/") + 1); } } //***added by Bluespring to enable json dataType*** var coverJsonToHtml=function(nodeArray){ //create tree node var ul=$("<ul>"); var nodeWrap=TREE.option.jsonWrap; var tempLi=null; for(var i in nodeArray){ tempLi=$('<li id="'+nodeArray[i][nodeWrap.id]+'"><span>'+nodeArray[i][nodeWrap.text]+'</span></li>'); if(nodeWrap.attrs!=null){ tempLi.attr(nodeArray[i][nodeWrap.attrs]); } if(null!=nodeArray[i][nodeWrap.parentId]){ tempLi.get(0).parentId=nodeArray[i][nodeWrap.parentId]; tempLi.get(0).isFolder=nodeWrap.isFolder!=null?nodeArray[i][nodeWrap.isFolder]:false; } ul.append(tempLi); } //arrange tree node var parentLi=null; $("> li",ul).each(function(){ if(this.parentId){ parentLi=$("#"+$(this).attr("parentId"),ul); if($("ul",parentLi).size()==0){ parentLi.append("<ul>"); } $(this).appendTo($("ul",parentLi)); } if(this.isFolder&&$("ul",this).size()==0){ $(this).append("<ul>"); } }); $("ul",ul).each(function(){ if($("li",this).size()==0){ $(this).addClass("ajax"); } }); return ul; };
在此附上测试用的action类及struts配置
package org.wisdoor.web.util;
import java.util.ArrayList;
import java.util.List;
import org.wisdoor.web.WisdoorAction;
import util.tree.bean.SimpleTreeNode;
public class TreeAction extends WisdoorAction {
private List<SimpleTreeNode> nodes=new ArrayList();
public String demoTest(){
for(int i=0;i<10;i++){
nodes.add(new SimpleTreeNode(""+i,"node_"+i,null,true));
for(int n=0;n<5;n++){
nodes.add(new SimpleTreeNode((""+i)+"_"+n,"node_"+i+"_"+n,""+i));
}
}
return SUCCESS;
}
public List<SimpleTreeNode> getNodes() {
return nodes;
}
public void setNodes(List<SimpleTreeNode> nodes) {
this.nodes = nodes;
}
}
<!-- Tree --> <package name="tree" extends="json-default"> <action name="tree" class="org.wisdoor.web.util.TreeAction" > <result type="json"> <param name="ignoreHierarchy"> false </param> </result> </action> </package>
在插件目录下有测试用的页面,需要后台准备数据
修改了TREE的初始化参数,新增了parm参数和responsDateName参数,parm是访问数据需要传后台的数据,responsDateName是后台返回的list的name
更新了war包,现在应该不会报错了。