前面介绍了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>
运行后,效果如下:
如果有子节点的话,可以选择、展开子节点

