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,"" 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() {
//多选: "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);
}
}
});