多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
**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> ~~~ ![](https://box.kancloud.cn/2016-03-23_56f252d6ae573.gif)   后台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]):''),"&nbsp;</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]):''),"&nbsp;</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); } } }); ~~~