checkBoxColunmTree.html
可以选择节点的多列的树,也可以说是可以分组选择的grid。既是tree也是grid。
column-tree.css这个文件在ext2.2版本中的ext-2.2/examples/tree这个目录下会找到这个文件的。
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html>
- <head>
- <title>checkBoxColunmTree.html</title>
- <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
- <meta http-equiv="description" content="this is my page">
- <meta http-equiv="content-type" content="text/html; charset=UTF-8">
- <link rel="stylesheet" type="text/css" href="ext/resources/css/ext-all.css" />
- <link rel="stylesheet" type="text/css" href="ext/resources/css/column-tree.css" />
- <script type="text/javascript" src="ext/adapter/ext/ext-base.js"></script>
- <script type="text/javascript" src="ext/ext-all.js"></script>
- <script type="text/javascript" src="ext/ColumnTree.js"></script>
- <script type="text/javascript">
- Ext.onReady(function () {
- Ext.BLANK_IMAGE_URL = 'ext/resources/images/default/s.gif';
- var tree = new Ext.tree.ColumnTree({
- width:568,
- height:300,
- border: false,
- lines: false,
- animate: false,
- rootVisible: false,
- autoScroll:true,
- checkModel:'cascade',//级联多选,如果不需要checkbox,该属性去掉
- onlyLeafCheckable: false,//所有结点可选,如果不需要checkbox,该属性去掉
- loader: new Ext.tree.TreeLoader({
- dataUrl: '../TreeDataServlet',//'column-data.json',
- uiProviders:{
- 'col': Ext.ux.ColumnTreeCheckNodeUI//如果不需要checkbox,则需要使用Ext.tree.ColumnTreeNodeUI
- }
- }),
- columns:[
- { header:'商品名称', width:170, dataIndex:'commodityName'},
- { header:'编号', width:70, dataIndex:'id'},
- { header:'代理/公司', width:180, dataIndex:'proxyName' },
- { header:'价格', width:70, dataIndex:'price'}
- ],
- root: new Ext.tree.AsyncTreeNode({
- text: '代理/公司'
- }),
- tbar:['公司名称:',{xtype:'textfield',id:'proxyName'},'商品名称:',{xtype:'textfield',id:'commodityName'},{text:'查询'}]
- });
- var win = new Ext.Window({
- title: 'Example column tree',
- width:582,
- height:388,
- border :true,
- resizable : false,
- items: tree,
- buttonAlign:'center',
- buttons:[{text:'确定'},{text:'关闭'}]
- });
- win.show();
- });
- </script>
- </head>
- <body>
- </body>
- </html>
后台java代码
TreeDataServlet.java
- package com.hoo.servlet;
- import java.io.IOException;
- import java.io.PrintWriter;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- public class TreeDataServlet extends HttpServlet {
- public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- this.doPost(request, response);
- }
- public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- response.setContentType("text/text");
- response.setCharacterEncoding("UTF-8");
- PrintWriter out = response.getWriter();
- StringBuffer resultStr = new StringBuffer();
- resultStr.append("[{");
- resultStr.append("id: ' 10000',");
- resultStr.append("commodityName: '微软鼠标',");
- resultStr.append("uiProvider: 'col',");
- //得到group 值
- resultStr.append("children: [{");
- resultStr.append("id: ' 100000',");
- resultStr.append("proxyName: '微软代理商-中国代理 联强 ',");
- resultStr.append("commodityName: 'IO 1.0',");
- resultStr.append("price: '198.00',");
- resultStr.append("leaf:true,");
- resultStr.append("uiProvider: 'col'},");
- resultStr.append("{id: ' 100000',");
- resultStr.append("proxyName: '微软代理商-中国代理 联强 ',");
- resultStr.append("commodityName: 'IE 3.0',");
- resultStr.append("price: '298.00',");
- resultStr.append("leaf:true,");
- resultStr.append("uiProvider: 'col'},");
- resultStr.append("{id: ' 100000',");
- resultStr.append("proxyName: '微软代理商-中国代理 联强 ',");
- resultStr.append("commodityName: 'IO 2.0',");
- resultStr.append("price: '200.00',");
- resultStr.append("leaf:true,");
- resultStr.append("uiProvider: 'col'");
- resultStr.append("}]},{");
- resultStr.append("id: ' 20000',");
- resultStr.append("commodityName: '罗技鼠标',");
- resultStr.append("uiProvider: 'col',");
- //得到group 值
- resultStr.append("children: [{");
- resultStr.append("id: ' 100001',");
- resultStr.append("proxyName: '罗技',");
- resultStr.append("commodityName: 'max 500',");
- resultStr.append("price: '298.00',");
- resultStr.append("leaf:true,");
- resultStr.append("uiProvider: 'col'},");
- resultStr.append("{id: ' 100000',");
- resultStr.append("proxyName: '罗技',");
- resultStr.append("commodityName: 'max 518',");
- resultStr.append("price: '298.00',");
- resultStr.append("leaf:true,");
- resultStr.append("uiProvider: 'col'},");
- resultStr.append("{id: ' 100000',");
- resultStr.append("proxyName: '罗技',");
- resultStr.append("commodityName: 'max 520',");
- resultStr.append("price: '245.00',");
- resultStr.append("leaf:true,");
- resultStr.append("uiProvider: 'col'");
- resultStr.append("}]");
- resultStr.append("}]");
- out.print(resultStr.toString());
- out.flush();
- out.close();
- }
- }
ext/ColumnTree.js
这个是扩展Ext.tree.ColumnTree的组件,只是添加了一个Ext.ux.ColumnTreeCheckNodeUI组件。有了这个组件我们才可以选择节点,所以这个是必须的;
- /*
- * Ext JS Library 2.0
- * Copyright(c) 2006-2007, Ext JS, LLC.
- * licensing@extjs.com
- *
- * http://extjs.com/license
- */
- Ext.tree.ColumnTree = Ext.extend(Ext.tree.TreePanel, {
- //lines:false,
- borderWidth: Ext.isBorderBox ? 0 : 2, // the combined left/right border for each cell
- cls:'x-column-tree',
- scrollOffset : 18,
- onRender : function(){
- Ext.tree.ColumnTree.superclass.onRender.apply(this, arguments);
- this.headers = this.body.createChild(
- {cls:'x-tree-headers '},this.body.dom);
- var cols = this.columns, c;
- var totalWidth = 0;
- for(var i = 0, len = cols.length; i < len; i++){
- c = cols[i];
- totalWidth += c.width;
- this.headers.createChild({
- cls:'x-tree-hd ' + (c.cls?c.cls+'-hd':''),
- cn: {
- cls:'x-tree-hd-text',
- html: c.header
- },
- style:'width:'+(c.width-this.borderWidth)+'px;'
- });
- }
- this.headers.createChild({
- cls:'x-tree-hd ',
- cn: {
- html: ''
- },
- style:'width:'+this.scrollOffset+'px;'
- });
- totalWidth += this.scrollOffset;
- this.headers.createChild({cls:'x-clear'});
- // prevent floats from wrapping when clipped
- this.headers.setWidth(totalWidth);
- totalWidth -= this.scrollOffset;
- this.innerCt.setWidth(totalWidth);
- }
- });
- Ext.tree.ColumnTreeNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
- focus: Ext.emptyFn, // prevent odd scrolling behavior
- renderElements : function(n, a, targetNode, bulkRender){
- this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
- var t = n.getOwnerTree();
- var cols = t.columns;
- var bw = t.borderWidth;
- var c = cols[0];
- var cb = typeof a.checked == 'boolean';
- if(typeof this.checkModel != 'undefined'){
- cb = (!this.onlyLeafCheckable || n.isLeaf());
- }
- var href = a.href ? a.href : Ext.isGecko ? "" : "#";
- var buf = ['<li class="x-tree-node"><div ext:tree-node-id="',n.id,'" class="x-tree-node-el x-tree-node-leaf x-unselectable ', a.cls,'" unselectable="on">',
- '<div class="x-tree-col" style="width:',c.width-bw,'px;">',
- '<span class="x-tree-node-indent">',this.indentMarkup,"</span>",
- '<img src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow">',
- '<img src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon',(a.icon ? " x-tree-node-inline-icon" : ""),(a.iconCls ? " "+a.iconCls : ""),'" unselectable="on">',
- cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '',
- '<a hidefocus="on" class="x-tree-node-anchor" href="',href,'" tabIndex="1" ',
- a.hrefTarget ? ' target="'+a.hrefTarget+'"' : "", '>',
- '<span unselectable="on">', n.text || (a[c.dataIndex]?(c.renderer ? c.renderer(a[c.dataIndex], n, a) : a[c.dataIndex]):'')," </span></a>",
- "</div>"];
- for(var i = 1, len = cols.length; i < len; i++){
- c = cols[i];
- buf.push('<div class="x-tree-col ',(c.cls?c.cls:''),'" style="width:',c.width-bw,'px;">',
- '<div class="x-tree-col-text">',(a[c.dataIndex]?(c.renderer ? c.renderer(a[c.dataIndex], n, a) : a[c.dataIndex]):'')," </div>",
- "</div>");
- }
- buf.push('<div class="x-clear"></div>',
- '</div>',
- '<ul class="x-tree-node-ct" style="display:none;"></ul>',
- "</li>");
- if(bulkRender !== true && n.nextSibling && n.nextSibling.ui.getEl()){
- this.wrap = Ext.DomHelper.insertHtml("beforeBegin",n.nextSibling.ui.getEl(), buf.join(""));
- }else{
- this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf.join(""));
- }
- this.elNode = this.wrap.childNodes[0];
- this.ctNode = this.wrap.childNodes[1];
- var cs = this.elNode.firstChild.childNodes;
- this.indentNode = cs[0];
- this.ecNode = cs[1];
- this.iconNode = cs[2];
- var index = 3;
- if(cb){
- this.checkbox = cs[3];
- index++;
- }
- this.anchor = cs[index];
- this.textNode = cs[index].firstChild;
- }
- });
- //这个组件是扩展的,加入这个组件即可
- Ext.ux.ColumnTreeCheckNodeUI = function() {
- //多选: 'multiple'(默认)
- //单选: 'single'
- //级联多选: 'cascade'(同时选父和子);'parentCascade'(选父);'childCascade'(选子)
- this.checkModel = 'multiple';
- //only leaf can checked
- this.onlyLeafCheckable = false;
- Ext.ux.ColumnTreeCheckNodeUI.superclass.constructor.apply(this, arguments);
- };
- Ext.extend(Ext.ux.ColumnTreeCheckNodeUI, Ext.tree.ColumnTreeNodeUI, {
- renderElements : function(n, a, targetNode, bulkRender){
- var t = n.getOwnerTree();
- this.checkModel = t.checkModel || this.checkModel;
- this.onlyLeafCheckable = t.onlyLeafCheckable || false;
- Ext.ux.ColumnTreeCheckNodeUI.superclass.renderElements.apply(this, arguments);
- var cb = (!this.onlyLeafCheckable || n.isLeaf());
- if(cb){
- Ext.fly(this.checkbox).on('click', this.check.createDelegate(this,[null]));
- }
- },
- // private
- check : function(checked){
- var n = this.node;
- var tree = n.getOwnerTree();
- this.checkModel = tree.checkModel || this.checkModel;
- if( checked === null ) {
- checked = this.checkbox.checked;
- } else {
- this.checkbox.checked = checked;
- }
- n.attributes.checked = checked;
- tree.fireEvent('check', n, checked);
- if(!this.onlyLeafCheckable){
- if(this.checkModel == 'cascade' || this.checkModel == 'parentCascade'){
- var parentNode = n.parentNode;
- if(parentNode !== null) {
- this.parentCheck(parentNode,checked);
- }
- }
- if(this.checkModel == 'cascade' || this.checkModel == 'childCascade'){
- if( !n.expanded && !n.childrenRendered ) {
- n.expand(false,false,this.childCheck);
- }else {
- this.childCheck(n);
- }
- }
- } else if(this.checkModel == 'single'){
- var checkedNodes = tree.getChecked();
- for(var i=0;i<checkedNodes.length;i++){
- var node = checkedNodes[i];
- if(node.id != n.id){
- node.getUI().checkbox.checked = false;
- node.attributes.checked = false;
- tree.fireEvent('check', node, false);
- }
- }
- }
- },
- // private
- childCheck : function(node){
- var a = node.attributes;
- if(!a.leaf) {
- var cs = node.childNodes;
- var csui;
- for(var i = 0; i < cs.length; i++) {
- csui = cs[i].getUI();
- if(csui.checkbox.checked ^ a.checked)
- csui.check(a.checked);
- }
- }
- },
- // private
- parentCheck : function(node ,checked){
- var checkbox = node.getUI().checkbox;
- if(typeof checkbox == 'undefined')return ;
- if(!(checked ^ checkbox.checked))return;
- if(!checked && this.childHasChecked(node))return;
- checkbox.checked = checked;
- node.attributes.checked = checked;
- node.getOwnerTree().fireEvent('check', node, checked);
- var parentNode = node.parentNode;
- if( parentNode !== null){
- this.parentCheck(parentNode,checked);
- }
- },
- // private
- childHasChecked : function(node){
- var childNodes = node.childNodes;
- if(childNodes || childNodes.length>0){
- for(var i=0;i<childNodes.length;i++){
- if(childNodes[i].getUI().checkbox.checked)
- return true;
- }
- }
- return false;
- },
- toggleCheck : function(value){
- var cb = this.checkbox;
- if(cb){
- var checked = (value === undefined ? !cb.checked : value);
- this.check(checked);
- }
- }
- });