带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 |
width: 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> |