Ext的TreeGrid增加复选框(CheckBox)与复选框操作
最近项目开发要求用树形列表显示多列数据,结构例如:
研发部
|--张三 男 25岁
|--李四 女 25岁
项目部
|--王二 男 18岁
接到任务后,首先想到的时Ext的Tree控件,但Ext.Tree.Treepanel只能显示单列数据,也就是说无法显示 "性别"和"年龄"这两个字段。
到网上查了相关资料后发现Ext拓展的TreeGrid是Table数,可以满足自己的需求,但TreeGrid在用的时候遇到了一个棘手的问题:没有原生TreeNode的CheckBox功能。
查了半天资料也到了比较完美的解决方案:
一、解决方法:
打开TreeGridNodeUI.js文件,将下面记为绿色的代码插入到相应位置,并保存文件。
1 /*! 2 * Ext JS Library 3.4 3 * Copyright(c) 2006-2010 Sencha Inc. 4 * licensing@sencha.com 5 * http://www.sencha.com/license 6 */ 7 /** 8 * @class Ext.ux.tree.TreeGridNodeUI 9 * @extends Ext.tree.TreeNodeUI 10 */ 11 Ext.ux.tree.TreeGridNodeUI = Ext.extend(Ext.tree.TreeNodeUI, { 12 isTreeGridNodeUI: true, 13 14 renderElements : function(n, a, targetNode, bulkRender){ 15 var t = n.getOwnerTree(), 16 cols = t.columns, 17 c = cols[0], 18 i, buf, len; 19 20 this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : ''; 21 22 var cb = Ext.isBoolean(a.checked); 23 buf = [ 24 '<tbody class="x-tree-node">', 25 '<tr ext:tree-node-id="', n.id ,'" class="x-tree-node-el x-tree-node-leaf ', a.cls, '">', 26 '<td class="x-treegrid-col">', 27 '<span class="x-tree-node-indent">', this.indentMarkup, "</span>", 28 '<img src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />', 29 '<img src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon', (a.icon ? " x-tree-node-inline-icon" : ""), (a.iconCls ? " "+a.iconCls : ""), '" unselectable="on" />', 30 cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '', 31 '<a hidefocus="on" class="x-tree-node-anchor" href="', a.href ? a.href : '#', '" tabIndex="1" ', 32 a.hrefTarget ? ' target="'+a.hrefTarget+'"' : '', '>', 33 '<span unselectable="on">', 34 (c.tpl ? c.tpl.apply(a) : a[c.dataIndex] || c.text), 35 '</span></a>', 36 '</td>' 37 ]; 38 39 for(i = 1, len = cols.length; i < len; i++){ 40 c = cols[i]; 41 buf.push( 42 '<td class="x-treegrid-col ', (c.cls ? c.cls : ''), '">', 43 '<div unselectable="on" class="x-treegrid-text"', (c.align ? ' style="text-align: ' + c.align + ';"' : ''), '>', 44 (c.tpl ? c.tpl.apply(a) : a[c.dataIndex]), 45 '</div>', 46 '</td>' 47 ); 48 } 49 50 buf.push( 51 '</tr><tr class="x-tree-node-ct"><td colspan="', cols.length, '">', 52 '<table class="x-treegrid-node-ct-table" cellpadding="0" cellspacing="0" style="table-layout: fixed; display: none; width: ', t.innerCt.getWidth() ,'px;"><colgroup>' 53 ); 54 for(i = 0, len = cols.length; i<len; i++) { 55 buf.push('<col style="width: ', (cols[i].hidden ? 0 : cols[i].width) ,'px;" />'); 56 } 57 buf.push('</colgroup></table></td></tr></tbody>'); 58 59 if(bulkRender !== true && n.nextSibling && n.nextSibling.ui.getEl()){ 60 this.wrap = Ext.DomHelper.insertHtml("beforeBegin", n.nextSibling.ui.getEl(), buf.join('')); 61 }else{ 62 this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf.join('')); 63 } 64 65 this.elNode = this.wrap.childNodes[0]; 66 this.ctNode = this.wrap.childNodes[1].firstChild.firstChild; 67 var cs = this.elNode.firstChild.childNodes; 68 69 this.indentNode = cs[0]; 70 this.ecNode = cs[1]; 71 this.iconNode = cs[2]; 72 73 if (cb) { 74 this.checkbox = cs[3]; 75 this.anchor = cs[4]; 76 this.textNode = cs[4].firstChild; 77 } else { 78 this.anchor = cs[3]; 79 this.textNode = cs[3].firstChild; 80 } 81 }, 82 83 // private 84 animExpand : function(cb){ 85 this.ctNode.style.display = ""; 86 Ext.ux.tree.TreeGridNodeUI.superclass.animExpand.call(this, cb); 87 } 88 }); 89 90 Ext.ux.tree.TreeGridRootNodeUI = Ext.extend(Ext.tree.TreeNodeUI, { 91 isTreeGridNodeUI: true, 92 93 // private 94 render : function(){ 95 if(!this.rendered){ 96 this.wrap = this.ctNode = this.node.ownerTree.innerCt.dom; 97 this.node.expanded = true; 98 } 99 100 if(Ext.isWebKit) { 101 // weird table-layout: fixed issue in webkit 102 var ct = this.ctNode; 103 ct.style.tableLayout = null; 104 (function() { 105 ct.style.tableLayout = 'fixed'; 106 }).defer(1); 107 } 108 }, 109 110 destroy : function(){ 111 if(this.elNode){ 112 Ext.dd.Registry.unregister(this.elNode.id); 113 } 114 delete this.node; 115 }, 116 117 collapse : Ext.emptyFn, 118 expand : Ext.emptyFn 119 });
二、使用方法:
PS:TreeGrid的CheckBox使用方法与Ext.Tree.Treepanel的CheckBox使用方法完全一样,包括数据生成和前台的方法、属性、事件。
1、添加CheckBox(生成Json字符串时在Item中加入checked属性即可,注意区分大小写)
例如:
1 { [id:'1',text:'张三'], 2 3 [id:'0',text:'张三',checked:true], 4 5 [id:'1',text:'张三',checked:false] }
以上我列出了三种情况:
①不使用CheckBox,不需要加"checked"属性,因为TreeNode认为,如果有checked属性就会在节点中自动增加CheckBox;
②使用CheckBox并默认为勾选状态,需要添加"checked"属性,并设置值为"false";
③使用CheckBox并默认为不勾选状态,需要添加"checked"属性,并设置值为"true";
2、在js中获取CheckBox选中状态的值。
直接调用TreeNode的atributes.checked方法即可。
例如:
1 TreeGrid.root.childNodes[0].attributes.checked
3、在js中设置CheckBox状态为选中或取消选中。
这里需要分两步
①设置CheckBox为选中或取消。
②设置checked属性:因为TreeNode不会自动设置TreeNode的TreeNode.attributes.checked属性。
下面请看代码:第一行是设置Checkbox的选中状态
第二行是设置checked属性。
1 TreeGrid.root.childNodes[0].getUI().checkbox.checked = true; 2 TreeGrid.root.childNodes[0].attributes.checked=true;
这是第一次写博客,排版不是很专业,请大家包涵一下,还在加班中,要发布程序了,就到此结束吧。。。有问题可以跟帖,我回答复。
下次会写关于Ext TreeGrid 左右相互拖拽(拖动)货单相拖拽的相关操作文章。
下面是带CheckBox的TreeGrid文件包,大家可以下载了直接用。