前面介绍了ColumnTree: http://www.cnblogs.com/hoojo/archive/2011/05/11/2043426.html
http://www.cnblogs.com/hoojo/archive/2011/05/11/2043453.html
加入CheckNodeColumnTree
A、首先在AccountAction中添加如下代码:
private
String jsonText;
public
String getJsonText() {
return
jsonText;
}
public String checkNodeColumnTreeData() throws Exception {
jsonText = JSONUtil.serialize(results);
//ServletActionContext.getResponse().getWriter().print(jsonText);
return "showData" ;
}
我们不直接使用Servlet的response方法,这样会使Action耦合Servlet的API。我们直接在Action中提供一个jsonText的属性,给该属性提供getter方法。然后当执行checkNodeColumnTreeData这个方法的时候,为jsonText赋值。等待请求成功,跳转到showData的视图中直接去取jsonText的值即可。
B、看看struts.xml中的配置
< action name ="account" class ="accountAction" >
< result type ="redirect" > account!show.action </ result >
< result name ="show" > /show.jsp </ result >
< result name ="showData" > /showData.jsp </ result >
< result name ="tree" type ="json" >
< param name ="excludeProperties" > acc </ param >
< param name ="contentType" > text/html </ param >
</ result >
</ action >
就配置一个result就可以了,跳转到showData页面
C、下面看看showData页面
<%@ page language= "java" import = "java.util.*" pageEncoding= "UTF-8" contentType= "text/text; charset=UTF-8" %>
${jsonText}
代码比较简单,设置下页面才contentType、然后用el表达式取出jsonText的值即可。
D、下面看看CheckNodeColumnTree代码
Ext.hoo.tree.UserCheckNodeColumnTree.js
/**
* @function CheckNode ColumnTree 多列信息的tree
* @auhor: hoojo
* @createDate: Aug 29, 2010 10:39:02 PM
* @blog: blog.csdn.net/IBM_hoojo
* @email: hoojo_@126.com
*/
Ext.ns(
"Ext.hoo.tree"
);
Ext.hoo.tree.UserCheckNodeColumnTree = Ext.extend(Ext.tree.ColumnTree, {
constructor:
function
() {
Ext.hoo.tree.UserCheckNodeColumnTree.superclass.constructor.call(
this
, {
renderTo:
"show"
,
title:
"远程数据"
,
width: 600,
hieght: 400,
autoScroll:
true
,
rootVisible:
true
,
checkModel: 'cascade' , //级联多选,如果不需要checkbox,该属性去掉
onlyLeafCheckable: false , //所有结点可选,如果不需要checkbox,该属性去掉
columns: [{
header:
"编号"
,
width: 100,
dataIndex:
"accountId"
}, {
header:
"用户名称"
,
width: 100,
dataIndex:
"username"
}, {
header:
"密码"
,
width: 100,
dataIndex:
"password"
}, {
header:
"创建时间"
,
width: 150,
dataIndex:
"createTime"
}],
loader:
new
Ext.tree.TreeLoader({
dataUrl: Ext.hoo.tree.UserCheckNodeColumnTree.TREE_DATA_URL,
clearOnLoad:
false
,
baseAttrs: {
uiProvider: Ext.ux.ColumnTreeCheckNodeUI,
leaf:
true
}
}),
root:
new
Ext.tree.AsyncTreeNode({
text:
"用户基本信息"
,
id:
"root"
})
});
}
});
Ext.hoo.tree.UserCheckNodeColumnTree.TREE_DATA_URL =
"account!checkNodeColumnTreeData.action"
;
Ext.onReady(
function
() {
Ext.BLANK_IMAGE_URL =
"ext2/resources/images/default/s.gif"
;
new
Ext.hoo.tree.UserCheckNodeColumnTree();
});
在webroot目录的jslib中加入这个文件Ext.hoo.tree.UserCheckNodeColumnTree.js,然后导入到html中即可。
E、上面的代码用到了Ext.ux.ColumnTreeCheckNodeUI这个UI,我们需要加入这个UI文件Ext.tree.ColumnTreeCheckNodeUI.js,代码如下:
/*
* 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 );
}
}
});
F、在html页面中导入这些js库即可运行示例
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
<html>
<head>
<title>UserCheckNodeColumnTree 示例</title>
<meta http-equiv= "Content-Type" content= "text/html;charset=UTF-8" />
<meta http-equiv= "author" content= "hoojo" />
<meta http-equiv= "email" content= "hoojo_@126.com" />
<meta http-equiv= "ext-lib" content= "verson 2.2" />
<meta http-equiv= "blog" content= "http://blog.csdn.net/IBM_hoojo" />
<meta http-equiv= "blog" content= "http://hoojo.cnblogs.com" />
<link rel= "stylesheet" type= "text/css" href= "ext2/resources/css/ext-all.css" />
<link rel= "stylesheet" type= "text/css" href= "jslib/column-tree.css" />
<script type= "text/javascript" src= "ext2/adapter/ext/ext-base.js" ></script>
<script type= "text/javascript" src= "ext2/ext-all.js" ></script>
<script type= "text/javascript" src= "ext2/build/locale/ext-lang-zh_CN-min.js" ></script>
<script type= "text/javascript" src= "jslib/Ext.tree.ColumnTreeCheckNodeUI.js" ></script>
<script type= "text/javascript" src= "jslib/Ext.hoo.tree.UserCheckNodeColumnTree.js" ></script>
</head>
<body>
<div id= "show" style= "margin-left: 200px; margin-top: 50px;" ></div>
</body>
</html>
运行后,效果如下:
如果有子节点的话,可以选择、展开子节点