- 浏览: 49552 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
xiaofan_0204:
ssssssssssssssssssssssssss
struts2 原理 -
chen4w:
有帮助,谢谢!
SNMP windows OIDs -
yuhang_java:
说得很好,概述很全。 感谢楼主分享。
Hibernate二级缓存(二) ---- 最佳实践 -
zhongxy0000:
JNDI使用配置总结 -
likeseerain:
在ext.../resource/css/ext-all.cs ...
改变Ext的样式在那里改
EXT2.0 checkbox树的扩展(支持单选,级联多选,只选叶子等)
在ext1.x里,树是没有checkbox的, 幸好在2.X版本里提供了这个功能, 在许多应用里, 带有checkbox的树使用还是很常见的
Ext2.X提供了简单的checkbox实现,但对于一些复杂的需求,如: 级联多选(选中父结点,自选中其所有子结点和所有父结点) , 单选等等, Ext2.X并没有帮我们实现
还有最难解决的情况, 当树是异步的时候, 要想级联多选, 实现起来有些难度
在此, 通过对Ext.tree.TreeNodeUI进行扩展,这些问题都得到很好的解决
Js代码
/**
* @class Ext.tree.TreeCheckNodeUI
* @extends Ext.tree.TreeNodeUI
*
* 对 Ext.tree.TreeNodeUI 进行checkbox功能的扩展,后台返回的结点信息不用非要包含checked属性
*
* 扩展的功能点有:
* 一、支持只对树的叶子进行选择
* 只有当返回的树结点属性leaf = true 时,结点才有checkbox可选
* 使用时,只需在声明树时,加上属性 onlyLeafCheckable: true 既可,默认是false
*
* 二、支持对树的单选
* 只允许选择一个结点
* 使用时,只需在声明树时,加上属性 checkModel: "single" 既可
*
* 二、支持对树的级联多选
* 当选择结点时,自动选择该结点下的所有子结点,以及该结点的所有父结点(根结点除外),特别是支持异步,当子结点还没显示时,会从后台取得子结点,然后将其选中/取消选中
* 使用时,只需在声明树时,加上属性 checkModel: "cascade" 既可
*
* 三、添加"check"事件
* 该事件会在树结点的checkbox发生改变时触发
* 使用时,只需给树注册事件,如:
* tree.on("check",function(node,checked){...});
*
* 默认情况下,checkModel为'multiple',也就是多选,onlyLeafCheckable为false,所有结点都可选
*
* 使用方法:在loader里加上 baseAttrs:{uiProvider:Ext.tree.TreeCheckNodeUI} 既可.
* 例如:
* var tree = new Ext.tree.TreePanel({
* el:'tree-ct',
* width:568,
* height:300,
* checkModel: 'cascade', //对树的级联多选
* onlyLeafCheckable: false,//对树所有结点都可选
* animate: false,
* rootVisible: false,
* autoScroll:true,
* loader: new Ext.tree.DWRTreeLoader({
* dwrCall:Tmplt.getTmpltTree,
* baseAttrs: { uiProvider: Ext.tree.TreeCheckNodeUI } //添加 uiProvider 属性
* }),
* root: new Ext.tree.AsyncTreeNode({ id:'0' })
* });
* tree.on("check",function(node,checked){alert(node.text+" = "+checked)}); //注册"check"事件
* tree.render();
*
*/
Ext.tree.TreeCheckNodeUI = function() {
//'multiple':多选; 'single':单选; 'cascade':级联多选
this.checkModel = 'multiple';
//only leaf can checked
this.onlyLeafCheckable = false;
Ext.tree.TreeCheckNodeUI.superclass.constructor.apply(this, arguments);
};
Ext.extend(Ext.tree.TreeCheckNodeUI, Ext.tree.TreeNodeUI, {
renderElements : function(n, a, targetNode, bulkRender){
var tree = n.getOwnerTree();
this.checkModel = tree.checkModel || this.checkModel;
this.onlyLeafCheckable = tree.onlyLeafCheckable || false;
// add some indent caching, this helps performance when rendering a large tree
this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
var cb = (!this.onlyLeafCheckable || a.leaf);
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="', 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,"</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];
Ext.fly(this.checkbox).on('click', this.check.createDelegate(this,[null]));
index++;
}
this.anchor = cs[index];
this.textNode = cs[index].firstChild;
},
// 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 && this.checkModel == 'cascade'){
var parentNode = n.parentNode;
if(parentNode !== null) {
this.parentCheck(parentNode,checked);
}
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);
}
}
});
/**
* @class Ext.tree.TreeCheckNodeUI
* @extends Ext.tree.TreeNodeUI
*
* 对 Ext.tree.TreeNodeUI 进行checkbox功能的扩展,后台返回的结点信息不用非要包含checked属性
*
* 扩展的功能点有:
* 一、支持只对树的叶子进行选择
* 只有当返回的树结点属性leaf = true 时,结点才有checkbox可选
* 使用时,只需在声明树时,加上属性 onlyLeafCheckable: true 既可,默认是false
*
* 二、支持对树的单选
* 只允许选择一个结点
* 使用时,只需在声明树时,加上属性 checkModel: "single" 既可
*
* 二、支持对树的级联多选
* 当选择结点时,自动选择该结点下的所有子结点,以及该结点的所有父结点(根结点除外),特别是支持异步,当子结点还没显示时,会从后台取得子结点,然后将其选中/取消选中
* 使用时,只需在声明树时,加上属性 checkModel: "cascade" 既可
*
* 三、添加"check"事件
* 该事件会在树结点的checkbox发生改变时触发
* 使用时,只需给树注册事件,如:
* tree.on("check",function(node,checked){...});
*
* 默认情况下,checkModel为'multiple',也就是多选,onlyLeafCheckable为false,所有结点都可选
*
* 使用方法:在loader里加上 baseAttrs:{uiProvider:Ext.tree.TreeCheckNodeUI} 既可.
* 例如:
* var tree = new Ext.tree.TreePanel({
* el:'tree-ct',
* width:568,
* height:300,
* checkModel: 'cascade', //对树的级联多选
* onlyLeafCheckable: false,//对树所有结点都可选
* animate: false,
* rootVisible: false,
* autoScroll:true,
* loader: new Ext.tree.DWRTreeLoader({
* dwrCall:Tmplt.getTmpltTree,
* baseAttrs: { uiProvider: Ext.tree.TreeCheckNodeUI } //添加 uiProvider 属性
* }),
* root: new Ext.tree.AsyncTreeNode({ id:'0' })
* });
* tree.on("check",function(node,checked){alert(node.text+" = "+checked)}); //注册"check"事件
* tree.render();
*
*/
Ext.tree.TreeCheckNodeUI = function() {
//'multiple':多选; 'single':单选; 'cascade':级联多选
this.checkModel = 'multiple';
//only leaf can checked
this.onlyLeafCheckable = false;
Ext.tree.TreeCheckNodeUI.superclass.constructor.apply(this, arguments);
};
Ext.extend(Ext.tree.TreeCheckNodeUI, Ext.tree.TreeNodeUI, {
renderElements : function(n, a, targetNode, bulkRender){
var tree = n.getOwnerTree();
this.checkModel = tree.checkModel || this.checkModel;
this.onlyLeafCheckable = tree.onlyLeafCheckable || false;
// add some indent caching, this helps performance when rendering a large tree
this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
var cb = (!this.onlyLeafCheckable || a.leaf);
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="', 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,"</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];
Ext.fly(this.checkbox).on('click', this.check.createDelegate(this,[null]));
index++;
}
this.anchor = cs[index];
this.textNode = cs[index].firstChild;
},
// 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 && this.checkModel == 'cascade'){
var parentNode = n.parentNode;
if(parentNode !== null) {
this.parentCheck(parentNode,checked);
}
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);
}
}
});
使用方法都在注释里了,应该已经很详细了,我就不多说了
需要注意的是, 使用例子里的Tree 使用了Ext.tree.DWRTreeLoader这个扩展类,用来加载后台树结点,这和使用其它的loader没有区别的,
如果您使用其它的loader, 同样加上baseAttrs: { uiProvider: Ext.tree.TreeCheckNodeUI }就行了
在ext1.x里,树是没有checkbox的, 幸好在2.X版本里提供了这个功能, 在许多应用里, 带有checkbox的树使用还是很常见的
Ext2.X提供了简单的checkbox实现,但对于一些复杂的需求,如: 级联多选(选中父结点,自选中其所有子结点和所有父结点) , 单选等等, Ext2.X并没有帮我们实现
还有最难解决的情况, 当树是异步的时候, 要想级联多选, 实现起来有些难度
在此, 通过对Ext.tree.TreeNodeUI进行扩展,这些问题都得到很好的解决
Js代码
/**
* @class Ext.tree.TreeCheckNodeUI
* @extends Ext.tree.TreeNodeUI
*
* 对 Ext.tree.TreeNodeUI 进行checkbox功能的扩展,后台返回的结点信息不用非要包含checked属性
*
* 扩展的功能点有:
* 一、支持只对树的叶子进行选择
* 只有当返回的树结点属性leaf = true 时,结点才有checkbox可选
* 使用时,只需在声明树时,加上属性 onlyLeafCheckable: true 既可,默认是false
*
* 二、支持对树的单选
* 只允许选择一个结点
* 使用时,只需在声明树时,加上属性 checkModel: "single" 既可
*
* 二、支持对树的级联多选
* 当选择结点时,自动选择该结点下的所有子结点,以及该结点的所有父结点(根结点除外),特别是支持异步,当子结点还没显示时,会从后台取得子结点,然后将其选中/取消选中
* 使用时,只需在声明树时,加上属性 checkModel: "cascade" 既可
*
* 三、添加"check"事件
* 该事件会在树结点的checkbox发生改变时触发
* 使用时,只需给树注册事件,如:
* tree.on("check",function(node,checked){...});
*
* 默认情况下,checkModel为'multiple',也就是多选,onlyLeafCheckable为false,所有结点都可选
*
* 使用方法:在loader里加上 baseAttrs:{uiProvider:Ext.tree.TreeCheckNodeUI} 既可.
* 例如:
* var tree = new Ext.tree.TreePanel({
* el:'tree-ct',
* width:568,
* height:300,
* checkModel: 'cascade', //对树的级联多选
* onlyLeafCheckable: false,//对树所有结点都可选
* animate: false,
* rootVisible: false,
* autoScroll:true,
* loader: new Ext.tree.DWRTreeLoader({
* dwrCall:Tmplt.getTmpltTree,
* baseAttrs: { uiProvider: Ext.tree.TreeCheckNodeUI } //添加 uiProvider 属性
* }),
* root: new Ext.tree.AsyncTreeNode({ id:'0' })
* });
* tree.on("check",function(node,checked){alert(node.text+" = "+checked)}); //注册"check"事件
* tree.render();
*
*/
Ext.tree.TreeCheckNodeUI = function() {
//'multiple':多选; 'single':单选; 'cascade':级联多选
this.checkModel = 'multiple';
//only leaf can checked
this.onlyLeafCheckable = false;
Ext.tree.TreeCheckNodeUI.superclass.constructor.apply(this, arguments);
};
Ext.extend(Ext.tree.TreeCheckNodeUI, Ext.tree.TreeNodeUI, {
renderElements : function(n, a, targetNode, bulkRender){
var tree = n.getOwnerTree();
this.checkModel = tree.checkModel || this.checkModel;
this.onlyLeafCheckable = tree.onlyLeafCheckable || false;
// add some indent caching, this helps performance when rendering a large tree
this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
var cb = (!this.onlyLeafCheckable || a.leaf);
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="', 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,"</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];
Ext.fly(this.checkbox).on('click', this.check.createDelegate(this,[null]));
index++;
}
this.anchor = cs[index];
this.textNode = cs[index].firstChild;
},
// 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 && this.checkModel == 'cascade'){
var parentNode = n.parentNode;
if(parentNode !== null) {
this.parentCheck(parentNode,checked);
}
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);
}
}
});
/**
* @class Ext.tree.TreeCheckNodeUI
* @extends Ext.tree.TreeNodeUI
*
* 对 Ext.tree.TreeNodeUI 进行checkbox功能的扩展,后台返回的结点信息不用非要包含checked属性
*
* 扩展的功能点有:
* 一、支持只对树的叶子进行选择
* 只有当返回的树结点属性leaf = true 时,结点才有checkbox可选
* 使用时,只需在声明树时,加上属性 onlyLeafCheckable: true 既可,默认是false
*
* 二、支持对树的单选
* 只允许选择一个结点
* 使用时,只需在声明树时,加上属性 checkModel: "single" 既可
*
* 二、支持对树的级联多选
* 当选择结点时,自动选择该结点下的所有子结点,以及该结点的所有父结点(根结点除外),特别是支持异步,当子结点还没显示时,会从后台取得子结点,然后将其选中/取消选中
* 使用时,只需在声明树时,加上属性 checkModel: "cascade" 既可
*
* 三、添加"check"事件
* 该事件会在树结点的checkbox发生改变时触发
* 使用时,只需给树注册事件,如:
* tree.on("check",function(node,checked){...});
*
* 默认情况下,checkModel为'multiple',也就是多选,onlyLeafCheckable为false,所有结点都可选
*
* 使用方法:在loader里加上 baseAttrs:{uiProvider:Ext.tree.TreeCheckNodeUI} 既可.
* 例如:
* var tree = new Ext.tree.TreePanel({
* el:'tree-ct',
* width:568,
* height:300,
* checkModel: 'cascade', //对树的级联多选
* onlyLeafCheckable: false,//对树所有结点都可选
* animate: false,
* rootVisible: false,
* autoScroll:true,
* loader: new Ext.tree.DWRTreeLoader({
* dwrCall:Tmplt.getTmpltTree,
* baseAttrs: { uiProvider: Ext.tree.TreeCheckNodeUI } //添加 uiProvider 属性
* }),
* root: new Ext.tree.AsyncTreeNode({ id:'0' })
* });
* tree.on("check",function(node,checked){alert(node.text+" = "+checked)}); //注册"check"事件
* tree.render();
*
*/
Ext.tree.TreeCheckNodeUI = function() {
//'multiple':多选; 'single':单选; 'cascade':级联多选
this.checkModel = 'multiple';
//only leaf can checked
this.onlyLeafCheckable = false;
Ext.tree.TreeCheckNodeUI.superclass.constructor.apply(this, arguments);
};
Ext.extend(Ext.tree.TreeCheckNodeUI, Ext.tree.TreeNodeUI, {
renderElements : function(n, a, targetNode, bulkRender){
var tree = n.getOwnerTree();
this.checkModel = tree.checkModel || this.checkModel;
this.onlyLeafCheckable = tree.onlyLeafCheckable || false;
// add some indent caching, this helps performance when rendering a large tree
this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
var cb = (!this.onlyLeafCheckable || a.leaf);
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="', 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,"</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];
Ext.fly(this.checkbox).on('click', this.check.createDelegate(this,[null]));
index++;
}
this.anchor = cs[index];
this.textNode = cs[index].firstChild;
},
// 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 && this.checkModel == 'cascade'){
var parentNode = n.parentNode;
if(parentNode !== null) {
this.parentCheck(parentNode,checked);
}
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);
}
}
});
使用方法都在注释里了,应该已经很详细了,我就不多说了
需要注意的是, 使用例子里的Tree 使用了Ext.tree.DWRTreeLoader这个扩展类,用来加载后台树结点,这和使用其它的loader没有区别的,
如果您使用其它的loader, 同样加上baseAttrs: { uiProvider: Ext.tree.TreeCheckNodeUI }就行了
发表评论
-
叮叮当当
2011-12-09 21:39 47叮叮当当撒旦飞洒 三十三 -
JS屏蔽功能类(屏蔽F5,退格键,空格键......)
2008-08-15 11:57 25901.屏蔽功能类 1.1 屏蔽键盘所有键 <script ... -
Ext 方法的解说
2008-08-01 11:18 15131.createDelegate( [Object obj], ... -
Ext面向对象编程
2008-08-01 10:42 1140不好意思老兄:收下人的 ... -
汇总Javascript各种判断脚本(javascript经典例子)
2008-07-18 11:26 1358一、验证类 1、数字验证内 1.1 整数 1.2 大于0的整数 ... -
改变Ext的样式在那里改
2008-02-25 14:11 2703我是Ext新手,我怎么该Ext样式???比如我想改Tabp ... -
如何用Ext使图片移动但移动的时候要有虚框
2008-02-22 18:22 1193我是一个初学Ext者,现在想使图片能随便移动,并且移动时候要有 ...
相关推荐
2. 字段组件:EXT提供了多种内置的表单字段,如TextField(文本输入)、ComboBox(下拉框)、CheckBox(复选框)、Radio(单选按钮)、DateField(日期选择器)等。 3. 表单验证:EXT 2.0的表单字段具有内置的验证...
9.2. 带全选的checkbox树形CheckBoxTree 9.3. 带全选的checkbox的grid 9.4. fisheye 9.5. 可以设置时间的日期控件 9.6. JsonView实现用户卡片拖拽与右键菜单 9.7. 下拉列表选择每页显示多少数据 10. 撕裂吧!...
这使得Ext 2.0具有极高的可扩展性。 在提供的压缩包中,EXT2文件很可能是包含这些示例代码的文件夹。通过查看和运行这些示例,你可以更好地理解并掌握Ext 2.0表单组件的用法和功能。同时,布局实例的例程将帮助你...
扩展到更复杂的需求,例如在表格中添加CheckBox选中功能,可以创建一个CheckboxSelectionModel并将其添加到ColumnModel中: ```javascript var sm = new Ext.grid.CheckboxSelectionModel(); var cm = new Ext.grid...
本文将深入探讨Ext2.0框架下Grid的使用方法,涵盖其基本配置、数据绑定以及高级特性如CheckBox的集成,旨在帮助开发者快速掌握并高效利用这一工具。 #### Grid组件概述 Grid组件在Ext2.0框架中主要用于展示表格...
### Ext2.0框架的Grid使用介绍 #### 一、Ext2.0框架概述 Ext2.0是一款基于JavaScript的库,它提供了大量的用户界面组件,使得开发人员能够轻松地构建出高度交互式的Web应用程序。相比其他框架如YUI等,Ext2.0拥有...
在描述中提到的博客链接(由于实际无法访问,这里仅作理论分析),博主可能分享了如何解决在使用Struts2.0的`checkbox`标签时遇到的具体问题,可能包括值的获取、动态生成复选框、或者与其他组件(如`<s:form>`)的...
Ext_Net_CheckboxGroup 勾选、全选、反选和限制勾选
EXTjs2 的treeNode 带有checkbox,可是API中,关于checkbox的事件就只有一个checkchange事件,所以写个方法传上来。
对于复选框的定制,可以通过`CMD`的SASS预处理器修改样式,或通过扩展`Checkbox`类来自定义功能。 7. **多选框组** 如果需要一组互斥的复选框,可以使用`Ext.container.CheckboxGroup`,它允许用户从一组选项中...
EXT TREE扩展CHECKBOX JS是一种在EXT JS框架下对树形组件(Tree Panel)进行增强,实现复选框功能的技术。EXT JS是一个强大的JavaScript GUI库,它提供了丰富的组件和功能,用于构建复杂的Web应用程序。在EXT JS中,...
在EXT.NET框架中,TreePanel是一个非常重要的组件,它用于展示层次结构的数据,通常用于构建树形目录或层级关系的界面。在这个特定的场景中,我们关注的是TreePanel中的Checkbox功能以及父子节点间的联动效果。 ...
在IT领域,"Checkbox树形结构"是一种常见的用户界面组件,尤其在数据管理和配置界面中广泛应用。它结合了树形视图(Tree View)和复选框(Checkbox)的特性,为用户提供了一种多级选择的方式,使得用户可以对一组...
在实际项目中,`checkBoxGroup`通常与其他组件结合使用,如表格、表单或者树形视图。结合`Store`来管理数据,可以轻松实现数据绑定,使应用具有更强的数据交互能力。 总结起来,`Ext JS`的`checkBoxGroup`组件是...
自动生成行号,支持checkbox全选,动态选择显示哪些列,支持本地以及远程分页,可以对单元格按照自己的想法进行渲染,这些也算可以想到的功能。 再加上可编辑grid,添加新行,删除一或多行,提示脏数据,推拽...
"checkbox树形展开效果"是这种概念的一个具体应用,它结合了多选框(checkbox)与树形结构,让用户能够以图形化的方式操作和选择具有层次关系的项目。 在实现"checkbox树形展开效果"时,我们通常会用到HTML、CSS和...
在IT领域,尤其是在前端开发中,"checkbox树"是一种常见的用户界面组件,它结合了复选框(checkbox)和树形结构,用于展示层级关系的数据,并允许用户进行多级选择。这种组件在诸如文件管理器、组织架构选择、权限...
jQuery_treetable实现checkbox树,实现多级联动,适用于权限树等各类需要树形结构数据的场景
“aspx中checkboxList扩展”这个主题主要涵盖了如何通过自定义代码或者使用第三方库来增强CheckboxList控件的功能。这包括但不限于以下几个方面: 1. 数据绑定优化:原生的CheckboxList控件在数据绑定时可能不够...