extjs的tree的使用(拖动、动态载入json数据、拖动后的事件处理)

本文介绍如何利用ExtJS框架实现树形控件的动态加载及交互功能,包括节点的点击、拖拽等事件处理,并通过AJAX技术实现与后台的数据交换。

<%@ 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, null, null);
         }

         
         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, null, null);
         }
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, null, null);  
         }
 
           
       }
 
    );
    
    //绑定节点右键菜单功能
    
    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;
    }

}
;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值