`

EXT2.0 checkbox树的扩展(支持单选,级联多选,只选叶子等)

    博客分类:
  • AJAX
阅读更多

在ext1.x里,树是没有checkbox的, 幸好在2.X版本里提供了这个功能, 在许多应用里, 带有checkbox的树使用还是很常见的

 

Ext2.X提供了简单的checkbox实现,但对于一些复杂的需求,如: 级联多选(选中父结点,自选中其所有子结点和所有父结点) , 单选等等, Ext2.X并没有帮我们实现

 

还有最难解决的情况, 当树是异步的时候, 要想级联多选, 实现起来有些难度

 

在此, 通过对Ext.tree.TreeNodeUI进行扩展,这些问题都得到很好的解决

/**   
 * @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 }就行了

分享到:
评论

相关推荐

    layui+ztree下拉树,支持单选和多选

    `layui`和`ztree`这两个工具结合,可以实现一个功能强大的下拉树组件,支持单选和多选,大大提升了用户体验。本文将详细介绍如何利用`layui`和`ztree`来构建这样的组件,并探讨其关键技术和应用场景。 `layui`是一...

    WPF在dataGrid中添加CheckBox支持单选,多选,全选功能

    项目中用到DataGrid, 需要在第一列添加checkbox, 可以多选、全选。 其中涉及的概念DataTemplate, DataGridCellStyle, DataGridCellControlTemplate,Binding, OnPropertyChanged等。

    自己实现treeview,支持单选和多选

    在本项目中,我们探讨的是如何使用`Qt`库自行实现一个具备单选和多选功能的`TreeView`,并且带有复选框(checkbox)功能。`Qt`是一个强大的跨平台应用开发框架,主要由C++编写,广泛应用于Windows、Linux、Mac OS等...

    简单zTree树形,支持单选、多选、移动实例

    在这个“简单zTree树形,支持单选、多选、移动实例”中,我们将深入探讨zTree的核心功能和应用场景。 zTree是一个轻量级的插件,它通过Ajax技术动态加载数据,可以轻松地与后端服务进行交互,实现数据的动态更新和...

    js多级联动多选checkbox插件

    在JavaScript开发中,多级联动多选checkbox插件是一种常见的交互元素,用于实现层次结构数据的筛选和选择。这类插件通常用在如地区选择、类别分类等场景,用户可以通过逐级选择来过滤出需要的结果。`cascadebox-...

    EXT2.0中文教程

    只为了树也要学ext。 3.1. 真的,我是为了树,才开始学ext的。 3.2. 传统是先做出一棵树来。 3.3. 超越一个根 3.4. 你不会认为2.0里跟1.x是一样的吧? 3.5. 这种装配树节点的形式,真是让人头大。 3.6. jsp的例子是...

    Layui的eleTree树式选择器,分单选和多选,带搜索功能

    eleTree是基于Layui框架的一个扩展组件,它以树形结构展示数据,支持多种交互操作,包括展开/折叠节点、选择节点、拖拽节点等。eleTree设计简洁,易用性强,与Layui的其他组件兼容性良好,可以无缝集成到Layui项目中...

    ext 2.0 form demo

    2. 字段组件:EXT提供了多种内置的表单字段,如TextField(文本输入)、ComboBox(下拉框)、CheckBox(复选框)、Radio(单选按钮)、DateField(日期选择器)等。 3. 表单验证:EXT 2.0的表单字段具有内置的验证...

    结合ztree的下拉框树形结构数据多选,单选

    zTree是一个强大的jQuery插件,它提供了丰富的树形操作功能,如节点的增删改查、多选和单选等。 首先,我们来看"下拉框"。在网页设计中,下拉框(Dropdown)是一种节省空间且易于使用的表单元素,它允许用户从预...

    Node.js-ListView列表单级单选单级多选多级单选多级多选效果展示

    本教程将详细讲解如何实现ListView的单级单选、单级多选以及多级单选和多级多选的效果。 1. **单级单选**: 在ListView中实现单级单选,通常使用CheckedTextView或者自定义View,配合OnItemClickListener监听器来...

    Ext2.0 form使用实例的例程

    包括文本字段(TextField)、密码字段(PasswordField)、选择框(Checkbox)、复选框组(CheckboxGroup)、单选框(RadioButton)、下拉列表(ComboBox)、日期选择器(DateField)等。每个字段都有其特定的配置项...

    ListView中使用单选和多选效果

    在某些应用场景中,我们可能需要实现ListView中的单选或多选功能,例如在创建问卷调查或设置选项时。本篇文章将详细讲解如何在ListView中实现单选和多选效果。 首先,我们需要了解ListView的基本结构。ListView通常...

    checkBox的单选多选

    在Android开发中,CheckBox控件是用户界面设计中不可或缺的一部分,它允许用户进行单选或多选操作。在很多场景下,比如设置、选项列表等,我们都需要用到这个功能。本教程将详细介绍如何在Android中实现CheckBox的...

    Android支持单选和多选的投票项目.zip

    本项目"Android支持单选和多选的投票项目"提供了一个示例,帮助开发者了解如何在ListView中集成Checkbox和RadioButton来实现这样的功能。 首先,我们要理解Checkbox和RadioButton的区别。Checkbox是复选框,允许...

    (jsp版本)jquery树,j支持son格式,支持异步请求,支持checkbox多选项,支持级联加载等

    在这个`(jsp版本)jquery树`项目中,我们聚焦于如何利用jQuery实现一个功能丰富的树形结构,该结构支持JSON格式的数据,能够进行异步请求,具备复选框多选项功能,并且可以实现级联加载。 首先,`jquery树`是用于...

    Android流式布局,支持单选、多选等,适合用于产品标签等。

    Android流式布局,支持单选、多选等,适合用于产品标签等。 ##特色 以setAdapter形式注入数据 直接设置selector为background即可完成标签选则的切换,类似CheckBox 支持控制选择的Tag数量,比如:单选、多选 支持...

    支持单选、多选、全选、全不选、自定义模式的listview

    本示例着重介绍如何实现一个功能丰富的ListView,支持单选、多选、全选、全不选以及自定义选择模式。以下是对这些功能的详细解释: 1. **单选模式**:在单选模式下,ListView中的每一项只能有一个被选中。通常情况...

    Android 树形结构开发demo,实现单选多选功能

    本教程将详细讲解如何利用Android技术实现一个支持单选和多选功能的树形结构示例。 首先,我们需要理解树形结构的基本概念。树形结构是由节点(Node)组成的一种数据结构,每个节点可以有零个或多个子节点。在...

    Android recycleview嵌套checkbox,实现单选和多选

    本文将详细讲解如何在RecyclerView中结合CheckBox实现单选和多选,并讨论左右分层的布局方式,类似listFragment的效果。 首先,我们需要创建一个自定义的ViewHolder,它包含一个CheckBox和其他视图。ViewHolder是...

Global site tag (gtag.js) - Google Analytics