首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Web前端 >

ext TreePanel应用

2012-09-01 
ext TreePanel使用1.首先还是主要的显示页面tree.html,这里有两个地方要注意一下,一个是我们引用的JS如果

ext TreePanel使用

1.首先还是主要的显示页面tree.html,这里有两个地方要注意一下,一个是我们引用的JS如果采用GBK的默认编码,浏览器会显示未结束的字符串常量的错误,所以我们一般会修改JS文件的编码方式为UTF-8,或者在导入JS时加上编码字符集。第二个是我们要定义一个显示TreePanel的DIV。<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title><link rel="stylesheet" type="text/css" href="resources/css/ext-all.css" /><script type="text/javascript" src="resources/js/ext-base.js"></script><script type="text/javascript" src="resources/js/ext-all.js"></script><script type="text/javascript" src="resources/js/tree.js" charset="gbk"></script></head><body><div id="tree-panel" style="overflow:auto; height:300px;width:200px;border:2px solid #c3daf9;"></div></body></html>2.然后是我们的主体JS文件,tree.jsExt.onReady(function() {Ext.QuickTips.init();// 浮动信息提示Ext.BLANK_IMAGE_URL = 'resources/images/default/s.gif';// 替换图片文件地址为本地// 创建一个简写var Tree = Ext.tree;// 定义根节点的Loadervar treeloader = new Tree.TreeLoader({// dataUrl : 'tree.jsp'//这里可以不需要指定URL,在加载前事件响应里面设置});// 添加一个树形面板var treepanel = new Tree.TreePanel({// renderTo:"tree_div",//如果使用renderTo,则不能使用setRootNode()方法,需要在TreePanel中设置root属性。el : 'tree-panel',// 将树形添加到一个指定的div中,非常重要!region : 'west',title : '功能菜单',width : 200,minSize : 180,maxSize : 250,split : true,autoHeight : false,frame : true,// 美化界面// width : 200,//面板宽度// title : '可编辑和拖动的异步树',//标题// autoScroll : true, // 自动滚动enableDD : true,// 是否支持拖拽效果containerScroll : true,// 是否支持滚动条rootVisible : true, // 是否隐藏根节点,很多情况下,我们选择隐藏根节点增加美观性border : true, // 边框animate : true, // 动画效果loader : treeloader// 树加载});// 异步加载根节点var rootnode = new Tree.AsyncTreeNode({id : '0',text : '家电品牌总类',draggable : false,// 根节点不容许拖动expanded : true});// 为tree设置根节点treepanel.setRootNode(rootnode);// 响应加载前事件,传递node参数treepanel.on('beforeload', function(node) {treepanel.loader.dataUrl = 'tree.jsp?parentId=' + node.id; // 定义子节点的Loader});// 渲染树形treepanel.render();// 展开节点,第一个参数表示是否级联展开子节点rootnode.expand(true);// 设置树的点击事件function treeClick(node, e) {if (node.isLeaf()) {e.stopEvent();var n = contentPanel.getComponent(node.id);if (!n) {var n = contentPanel.add({'id' : node.id,'title' : node.text,closable : true,autoLoad : {url : 'tabFrame.jsp?url=grid.html',scripts : true} // 通过autoLoad属性载入目标页,如果要用到脚本,必须加上scripts属性});}contentPanel.setActiveTab(n);}}// 增加鼠标单击事件treepanel.on('click', treeClick);// 定义右键菜单var rightClick = new Ext.menu.Menu({id : 'rightClickCont',items : [{id : 'rMenu1',text : '添加节点',// 增加菜单点击事件handler : function() {alert('添加节点的实现!');}}, {id : 'rMenu2',text : '编辑节点'}, {id : 'rMenu3',text : '删除节点'}]});// 增加右键点击事件treepanel.on('contextmenu', function(node, event) {// 声明菜单类型event.preventDefault();// 阻止浏览器默认右键菜单显示rightClick.showAt(event.getXY());// 取得鼠标点击坐标,展示菜单});/* * 设置tree的节点放置函数此函数有一个很重要的参数对象e e对象有三个重要的属性,分别为dropNode,target,point * 1.dropNode为在拖动时鼠标抓住的节点 2.target为将要放置在某处的节点 * 3.point为被放置的状态,分别有append表示添加,above节点的上方,below节点的下方。 *  */treepanel.on('nodedrop', function(e) {if (e.point == 'append') {alert('当前"' + e.dropNode.text + '"划到"' + e.target.text+ '"里面!');} else if (e.point == 'above') {alert('当前"' + e.dropNode.text + '"放在了"' + e.target.text+ '"上面!');} else if (e.point == 'below') {alert('当前"' + e.dropNode.text + '"放在了"' + e.target.text+ '"下面!');}});// 在原有的树形添加一个TreeEditorvar treeEditer = new Tree.TreeEditor(treepanel, {allowBlank : false});/* * 为创建的treeEditer添加事件 有两个事件最为常用,一个为beforestartedit另一个为complete * 从名字就可以看出,beforestartedit事件是在编辑前的事件,因此可以通过它来判断那些节点可以编辑那些不可以。 * complete为编辑之后的事件,在这里面可以添加很多事件,比如添加一个Ext.Ajax向后台传送修改的值等等。 */treeEditer.on("beforestartedit", function(treeEditer) {var tempNode = treeEditer.editNode;// 将要编辑的节点if (tempNode.isLeaf()) {// 这里设定叶子节点才容许编辑return true;} else {return false;}});treeEditer.on("complete", function(treeEditer) {alert("被修改为" + treeEditer.editNode.text);});// (1)通过TabPanel控件的html属性配合<iframe>实现。该方法是利用// html属性中包含<iframe>的语法来调用另一个页面,具体见代码。// (2)通过TabPanel控件的autoLoad属性实现。该方法是利用autoLoad属性,它有很多参数,// 其中有两个比较重要,url表示要载入的文件,scripts表示载入的文件是否含有脚本,该属性相当重要,// 如果在新的页面中要创建Ext控件,必须指定该参数。该方法实现较前一个复杂,因为引入的文件不是一个完整的html文件,// 有可能只是内容的一部分,但是资源占用较少,而且载入速度较快(它有一个载入指示)// 添加第一个节点(html)treepanel.root.appendChild(new Ext.tree.TreeNode({id : 'htmlPanel',text : '通过html打开',listeners : {'click' : function(node, event) {event.stopEvent();var n = contentPanel.getComponent(node.id);if (!n) { // 判断是否已经打开该面板n = contentPanel.add({'id' : node.id,'title' : node.text,closable : true, // 通过html载入目标页html : '<iframe scrolling="auto" frameborder="0" width="100%" height="100%" src="grid.html"></iframe>'});}contentPanel.setActiveTab(n);}}}));// 添加第二个节点(autoLoad)treepanel.root.appendChild(new Ext.tree.TreeNode({id : 'autoLoadPanel',text : '通过autoLoad打开',listeners : {'click' : function(node, event) {event.stopEvent();var n = contentPanel.getComponent(node.id);if (!n) { // //判断是否已经打开该面板n = contentPanel.add({'id' : node.id,'title' : node.text,closable : true,autoLoad : {url : 'tabFrame.jsp?url=grid.html',scripts : true} // 通过autoLoad属性载入目标页,如果要用到脚本,必须加上scripts属性});}contentPanel.setActiveTab(n);}}}));// 右边具体功能面板区var contentPanel = new Ext.TabPanel({region : 'center',enableTabScroll : true,activeTab : 0,items : [{id : 'homePage',title : '首页',autoScroll : true,html : '<div style="position:absolute;color:#ff0000;top:40%;left:40%;">Tree控件和TabPanel控件结合功能演示</div>'}]});new Ext.Viewport({layout : 'border', // 使用border布局defaults : {activeItem : 0},items : [treepanel, contentPanel]});});3.   再接着是tree.js中ExtJS的TreeLoader调用的tree.jsp,在目录树上点击TreeNode后会加载下一级节点。tree.jsp负责TreeNode点击后,传回由下一级节点构造的JSON数据,也就是前台树异步请求访问的后台WEB组件。它会调用JAVABEAN操作数据库,得到每个节点的子节点数据。这里由于我们后台需要返回给客户端JSON格式的数据,也就是需要操作JSON数据格式。所以我们首先要下载JSON-lib,地址:http://json-lib.sourceforge.net/打开网址后,首页上有一段话:  Json-lib requires (at least) the following dependencies in your classpath:       jakarta commons-lang 2.3       jakarta commons-beanutils 1.7.0       jakarta commons-collections 3.2       jakarta commons-logging 1.1.1       ezmorph 1.0.4    需要下载上述jar文件,配合JSON-lib 一起使用。    commons 下载地址:http://commons.apache.org/    ezmorph 下载地址:http://ezmorph.sourceforge.net    或者,到 http://www.docjar.com 搜索下载。    JSON的用法,我们已经提过多次,大家可参考相关文档。看看tree.jsp的代码:<%@ page language="java" pageEncoding="utf-8"%><jsp:useBean id="JSONTree"></jsp:useBean><%String parentId = "";if (request.getParameter("parentId") != null) {parentId = request.getParameter("parentId").toString();}JSONTree.setparentId(parentId);%><%=JSONTree.getJSONString()%>4. 后台用到的JAVA类,这里包括访问数据库的数据源工厂类DataSourceFactory(这里用到了DBCP连接池,大家要记得导入连接sqlserver 2000数据库和dbcp连接池的相关JAR包!),定义树节点的属性,包括节点ID、Text、图标、是否为叶子节点、是否展开等的类JSONTreeNode,还有类似DAO能够封装数据访问和格式转换细节的JSONTree。package org.leno.javabean;import java.sql.SQLException;import org.apache.commons.dbcp.BasicDataSource;public class DataSourceFactory {/** * @param args */private static BasicDataSource ds;public static BasicDataSource getDataSource() {if (ds == null) {ds = new BasicDataSource();ds.setDriverClassName("com.microsoft.jdbc.sqlserver.SQLServerDriver");ds.setUrl("jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=java28");ds.setUsername("sa");ds.setPassword("123");ds.setMaxActive(5);}        return ds;}public static void main(String[] args) {// TODO Auto-generated method stubtry {System.out.println(DataSourceFactory.getDataSource().getConnection());} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}package org.leno.javabean;/** * @author leno *定义树节点的属性,包括节点ID、Text、图标、是否为叶子节点、是否展开等。 */public class JSONTreeNode {  private String id;            //ID      private String text;          //节点显示      private String cls;           //图标      private boolean leaf;         //是否叶子      private String href;          //链接      private String hrefTarget;    //链接指向      private boolean expandable;   //是否展开      private String description;   //描述信息      get/set…… }package org.leno.javabean;import java.sql.*;import java.util.*;import net.sf.json.JSONArray;public class JSONTree {private String parentId;         public String getJSONString(){              Connection con =null;         Statement st = null;         ResultSet rs = null;         List<JSONTreeNode> treeNodeArray = null;                 String SQLString = "SELECT * FROM Categories WHERE parentId="+this.parentId+" ORDER BY categoryId";                        try         {             con = DataSourceFactory.getDataSource().getConnection();            st = con.createStatement();             //查找所有拥有下级类别的类别ID            rs = st.executeQuery("SELECT parentId FROM Categories WHERE parentId>0 Group By parentId Order By parentId");                                    StringBuffer parentIDBuffer =new StringBuffer();             parentIDBuffer.append("|");                     while(rs.next())             {                 parentIDBuffer.append(rs.getString("parentId"));                 parentIDBuffer.append("|");             }             //得到所有的parentcategoryId列表             String parentIDString = parentIDBuffer.toString();                                 rs = st.executeQuery(SQLString);                treeNodeArray = new ArrayList<JSONTreeNode>();             while(rs.next())             {                 JSONTreeNode treeNode = new JSONTreeNode();                 String categoryId = rs.getString("categoryId");                treeNode.setId(categoryId);                 treeNode.setText(rs.getString("categoryName"));                 treeNode.setDescription(rs.getString("description"));          //                    treeNode.setHref("rightframe.jsp?categoryId="//+ rs.getString("categoryId").toString()); //                    treeNode.setHrefTarget("rightFrame");                                               if (parentIDString.indexOf("|"+categoryId+"|")>=0) //父节点                     {                         treeNode.setCls("folder");                         treeNode.setLeaf(false);                         treeNode.setExpandable(false);                     }                     else //子节点                    {                         treeNode.setCls("file");                         treeNode.setLeaf(true);                         treeNode.setExpandable(false);                     }                     treeNodeArray.add(treeNode);             }                         JSONArray JsonArray = JSONArray.fromObject(treeNodeArray); //得到JSON数组                 return JsonArray.toString();//返回JSON数据         }         catch(Exception e)         {             System.out.println("getJSONString() of JSONTree.java throws : "+e.toString());             return "";         }         finally         {            try {           if(con!=null&&!con.isClosed()){           con.close();           }} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}        }     }       public String getparentId() {         return parentId;     }     public void setparentId(String parentId) {         this.parentId = parentId;     } }5.最后是我们的数据库脚本script.sql,大家用SQLServer 2000数据库创建一个java28的database,然后执行下列脚本即可。create table Categories(categoryId int identity(1,1) primary key,categoryName varchar(30),description varchar(100),parentId int)insert into Categories values('电脑','关于电脑',0);insert into Categories values('电视机','关于电视机',0);insert into Categories values('数码相机','关于数码相机',0);insert into Categories values('冰箱','关于冰箱',0);insert into Categories values('联想电脑','关于联想电脑',1);insert into Categories values('创维电视机','关于创维电视机',2);insert into Categories values('索尼相机','关于索尼相机',3);insert into Categories values('海尔冰箱','关于海尔冰箱',4);insert into Categories values('旭日电脑','关于旭日电脑',5);insert into Categories values('天逸电脑','关于天逸电脑',5);insert into Categories values('创维液晶电视','关于创维液晶电视机',6);insert into Categories values('索尼M23相机','关于索尼M23相机',7);insert into Categories values('海尔G1冰箱','关于海尔G1冰箱',8);select * from CategoriesSELECT parentId FROM Categories WHERE parentId>0 Group By parentId Order By parentIdExtJS只要求返回的数据格式类似下面这样即可:[{'text':'welcome.html','id':'welcome.html','cls':'file',myPara:'myValue'},{'text':'welcome2.html','id':'welcome2.html','leaf':true,'cls':'file','href':'welcome2.html'}]这些数据是存储到一个数组中的,数组中的每一项代表一个节点,每一个节点都包含以下几个主要属性:text:定义该节点显示的名称;id:定义该节点的页面ID,便于document.getElementById方法获取该节点;leaf:true或者false,定义该节点是否是叶子节点;cls:定义该节点的class(显示的样式);href:定义点击该节点后链接的页面;另外你还可以为节点增加自定义的属性,方法如上面的myPara:'myValue'一样。ExtJS会自动将返回的数据解析成节点并正确显示到页面上。

热点排行