返回介绍

extJS checkBoxColunmTree 可以选择带 checkBox 的树(tree、grid)

发布于 2025-02-25 12:38:57 字数 14126 浏览 0 评论 0 收藏 0

checkBoxColunmTree.html

可以选择节点的多列的树,也可以说是可以分组选择的 grid。既是 tree 也是 grid。

column-tree.css 这个文件在 ext2.2 版本中的 ext-2.2/examples/tree 这个目录下会找到这个文件的。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
<html>  
  <head>  
  <title>checkBoxColunmTree.html</title>  

  <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
  <meta http-equiv="description" content="this is my page">  
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">  
  <link rel="stylesheet" type="text/css" href="ext/resources/css/ext-all.css" />  
  <link rel="stylesheet" type="text/css" href="ext/resources/css/column-tree.css" />  
  <script type="text/javascript" src="ext/adapter/ext/ext-base.js"></script>  
  <script type="text/javascript" src="ext/ext-all.js"></script>  
  <script type="text/javascript" src="ext/ColumnTree.js"></script>  

  <script type="text/javascript">  
    Ext.onReady(function () {  
      Ext.BLANK_IMAGE_URL = 'ext/resources/images/default/s.gif';  
      var tree = new Ext.tree.ColumnTree({   
        width:568,   
        height:300,   
        border: false,   
        lines: false,   
        animate: false,   
        rootVisible: false,   
        autoScroll:true,   
        checkModel:'cascade',//级联多选,如果不需要 checkbox,该属性去掉   
        onlyLeafCheckable: false,//所有结点可选,如果不需要 checkbox,该属性去掉   
        loader: new Ext.tree.TreeLoader({  
          dataUrl: '../TreeDataServlet',//'column-data.json',  
          uiProviders:{  
            'col': Ext.ux.ColumnTreeCheckNodeUI//如果不需要 checkbox,则需要使用 Ext.tree.ColumnTreeNodeUI   
          }  
        }),  
        columns:[   
          { header:'商品名称', width:170, dataIndex:'commodityName'},   
          { header:'编号', width:70, dataIndex:'id'},  
          { header:'代理/公司', width:180, dataIndex:'proxyName' },   
          { header:'价格', width:70, dataIndex:'price'}  
        ],   
        root: new Ext.tree.AsyncTreeNode({  
          text: '代理/公司'  
        }),  
        tbar:['公司名称:',{xtype:'textfield',id:'proxyName'},'商品名称:',{xtype:'textfield',id:'commodityName'},{text:'查询'}]   
      });   
      var win = new Ext.Window({   
        title: 'Example column tree',   
        width:582,   
        height:388,   
        border :true,   
        resizable : false,   
        items: tree,   
        buttonAlign:'center',   
        buttons:[{text:'确定'},{text:'关闭'}]   
      });   
      win.show();  
    });  
  </script>  
  </head>  

  <body>  
  </body>  
</html> 

后台 java 代码

TreeDataServlet.java

package com.hoo.servlet;  
import java.io.IOException;  
import java.io.PrintWriter;  
import javax.servlet.ServletException;  
import javax.servlet.http.HttpServlet;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
public class TreeDataServlet extends HttpServlet {  
  public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
    this.doPost(request, response);  
  }  
  public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
    response.setContentType("text/text");  
    response.setCharacterEncoding("UTF-8");  
    PrintWriter out = response.getWriter();  

    StringBuffer resultStr = new StringBuffer();  
    resultStr.append("[{");  
    resultStr.append("id: ' 10000',");  
    resultStr.append("commodityName: '微软鼠标',");  
    resultStr.append("uiProvider: 'col',");  
    //得到 group 值  
    resultStr.append("children: [{");  
      resultStr.append("id: ' 100000',");  
      resultStr.append("proxyName: '微软代理商-中国代理 联强 ',");  
      resultStr.append("commodityName: 'IO 1.0',");  
      resultStr.append("price: '198.00',");  
      resultStr.append("leaf:true,");  
      resultStr.append("uiProvider: 'col'},");  

      resultStr.append("{id: ' 100000',");  
      resultStr.append("proxyName: '微软代理商-中国代理 联强 ',");  
      resultStr.append("commodityName: 'IE 3.0',");  
      resultStr.append("price: '298.00',");  
      resultStr.append("leaf:true,");  
      resultStr.append("uiProvider: 'col'},");  

      resultStr.append("{id: ' 100000',");  
      resultStr.append("proxyName: '微软代理商-中国代理 联强 ',");  
      resultStr.append("commodityName: 'IO 2.0',");  
      resultStr.append("price: '200.00',");  
      resultStr.append("leaf:true,");  
      resultStr.append("uiProvider: 'col'");  
      resultStr.append("}]},{");  
      resultStr.append("id: ' 20000',");  
      resultStr.append("commodityName: '罗技鼠标',");  
      resultStr.append("uiProvider: 'col',");  
      //得到 group 值  
      resultStr.append("children: [{");  
        resultStr.append("id: ' 100001',");  
        resultStr.append("proxyName: '罗技',");  
        resultStr.append("commodityName: 'max 500',");  
        resultStr.append("price: '298.00',");  
        resultStr.append("leaf:true,");  
        resultStr.append("uiProvider: 'col'},");  

        resultStr.append("{id: ' 100000',");  
        resultStr.append("proxyName: '罗技',");  
        resultStr.append("commodityName: 'max 518',");  
        resultStr.append("price: '298.00',");  
        resultStr.append("leaf:true,");  
        resultStr.append("uiProvider: 'col'},");  

        resultStr.append("{id: ' 100000',");  
        resultStr.append("proxyName: '罗技',");  
        resultStr.append("commodityName: 'max 520',");  
        resultStr.append("price: '245.00',");  
        resultStr.append("leaf:true,");  
        resultStr.append("uiProvider: 'col'");  
        resultStr.append("}]");  
    resultStr.append("}]");  

    out.print(resultStr.toString());  
    out.flush();  
    out.close();  
  }  
}

ext/ColumnTree.js

这个是扩展 Ext.tree.ColumnTree 的组件,只是添加了一个 Ext.ux.ColumnTreeCheckNodeUI 组件。有了这个组件我们才可以选择节点,所以这个是必须的;

/* 
 * Ext JS Library 2.0 
 * Copyright(c) 2006-2007, Ext JS, LLC. 
 * licensing@extjs.com 
 *  
 * 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" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '',  
          '<a hidefocus="on" class="x-tree-node-anchor" href="',href,'" ',  
          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]):''),"&nbsp;</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]):''),"&nbsp;</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() {  
  //多选: 'multiple'(默认)  
  //单选: 'single'  
  //级联多选: 'cascade'(同时选父和子);'parentCascade'(选父);'childCascade'(选子)  
  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);  
    }  
  }  
}); 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文