主要实现原理就是替换TreeNodeUI这个类的renderElements方法,将以前的<input type='checkbox'>替换成图片形式的checkbox。当然需要修改相应的方法,如isChecked() 等方法。
注意:1、现在三态的表示方式均为字符串 "True","False","Not",分别代表 选中、空、反选。
2、在TreeNode中增加isThr属性,表示是否为三太显示,false和置默认为两态,true为三太。
废话不说了直接上代码。
1、JS代码:
- Ext.override(Ext.tree.TreeNodeUI, {
- grayedValue: null,
- isThr: false,
- onDisableChange: function (node, state) {
- this.disabled = state;
- this[state ? 'addClass' : 'removeClass']("x-tree-node-disabled");
- },
- initEvents: function () {
- this.node.on("move", this.onMove, this);
- if (this.node.disabled) {
- this.disabled = true;
- this.addClass("x-tree-node-disabled");
- }
- if (this.node.hidden) {
- this.hide();
- }
- var ot = this.node.getOwnerTree();
- var dd = ot.enableDD || ot.enableDrag || ot.enableDrop;
- if (dd && (!this.node.isRoot || ot.rootVisible)) {
- Ext.dd.Registry.register(this.elNode, {
- node: this.node,
- handles: this.getDDHandles(),
- isHandle: false
- });
- }
- },
- onDblClick: function (e) {
- e.preventDefault();
- if (this.disabled) {
- return;
- }
- if (!this.animating && this.node.isExpandable() && !e.getTarget('.x-tree-checkbox', 1)) {
- this.node.toggle();
- }
- this.fireEvent("dblclick", this.node, e);
- },
- onCheckChange: function () {
- var checked = this.isChecked();
- if (checked !== this.node.attributes.checked) {
- this.node.attributes.checked = checked;
- this.fireEvent('checkchange', this.node, checked);
- }
- },
- toggleCheck: function (checked) {
- var cb = this.checkbox;
- if (!cb) {
- return 'false';
- }
- if (checked === undefined) {
- checked = this.isChecked();
- }
- else {
- if (this.isThr == true) {
- checked = checked == 'true' ? 'false' : (checked == 'false' ? 'not' : 'true');
- }
- else {
- checked = checked == 'true' ? 'false' : 'true';
- }
- }
- if (this.isThr == true) {
- if (checked == 'true') {
- Ext.fly(cb).replaceClass('x-tree-node-checked', 'x-tree-node-grayed');
- } else if (checked == 'false') {
- Ext.fly(cb).replaceClass('x-tree-node-unchecked', 'x-tree-node-checked');
- } else if (checked == 'not') {
- Ext.fly(cb).replaceClass('x-tree-node-grayed', 'x-tree-node-unchecked');
- }
- else {
- Ext.fly(cb).removeClass(['x-tree-node-checked', 'x-tree-node-grayed', 'x-tree-node-unchecked']);
- }
- }
- else {
- if (checked == 'true') {
- Ext.fly(cb).replaceClass('x-tree-node-checked', 'x-tree-node-unchecked');
- } else if (checked == 'false') {
- Ext.fly(cb).replaceClass('x-tree-node-unchecked', 'x-tree-node-checked');
- } else {
- Ext.fly(cb).removeClass(['x-tree-node-checked', 'x-tree-node-unchecked']);
- }
- }
- this.onCheckChange();
- return checked;
- },
- onCheckboxClick: function () {
- if (!this.disabled) {
- this.toggleCheck();
- }
- },
- onCheckboxOver: function () {
- this.addClass('x-tree-checkbox-over');
- },
- onCheckboxOut: function () {
- this.removeClass('x-tree-checkbox-over');
- },
- onCheckboxDown: function () {
- this.addClass('x-tree-checkbox-down');
- },
- onCheckboxUp: function () {
- this.removeClass('x-tree-checkbox-down');
- },
- renderElements: function (n, a, targetNode, bulkRender) {
- this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
- var cb = a.checked !== undefined;
- this.isThr = a.isThr !== undefined;
- 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">',
- '<span class="x-tree-node-indent">', this.indentMarkup, "</span>",
- '<img src=\'#\'" /span>, this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />',
- '<img src=\'#\'" /span>, a.icon || this.emptyIcon, '" class="x-tree-node-icon', (a.icon ? " x-tree-node-inline-icon" : ""), (a.iconCls ? " " + a.iconCls : ""), '" unselectable="on" />',
- cb ? ('<img src=\'#\'" /span> + this.emptyIcon + '" class="x-tree-checkbox' + (a.checked === true ? ' x-tree-node-checked' : (a.checked === false ? ' x-tree-node-unchecked' : ' x-tree-node-grayed')) + '" />') : '',
- '<a hidefocus="on" class="x-tree-node-anchor" href="', href, '" tabIndex="1" ',
- a.hrefTarget ? ' target="' + a.hrefTarget + '"' : "", '><span unselectable="on">', n.text, "</span></a></div>",
- '<ul class="x-tree-node-ct" style="display:none;"></ul>',
- "</li>"].join('');
- var nel;
- if (bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())) {
- this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);
- } else {
- this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
- }
- this.elNode = this.wrap.childNodes[0];
- this.ctNode = this.wrap.childNodes[1];
- var cs = this.elNode.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;
- },
- isChecked: function () {
- if (this.isThr == true) {
- return this.checkbox
- ? (Ext.fly(this.checkbox).hasClass('x-tree-node-checked')
- ? 'true'
- : Ext.fly(this.checkbox).hasClass('x-tree-node-grayed')
- ? 'not'
- : Ext.fly(this.checkbox).hasClass('x-tree-node-unchecked')
- ? 'false'
- : 'false'
- )
- : false;
- }
- else {
- return this.checkbox
- ? (Ext.fly(this.checkbox).hasClass('x-tree-node-checked')
- ? 'true'
- : Ext.fly(this.checkbox).hasClass('x-tree-node-unchecked')
- ? 'false'
- : 'false')
- : 'false';
- }
- },
- getChecked: function () {
- return this.node.attributes.checked;
- }
- });
- Ext.override(Ext.tree.TreeEventModel, {
- initEvents :function(){
- var el = this.tree.getTreeEl();
- el.on('click', this.delegateClick, this);
- if(this.tree.trackMouseOver !== false){
- el.on('mouseover', this.delegateOver, this);
- el.on('mouseout', this.delegateOut, this);
- }
- el.on('mousedown', this.delegateDown, this);
- el.on('mouseup', this.delegateUp, this);
- el.on('dblclick', this.delegateDblClick, this);
- el.on('contextmenu', this.delegateContextMenu, this);
- },
- delegateOver :function(e, t){
- if(!this.beforeEvent(e)){
- return;
- }
- if(this.lastEcOver){
- this.onIconOut(e, this.lastEcOver);
- delete this.lastEcOver;
- }
- if(this.lastCbOver){
- this.onCheckboxOut(e, this.lastCbOver);
- delete this.lastCbOver;
- }
- if(e.getTarget('.x-tree-ec-icon', 1)){
- this.lastEcOver = this.getNode(e);
- this.onIconOver(e, this.lastEcOver);
- }
- else if(e.getTarget('.x-tree-checkbox', 1)){
- this.lastCbOver = this.getNode(e);
- this.onCheckboxOver(e, this.lastCbOver);
- }
- if(this.getNodeTarget(e)){
- this.onNodeOver(e, this.getNode(e));
- }
- },
- delegateOut :function(e, t){
- if(!this.beforeEvent(e)){
- return;
- }
- var n;
- if(e.getTarget('.x-tree-ec-icon', 1)){
- n = this.getNode(e);
- this.onIconOut(e, n);
- if(n == this.lastEcOver){
- delete this.lastEcOver;
- }
- }
- else if(e.getTarget('.x-tree-checkbox', 1)){
- n = this.getNode(e);
- this.onCheckboxOut(e, n);
- if(n == this.lastCbOver){
- delete this.lastCbOver;
- }
- }
- t = this.getNodeTarget(e);
- if(t && !e.within(t, true)){
- this.onNodeOut(e, this.getNode(e));
- }
- },
- delegateDown :function(e, t){
- if(!this.beforeEvent(e)){
- return;
- }
- if(e.getTarget('.x-tree-checkbox', 1)){
- this.onCheckboxDown(e, this.getNode(e));
- }
- },
- delegateUp :function(e, t){
- if(!this.beforeEvent(e)){
- return;
- }
- if(e.getTarget('.x-tree-checkbox', 1)){
- this.onCheckboxUp(e, this.getNode(e));
- }
- },
- delegateClick :function(e, t){
- if(!this.beforeEvent(e)){
- return;
- }
- if(e.getTarget('.x-tree-checkbox', 1)){
- this.onCheckboxClick(e, this.getNode(e));
- }
- else if(e.getTarget('.x-tree-ec-icon', 1)){
- this.onIconClick(e, this.getNode(e));
- }
- else if(this.getNodeTarget(e)){
- this.onNodeClick(e, this.getNode(e));
- }
- },
- onCheckboxClick :function(e, node){
- node.ui.onCheckboxClick();
- },
- onCheckboxOver :function(e, node){
- node.ui.onCheckboxOver();
- },
- onCheckboxOut :function(e, node){
- node.ui.onCheckboxOut();
- },
- onCheckboxDown :function(e, node){
- node.ui.onCheckboxDown();
- },
- onCheckboxUp :function(e, node){
- node.ui.onCheckboxUp();
- }
- });
- Ext.override(Ext.tree.TreePanel, {
- getChecked : function(a, startNode){
- startNode = startNode || this.root;
- var r = [];
- var f = function(){
- if(this.ui.getChecked()){
- r.push(!a ? this : (a == 'id' ? this.id : this.attributes[a]));
- }
- };
- startNode.cascade(f);
- return r;
- }
- });
2、CSS文件:
- .x-tree-checkbox {
- background:url('../../resources/images/default/form/checkbox.gif') no-repeat 0 0;
- height:13px;
- width:13px;
- vertical-align:middle;
- }
- .x-tree-checkbox-over .x-tree-checkbox {
- background-position:-13px 0;
- }
- .x-tree-checkbox-down .x-tree-checkbox {
- background-position:-26px 0;
- }
- .x-tree-node-disabled .x-tree-checkbox {
- background-position:-39px 0;
- }
- .x-tree-node-checked {
- background-position:0 -13px;
- }
- .x-tree-checkbox-over .x-tree-node-checked {
- background-position:-13px -13px;
- }
- .x-tree-checkbox-down .x-tree-node-checked {
- background-position:-26px -13px;
- }
- .x-tree-node-disabled .x-tree-node-checked {
- background-position:-39px -13px;
- }
- .x-tree-node-grayed {
- background-position:0 -26px;
- }
- .x-tree-checkbox-over .x-tree-node-grayed {
- background-position:-13px -26px;
- }
- .x-tree-checkbox-down .x-tree-node-grayed {
- background-position:-26px -26px;
- }
- .x-tree-node-unchecked {
- background-position:0 0;
- }
- .x-tree-checkbox-over .x-tree-node-unchecked {
- background-position:-13px 0;
- }
- .x-tree-checkbox-down .x-tree-node-unchecked {
- background-position:-26px 0;
- }
- .x-tree-node-disabled .x-tree-node-grayed {
- background-position:-39px -26px;
- }
3、图片:
将该图片放到 ext路径/resources/images/default/form/ 下替换 checkbox.gif文件