EXT3.0 ColumnTree带Checkbox的示例

如题所示,要做一个表格和树形相结合的界面。这个当然就需要用到ColumnTree,而又要在其中包含Checkbox,且当Checkbox被选中时,表格的权限列相应的发生变化。必然可读列的Checkbox被选中时,权限自动由0变为1。

要做带Checkbox的ColumnTree,必须要用到对普通ColumnTreeNodeUI进行扩展的ColumnTreeCheckNodeUI.js,这个js文件如下所示。

/* 
 * Ext JS Library 2.0 
 * Copyright(c) 2006-2007, Ext JS, LLC. 
 * [email protected] 
 *  
 * 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" style="display:none;" 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]):'')," </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]):'')," </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() {  
   
    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);  
        }  
    }  
});  

将这个代码粘贴到项目新建的ColumnTreeCheckNodeUI.js文件中,并在页面的头部进行引入。

<!-- 引入扩展树 -->
    <link rel="stylesheet" type="text/css" href="extExtend/ColumnNodeUI.css" />
    <link rel="stylesheet" type="text/css" href="extExtend//column-tree.css" />
    <script type="text/javascript" src="extExtend/ColumnNodeUI.js"></script>
    <script type="text/javascript" src="extExtend/ColumnTreeCheckNodeUI.js"></script>

extExtend下的文件下载地址http://download.csdn.net/download/rongyongfeikai2/4481420

然后页面中,这棵ColumnTree的写法为:

 tree = new Ext.ux.tree.ColumnTree({
    
        width: Ext.get('myTreeDiv').getWidth(),
        height: 600,
        rootVisible:true,
        autoScroll:true,
        title:'权限分配',
        renderTo: 'myTreeDiv',
        viewConfig:{
        	forceFit:true
        },

        columns:[{
            header:'模块',
            width:Ext.get('myTreeDiv').getWidth()*0.6,
            dataIndex:'GNMKMC'
        },{
            header:'可读',
            width:Ext.get('myTreeDiv').getWidth()*0.1,
            dataIndex:'KD'
        },{
            header:'可写',
            width:Ext.get('myTreeDiv').getWidth()*0.1,
            dataIndex:'KX'
        },{
            header:'审核',
            width:Ext.get('myTreeDiv').getWidth()*0.1,
            dataIndex:'SH'
        },{
            header:'权限',
            width:Ext.get('myTreeDiv').getWidth()*0.1,
            dataIndex:'QX'
        }],

        loader: new Ext.tree.TreeLoader({
            dataUrl:'servlet/GnmkColumnTreeServlet',
            uiProviders:{
                'col':  Ext.ux.ColumnTreeCheckNodeUI 
            }
        }),

        root: new Ext.tree.AsyncTreeNode({
        
           text:'****人事管理系统权限管理'
        })
    });

那么这棵树的数据从哪里来呢?我们可以看到,TreeLoader的dataUrl调用了一个Servlet。Servlet拼接了一个Json串传给tree。

request.setCharacterEncoding("utf-8");
		response.setCharacterEncoding("utf-8");
		response.setContentType("text/html");
		
		String testJson = "";
		System.out.println("进入了!!!!");
		
		testJson = "[{GNMKMC:'菜单功能',uiProvider:'col',cls:'master-task',iconCls:'task-folder',children:[{GNMKMC:'查询',KD:'<input type=\"checkbox\" onclick=\"clickCheck(this,0)\"  name=\"KD\"/>',QX:'0',uiProvider:'col',cls:'master-task',iconCls:'task-folder',leaf:true,id:'0'}]},"+
		            "{GNMKMC:'组织机构功能',KD:'<input type=\"checkbox\" onclick=\"clickCheck(this,1)\"  name=\"KD\"/>',QX:'0',uiProvider:'col',cls:'master-task',iconCls:'task-folder',leaf:true,id:'1'},"+
		            "{GNMKMC:'面板功能',KD:'<input type=\"checkbox\" onclick=\"clickCheck(this,2)\"  name=\"KD\"/>',KX:'<input type=\"checkbox\" name=\"KX\" onclick=\"clickCheck(this,2)\" />',SH:'<input type=\"checkbox\" name=\"SH\" onclick=\"clickCheck(this,2)\" />',QX:'0',uiProvider:'col',cls:'master-task',iconCls:'task-folder',leaf:true,id:'2'}]";
		
		System.out.println(testJson);
		response.getWriter().write(testJson);


我们可以看到,放的Checkbox在clickCheck中将节点的id传了出来。这样,我们就可以在clickCheck中对节点的列进行修改。

//点击了选择框
function clickCheck(checkbox,param) {

	var qxValue = 0;
	var myQx = 0;
	
	var oldNode = tree.getNodeById(param);

	if(checkbox.name == 'KD') {
    	
    		qxValue = 1;
    }else if(checkbox.name == 'KX') {
    	
    		qxValue = 2;
    }else if(checkbox.name == 'SH') {
    	
    		qxValue = 4;
    }
	//如果选择框被选中
    if(checkbox.checked) {
    
    	myQx = parseInt(oldNode.attributes.QX) + qxValue;
    }else {
    
   		myQx = parseInt(oldNode.attributes.QX) - qxValue;
    }
    oldNode.attributes.QX = myQx;
    oldNode.ui.elNode.childNodes[4].firstChild.innerHTML = myQx;
    
    judge(myQx);
}

如此,就大功告成了!

 

由于是异步加载数据,故有时不希望树可以被关闭。禁止树被关闭的代码为:

tree.on('beforecollapsenode',function(node,deep,anim){
 	
 		return false;
 	});


 

你可能感兴趣的:(function,ext,header,Class,stylesheet)