我是为了实现树的拖动才开始学习extjs的,它也让我感到了extjs的强大,我就直接贴代码了。

一、实现树的jsp页面,我是直接将extjs写到jsp页面的,格式有点乱,呵。。。。。

<%@ page language="java" import="java.util.*,java.lang.*"
    contentType
="text/html; charset=GBK" isErrorPage="true"
%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  
<head>
    
    
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
    
<title></title>
    
<link rel="stylesheet" href="../resources/css/ext-all.css" />
    
<link rel="stylesheet" href="../resources/css/xtheme-default.css" />
    
<script language="javascript" src="../js/ext/ext-base.js"></script>
    
<script language="javascript" src="../js/ext/ext-all.js"></script>
    
<script language="javascript" src="<c:url value='/js/xmlHttpHelper.js'/>"></script>
    
<script type="text/javascript">
        
var Tree = Ext.tree;
        
var tree = null;
        Ext.onReady(
function(){
            tree 
= new Tree.TreePanel({
            el:
'tree-div',
            onlyLeafCheckable:
false,
            rootVisible: 
true,
            autoScroll:
true,
            animate:
false,//是否动画
            enableDD:true,// 是否支持拖放
            containerScroll:true,
            lines:
true
            checkModel:
'cascade',
            loader:
new Tree.TreeLoader({dataUrl:'../info/rss.do?method=getJsonArray',
                           baseAttrs: 
{uiProvider: Ext.tree.TreeCheckNodeUI}
            }
)
          }
);
        
    
// set the root node
    var root = new Tree.AsyncTreeNode(
        
{
        
"text":"我的网摘",
        
"id":"01",
        
"allowDrag":false   //false表示不能被拖动
        
        }

    
    );


    
     
//绑定节点加载之前事件
    tree.on('beforeload',function(node){   
        
if(node.id!='01'){
              tree.loader.dataUrl 
= '../info/rss.do?method=getChildJsonArray&nodeid='+node.id;
          }

    }
); 
    

    
//绑定节点点击事件
    /*
    tree.on('click', function(node){
        if(node.id!='root'){
            alert(node.id);
            alert(node.text);
            alert(node.href);
        }
    });
    
*/

   

    

    
//绑定节点拖动事件,找了很久树节点拖动的实现,终于在老外的帖子发现上了这个实现,拖动以后所需的信息已经捕获,与后台联动的函数 加上即可实现TREE的拖拽
   tree.on('nodedrop'
      
function(e){   
                           
         
if(e.point=='append'){   
            alert(
'当前"【'+e.dropNode.text+'】"被放到目录"【'+e.target.text+'】"下!');   
            
var resultUrl = "../info/rss.do?method=treeNodeTuoDong&currenRootId="+e.dropNode.id+"&parentRootId="+e.target.id+"&type=append";
            
var resulthtml = XmlHttpHelper.transmit(false"get""text", resultUrl, nullnull);
         }

         
         
else if(e.point=='above'){   
            
//alert('当前"'+e.dropNode.text+'"放在了"'+e.target.text+'"上面!');   
             var resultUrl = "../info/rss.do?method=treeNodeTuoDong&currenRootId="+e.dropNode.id+"&parentRootId="+e.target.id+"&type=above";
             
var resulthtml = XmlHttpHelper.transmit(false"get""text", resultUrl, nullnull);
         }
else if(e.point=='below'){   
            
//alert('当前"'+e.dropNode.text+'"放在了"'+e.target.text+'"下面!'); 
             var resultUrl = "../info/rss.do?method=treeNodeTuoDong&currenRootId="+e.dropNode.id+"&parentRootId="+e.target.id+"&type=below";
            
var resulthtml = XmlHttpHelper.transmit(false"get""text", resultUrl, nullnull);  
         }
 
           
       }
 
    );
    
    
//绑定节点右键菜单功能
    
    tree.on(
'contextmenu',function(node,event){  
         
// alert("node.id="+ node.id);
          event.preventDefault(); //这行是必须的
          rightClick.showAt(event.getXY());//取得鼠标点击坐标,展示菜单
          //alert(node.id);
          document.getElementById('rootid').value=node.id;
         }
); 
         
         
     
//定义右键菜单
    var rightClick = new Ext.menu.Menu({
        id :
'rightClickCont',
        items : [
{
            id:
'rMenu1',
            text : 
'编辑',
            
//增加菜单点击事件
            handler:function (node){
                 
//alert(node.dropNode.id);
            }

        }
{
            id:
'rMenu2',
            text : 
'删除'
        }
{
            id:
'rMenu3',
            text : 
'菜单3'
        }
]
     }
);


    tree.setRootNode(root);
    
// render the tree
    tree.render();
    root.expand();
  }
);
    
</script>
  
</head>
  
  
<body>
      <div id="tree-div" style="overflow:auto;width:98%;"></div>
  
</body>
</html>

注意dataUrl的值,那个action就是动态读取json数据的action,如下:
public ActionForward getJsonArray(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
{
        FndUser user 
= (FndUser) request.getSession().getAttribute(
                HASConstants.SESSION_USER);
        JSONArray jsonArray
=this.getJson(user);    
        response.setContentType(
"text/json; charset=GBK");     
            
try {    
                response.getWriter().print(jsonArray);    
            }
 catch (Exception e) {    
                log.error(
"输出json失败"+e.getMessage());    
                
return null;    
            }
    

        
return null;
    }


我读取的json数据是第一层节点
public JSONArray  getJson(FndUser user)
    
{
        List list  
= new ArrayList(); 
        List userContentslist 
= getUserRssContents(user);
        
for(Iterator iter=userContentslist.iterator();iter.hasNext();)
        
{
            String[] userContent
=(String[])iter.next();
            Map tree 
= new HashMap();    
            tree.put(
"text", userContent[1]);
            tree.put(
"id", userContent[0]);
            list.add(tree);
        }

        
        JSONArray jsonArray 
= JSONArray.fromObject(list);    
        
return jsonArray;
    }

二、当点击第一层节点时,会异步绑定下级节点,在绑定下级节点前,会调用beforeload函数
          tree.loader.dataUrl = '../info/rss.do?method=getChildJsonArray&nodeid='+node.id
         根据传入的上级节点的节点ID,得到其下级节点的json格式的数据
         
public ActionForward getChildJsonArray(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
{
        FndUser user 
= (FndUser) request.getSession().getAttribute(
                HASConstants.SESSION_USER);
        
        String nodeid
=request.getParameter("nodeid");
        
        List list  
= new ArrayList(); 
        List urllisttree 
= getUserRssUrl(user,nodeid);
        
for(Iterator iterurl=urllisttree.iterator();iterurl.hasNext();)
        
{
            String[] userUrl
=(String[])iterurl.next();;
            Map url 
= new HashMap(); 
            url.put(
"text", userUrl[2]);
            url.put(
"id", userUrl[0]);
            url.put(
"href""../info/rss.do?method=getRssComent&rssurl="+userUrl[1]);
            url.put(
"hrefTarget""rssiframe");
            url.put(
"allowDrag", Boolean.TRUE);
            url.put(
"leaf", Boolean.TRUE);
            list.add(url);
            
        }

        
        JSONArray jsonArray 
= JSONArray.fromObject(list);     
        response.setContentType(
"text/json; charset=GBK");     
            
try {    
                response.getWriter().print(jsonArray);    
            }
 catch (Exception e) {    
                log.error(
"输出json失败"+e.getMessage());    
                
return null;    
            }
    

        
return null;
    }

这样,就实现了异步加载,看起来真是很简单哦

对于拖动事件,也是一样的,调用action,来更改文件夹之间的上下级关系,并实现后台的更新数据库,由于处于学习阶段,代码不尽合理。

xmlHttpHelper.js
function XmlHttpHelper(){}

XmlHttpHelper.__getXmlHttpObj 
= function()
{
    
try
    
{
        
return new ActiveXObject("MSXML2.XMLHTTP");
    }

    
catch(e)
    
{
        
try
        
{
            
return new XMLHttpRequest();
        }

        
catch(ee)
        
{
            
throw(new Error(-1"无法创建XMLHTTP对象。"));
        }

    }

}
;

//
//
  使用XMLHTTP和远程服务器通信。
//
//
    async            是否为异步方式:true/false
//
    httpMethod        http方法:"post"/"get"
//
    responseType    返回数据的类型:"text"/"xml"/null
//
    url                请求的URL地址
//
    callback        异步操作完成时执行的回调函数
//
    postData        post方式时发送的数据
//
XmlHttpHelper.transmit = function(async, httpMethod, responseType, url, callback, postData)
{
    
var xmlhttp = this.__getXmlHttpObj();
    xmlhttp.open(httpMethod, url, async);
    
    
if(!async && httpMethod.toLowerCase() == "post")
    
{
        xmlhttp.setRequestHeader(
'Content-Length', postData.length);
        xmlhttp.setRequestHeader(
"Content-Type""application/x-www-form-urlencoded;charset=UTF-8");
    }


    
if(async)
    
{
        xmlhttp.onreadystatechange 
= function()
        
{
            
if(xmlhttp.readyState == 4)
            
{
                
try
                
{
                    
if(responseType != null)
                    
{
                        
if(responseType.toLowerCase() == "text")
                            callback(xmlhttp.responseText);
                        
else if(responseType.toLowerCase() == "xml")
                            callback(xmlhttp.responseXML);
                    }

                    
else
                    
{
                        callback(
null);
                    }

                }

                
finally
                
{
                    xmlhttp 
= null;
                }

            }

        }

        xmlhttp.send(postData);
    }

    
else
    
{
        xmlhttp.send(postData);
        
if(xmlhttp.status == 200)
        
{
            
if(responseType != null)
            
{
                
if(responseType.toLowerCase() == "text")
                    
return xmlhttp.responseText;
                
else if(responseType.toLowerCase() == "xml")
                    
return xmlhttp.responseXML;
            }

            
else
            
{
                
return null;
            }

        }

        
return null;
    }

}
;
posted on 2008-07-17 14:07  huazi4995  阅读(6250)  评论(1编辑  收藏  举报