带checkbox的TreeView的赋值与读值
日前做一个用户权限管理的页面,权限是一个树形结构,每个节点前是一checkbox,其状态表示
用户是否具有该权限,当切换用户时,根据选择用户的权限设置树形的相应节点,保存时根据当
前用户的选中情况保存数据。
画面如下:
其间主要碰到三个问题
1)带checkbox的TreeView的显示
2)根据用户权限数据对权限树赋值
3)根据树形中checkbox的状态获取权限数据
其解决办法如下:
1)
HTML中展现TreeView的div需要将class设为"ygtv-checkbox"
另外javascript里要做如下处理(详细功用参见注释):
2)
可以用TreeView的getNodeByIndex或者getNodeByProperty取得节点,然后
使用Node的unhighlight不选,用highlight选中节点,代码片段如下:
在设定当前用户的权限时,非叶子节点的状态可能是选中、部分选中和未选中,我
们不必自己判断,只要仅对叶子节点进行设置,然后让YUI自己去改变其上级节点状
态就可以了。
其中unhighlight,highlight的参数表示是否不改变该节点的上下级节点状态,在
清除所有checkbox时不需要改变,但在设定当前用户的权限时正好可以利用这一功能。
3)
YUI的带checkbox的TreeView其实不是真正的checkbox,是用css切换图片实现的,所以
好像无法像一组checkbox一样直接取得选中信息(我是没找到),不过可以根据Node的
highlightState属性知道该节点的状态,其中0表示未选中,1未部分选中,2未选中,所
以下面这段代码可以将选中的权限的ID组成一个数组:
Javascript代码
1 |
var menuIDs = new Array(); |
2 |
var idx = 0 ; |
3 |
for (var i= 1 ; i<=menuTree.getNodeCount(); i++) { |
4 |
var node = menuTree.getNodeByIndex(i); |
5 |
if (node.highlightState > 0 ) { |
6 |
menuIDs[idx] = node.data; |
7 |
idx ++; |
8 |
} |
9 |
} |
总的感觉YUI是一个比较全面的库,虽然写法有些繁琐,但作为一个还算面面俱到的库使用
起来还是感觉蛮不错的,我只是另外少数地方用到了prototype,感觉就它们俩一般问题都
能搞定了。
最后,贴出整个页面的代码,其中很多是和TreeView无关的代码。我和后台交互的是json
格式的数据,具体我就不说明了,根据代码也能猜出个大概其了。
001 |
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd" > |
002 |
|
003 |
<html> |
004 |
|
005 |
<head> |
006 |
<meta http-equiv= "Content-Type" content= "text/html; charset=UTF-8" > |
007 |
<title>JNOC OA</title> |
008 |
|
009 |
<link rel= "stylesheet" type= "text/css" href= "http://www.cnblogs.com/js/yui_2.8.1/reset/reset.css" > |
010 |
<link rel= "stylesheet" type= "text/css" href= "http://www.cnblogs.com/js/yui_2.8.1/fonts/fonts.css" > |
011 |
<link type= "text/css" rel= "stylesheet" href= "http://www.cnblogs.com/css/common.css" /> |
012 |
|
013 |
<style type= "text/css" > |
014 |
table#pageTable { |
015 |
80 %; |
016 |
} |
017 |
|
018 |
table#pageTable tr#user { |
019 |
background-color:#FFFFCC; |
020 |
} |
021 |
|
022 |
table#pageTable tr#privilege { |
023 |
background-color:#CCFFFF; |
024 |
} |
025 |
|
026 |
table#pageTable th { |
027 |
vertical-align: top; |
028 |
} |
029 |
</style> |
030 |
|
031 |
<script type= "text/javascript" src= "http://www.cnblogs.com/js/prototype_1.6.1/prototype.js" ></script> |
032 |
<script type= "text/javascript" src= "http://www.cnblogs.com/js/yui_2.8.1/yahoo/yahoo.js" ></script> |
033 |
<script type= "text/javascript" src= "http://www.cnblogs.com/js/yui_2.8.1/yuiloader/yuiloader.js" ></script> |
034 |
<script type= "text/javascript" src= "http://www.cnblogs.com/js/common.js" ></script> |
035 |
<script type= "text/javascript" > |
036 |
var menuTree; |
037 |
|
038 |
function showMenuTree() { |
039 |
YAHOO.util.Connect.setDefaultPostHeader( false ); |
040 |
YAHOO.util.Connect.initHeader( "Accept" , "application/json" , true ); |
041 |
|
042 |
var request = YAHOO.util.Connect.asyncRequest( 'POST' , JNOCOA_ROOT_PATH + '/menuInfo/getMenuJSON.do' , { |
043 |
success: function(resp){ |
044 |
var respJSON = resp.responseText.evalJSON(); |
045 |
if (respJSON.successed) { |
046 |
var treeJSON = respJSON.returnObject.evalJSON(); |
047 |
menuTree = new YAHOO.widget.TreeView( "divMenuTree" , treeJSON); |
048 |
menuTree.subscribe( 'clickEvent' , menuTree.onEventToggleHighlight); |
049 |
menuTree.setNodesProperty( 'propagateHighlightUp' , true ); |
050 |
menuTree.setNodesProperty( 'propagateHighlightDown' , true ); |
051 |
menuTree.render(); |
052 |
} |
053 |
else { |
054 |
alert(respJSON.errors[ 0 ].message); |
055 |
} |
056 |
}, |
057 |
failure: function(error){ |
058 |
alert( "读取菜单数据错误:" + error.statusText); |
059 |
} |
060 |
}, null ); |
061 |
} |
062 |
|
063 |
function loadUsers() { |
064 |
YAHOO.util.Connect.setDefaultPostHeader( false ); |
065 |
YAHOO.util.Connect.initHeader( "Accept" , "application/json" , true ); |
066 |
|
067 |
var request = YAHOO.util.Connect.asyncRequest( 'POST' , JNOCOA_ROOT_PATH + '/userInfo/getAllUser.do' , { |
068 |
success: function(resp){ |
069 |
var respJSON = resp.responseText.evalJSON(); |
070 |
if (respJSON.successed) { |
071 |
users = respJSON.returnObject; |
072 |
var seleUser = $( "userList" ); |
073 |
for (var i= 0 ; i<users.length; i++) { |
074 |
oOption = document.createElement( 'option' ); |
075 |
oOption.appendChild(document.createTextNode(users[i].name)); |
076 |
oOption.setAttribute( 'value' , users[i].id); |
077 |
seleUser.appendChild(oOption); |
078 |
} |
079 |
|
080 |
YAHOO.util.Event.addListener(seleUser, "change" , refreshPrivilege); |
081 |
} |
082 |
else { |
083 |
alert(respJSON.errors[ 0 ].message); |
084 |
} |
085 |
}, |
086 |
failure: function(error){ |
087 |
alert( "读取用户数据错误:" + error.statusText); |
088 |
} |
089 |
}, null ); |
090 |
} |
091 |
|
092 |
function refreshPrivilege() { |
093 |
var selectedIdx = this .selectedIndex; |
094 |
var userID = parseInt( this .options[selectedIdx].getAttribute( 'value' )); |
095 |
|
096 |
//准备POST数据:用户ID |
097 |
var data = $H( { id : userID }).toJSON(); |
098 |
|
099 |
YAHOO.util.Connect.setDefaultPostHeader( false ); |
100 |
YAHOO.util.Connect.initHeader( "Accept" , "application/json" , true ); |
101 |
YAHOO.util.Connect.initHeader( "Content-Type" , "application/json; charset=utf-8" , true ); |
102 |
|
103 |
var request = YAHOO.util.Connect.asyncRequest( 'POST' , JNOCOA_ROOT_PATH + '/privilege/get.do' , { |
104 |
success: function(resp){ |
105 |
var respJSON = resp.responseText.evalJSON(); |
106 |
if (respJSON.successed) { |
107 |
menus = respJSON.returnObject.menuIDs; |
108 |
//清除所有checkbox |
109 |
for (var i= 1 ; i<=menuTree.getNodeCount(); i++) { |
110 |
menuTree.getNodeByIndex(i).unhighlight( true ); |
111 |
} |
112 |
//勾选叶子节点的checkbox,它们的上级节点状态会自动跟着变化,不用设置 |
113 |
for (var i= 0 ; i<menus.size(); i++) { |
114 |
var node = menuTree. getNodeByProperty( 'data' , menus[i]); |
115 |
if (!node.hasChildren( true )) { |
116 |
node.highlight( false ); |
117 |
} |
118 |
} |
119 |
} else { |
120 |
alert(respJSON.errors[ 0 ].message); |
121 |
} |
122 |
}, |
123 |
failure: function(error){ |
124 |
alert( "读取用户权限数据错误:" + error.statusText); |
125 |
} |
126 |
}, data); |
127 |
} |
128 |
|
129 |
function savePrivilege() { |
130 |
if (!menuTree) { |
131 |
return ; |
132 |
} |
133 |
|
134 |
var selectedIdx = $( 'userList' ).selectedIndex; |
135 |
var userID = parseInt($( 'userList' ).options[selectedIdx].getAttribute( 'value' )); |
136 |
var menuIDs = new Array(); |
137 |
var idx = 0 ; |
138 |
for (var i= 1 ; i<=menuTree.getNodeCount(); i++) { |
139 |
var node = menuTree.getNodeByIndex(i); |
140 |
if (node.highlightState > 0 ) { |
141 |
menuIDs[idx] = node.data; |
142 |
idx ++; |
143 |
} |
144 |
} |
145 |
|
146 |
var data = $H( { userID : userID, menuIDs : menuIDs }).toJSON(); |
147 |
|
148 |
YAHOO.util.Connect.setDefaultPostHeader( false ); |
149 |
YAHOO.util.Connect.initHeader( "Accept" , "application/json" , true ); |
150 |
YAHOO.util.Connect.initHeader( "Content-Type" , "application/json; charset=utf-8" , true ); |
151 |
|
152 |
var request = YAHOO.util.Connect.asyncRequest( 'POST' , JNOCOA_ROOT_PATH + '/privilege/change.do' , { |
153 |
success: function(resp){ |
154 |
var respJSON = resp.responseText.evalJSON(); |
155 |
if (respJSON.successed) { |
156 |
alert( '已成功修改用户权限。' ); |
157 |
} else { |
158 |
alert(respJSON.errors[ 0 ].message); |
159 |
} |
160 |
}, |
161 |
failure: function(error){ |
162 |
alert( "修改用户权限失败:" + error.statusText); |
163 |
} |
164 |
}, data); |
165 |
} |
166 |
|
167 |
new YAHOO.util.YUILoader( { |
168 |
require : [ 'menu' , 'event' , 'connection' , 'datasource' , 'datatable' , 'treeview' ], |
169 |
base : 'http://www.cnblogs.com/js/yui_2.8.1/' , |
170 |
filter : 'RAW' , |
171 |
onSuccess : function() { |
172 |
YAHOO.util.Event.onContentReady( "menubar" , function() { |
173 |
getMenu(); |
174 |
}); |
175 |
|
176 |
YAHOO.util.Event.onContentReady( "userList" , function() { |
177 |
loadUsers(); |
178 |
}); |
179 |
|
180 |
YAHOO.util.Event.onContentReady( "divMenuTree" , function() { |
181 |
showMenuTree(); |
182 |
}); |
183 |
}, |
184 |
onFailure : function(o) { |
185 |
alert( "YUI模块加载错误: " + YAHOO.lang.dump(o)); |
186 |
} |
187 |
}).insert(); |
188 |
</script> |
189 |
</head> |
190 |
|
191 |
<body class = "yui-skin-sam" > |
192 |
<div id= "banner" ></div> |
193 |
<div id= "menu" > |
194 |
<div id= "menubar" class = "yuimenubar yuimenubarnav" > |
195 |
<div class = "bd" > |
196 |
<ul class = "first-of-type" > |
197 |
<li class = "yuimenubaritem first-of-type" > |
198 |
<a class = "yuimenubaritemlabel" >数据录入</a> |
199 |
</li> |
200 |
<li class = "yuimenubaritem" > |
201 |
<a class = "yuimenubaritemlabel" >数据修改</a> |
202 |
</li> |
203 |
<li class = "yuimenubaritem" > |
204 |
<a class = "yuimenubaritemlabel" >数据检索</a> |
205 |
</li> |
206 |
<li class = "yuimenubaritem" > |
207 |
<a class = "yuimenubaritemlabel" >报表</a> |
208 |
</li> |
209 |
<li class = "yuimenubaritem" > |
210 |
<a class = "yuimenubaritemlabel" >系统</a> |
211 |
</li> |
212 |
</ul> |
213 |
</div> |
214 |
</div> |
215 |
</div> |
216 |
<div id= "desktop" > |
217 |
<div id= "pageTitle" >用户权限管理</div> |
218 |
<table id= "pageTable" > |
219 |
<tr id= "user" > |
220 |
<th width= "10%" >用户:</th> |
221 |
<td> |
222 |
<select id= "userList" > |
223 |
<option value= "-1" >请选择用户</option> |
224 |
</select> |
225 |
<button onclick= "savePrivilege()" >保存</button> |
226 |
</td> |
227 |
</tr> |
228 |
<tr id= "privilege" > |
229 |
<th>权限:</th> |
230 |
<td><div id= "divMenuTree" class = "ygtv-checkbox" ></div></td> |
231 |
</tr> |
232 |
</table> |
233 |
</div> |
234 |
|
235 |
<div id= "footer" > |
236 |
<table width= "100%" > |
237 |
<tr> |
238 |
<td id= "loginUser" width= "200px" ></td> |
239 |
<td width= "500px" ></td> |
240 |
<td width= "100px" align= "right" ><a href= "javascript:logout();" >退出</a></td> |
241 |
</tr> |
242 |
</table> |
243 |
</div> |
244 |
</body> |
245 |
|
246 |
</html> |