YUI:带checkbox的TreeView的赋值与读值

日前做一个用户权限管理的页面,权限是一个树形结构,每个节点前是一checkbox,其状态表示
用户是否具有该权限,当切换用户时,根据选择用户的权限设置树形的相应节点,保存时根据当
前用户的选中情况保存数据。

画面如下:
[img]http://dl.iteye.com/upload/attachment/306901/0bb3402c-b05c-3b48-a0bd-7528ad8fa72a.png[/img]

其间主要碰到三个问题

1)带checkbox的TreeView的显示
2)根据用户权限数据对权限树赋值
3)根据树形中checkbox的状态获取权限数据

其解决办法如下:
1)

HTML中展现TreeView的div需要将class设为"ygtv-checkbox"
<div id="divMenuTree" class="ygtv-checkbox"></div>


另外javascript里要做如下处理(详细功用参见注释):
menuTree = new YAHOO.widget.TreeView("divMenuTree", treeJSON);
//点击节点时变换checkbox状态
menuTree.subscribe('clickEvent', menuTree.onEventToggleHighlight);
//节点状态变化时相应改变其父、子节点的状态
menuTree.setNodesProperty('propagateHighlightUp', true);
menuTree.setNodesProperty('propagateHighlightDown', true);


2)
可以用TreeView的getNodeByIndex或者getNodeByProperty取得节点,然后
使用Node的unhighlight不选,用highlight选中节点,代码片段如下:
//清除所有checkbox
for(var i=1; i<=menuTree.getNodeCount(); i++) {
menuTree.getNodeByIndex(i).unhighlight(true);
}
//设定当前用户的权限
//只勾选叶子节点的checkbox,它们的上级节点状态会自动跟着变化,不用设置
for(var i=0; i<menus.size(); i++) {
var node = menuTree. getNodeByProperty('data', menus[i]);
if (!node.hasChildren(true)) {
node.highlight(false);
}
}


在设定当前用户的权限时,非叶子节点的状态可能是选中、部分选中和未选中,我
们不必自己判断,只要仅对叶子节点进行设置,然后让YUI自己去改变其上级节点状
态就可以了。
其中unhighlight,highlight的参数表示是否不改变该节点的上下级节点状态,在
清除所有checkbox时不需要改变,但在设定当前用户的权限时正好可以利用这一功能。

3)
YUI的带checkbox的TreeView其实不是真正的checkbox,是用css切换图片实现的,所以
好像无法像一组checkbox一样直接取得选中信息(我是没找到),不过可以根据Node的
highlightState属性知道该节点的状态,其中0表示未选中,1未部分选中,2未选中,所
以下面这段代码可以将选中的权限的ID组成一个数组:
var menuIDs = new Array();
var idx = 0;
for(var i=1; i<=menuTree.getNodeCount(); i++) {
var node = menuTree.getNodeByIndex(i);
if (node.highlightState > 0) {
menuIDs[idx] = node.data;
idx ++;
}
}


总的感觉YUI是一个比较全面的库,虽然写法有些繁琐,但作为一个还算面面俱到的库使用
起来还是感觉蛮不错的,我只是另外少数地方用到了prototype,感觉就它们俩一般问题都
能搞定了。

最后,贴出整个页面的代码,其中很多是和TreeView无关的代码。我和后台交互的是json
格式的数据,具体我就不说明了,根据代码也能猜出个大概其了。

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JNOC OA</title>

<link rel="stylesheet" type="text/css" href="../../js/yui_2.8.1/reset/reset.css">
<link rel="stylesheet" type="text/css" href="../../js/yui_2.8.1/fonts/fonts.css">
<link type="text/css" rel="stylesheet" href="../../css/common.css"/>

<style type="text/css">
table#pageTable {
width: 80%;
}

table#pageTable tr#user {
background-color:#FFFFCC;
}

table#pageTable tr#privilege {
background-color:#CCFFFF;
}

table#pageTable th {
vertical-align: top;
}
</style>

<script type="text/javascript" src="../../js/prototype_1.6.1/prototype.js"></script>
<script type="text/javascript" src="../../js/yui_2.8.1/yahoo/yahoo.js"></script>
<script type="text/javascript" src="../../js/yui_2.8.1/yuiloader/yuiloader.js"></script>
<script type="text/javascript" src="../../js/common.js"></script>
<script type="text/javascript">
var menuTree;

function showMenuTree() {
YAHOO.util.Connect.setDefaultPostHeader(false);
YAHOO.util.Connect.initHeader("Accept", "application/json", true);

var request = YAHOO.util.Connect.asyncRequest('POST', JNOCOA_ROOT_PATH + '/menuInfo/getMenuJSON.do', {
success: function(resp){
var respJSON = resp.responseText.evalJSON();
if (respJSON.successed) {
var treeJSON = respJSON.returnObject.evalJSON();
menuTree = new YAHOO.widget.TreeView("divMenuTree", treeJSON);
menuTree.subscribe('clickEvent', menuTree.onEventToggleHighlight);
menuTree.setNodesProperty('propagateHighlightUp', true);
menuTree.setNodesProperty('propagateHighlightDown', true);
menuTree.render();
}
else {
alert(respJSON.errors[0].message);
}
},
failure: function(error){
alert("读取菜单数据错误:" + error.statusText);
}
}, null);
}

function loadUsers() {
YAHOO.util.Connect.setDefaultPostHeader(false);
YAHOO.util.Connect.initHeader("Accept", "application/json", true);

var request = YAHOO.util.Connect.asyncRequest('POST', JNOCOA_ROOT_PATH + '/userInfo/getAllUser.do', {
success: function(resp){
var respJSON = resp.responseText.evalJSON();
if (respJSON.successed) {
users = respJSON.returnObject;
var seleUser = $("userList");
for (var i=0; i<users.length; i++) {
oOption = document.createElement('option');
oOption.appendChild(document.createTextNode(users[i].name));
oOption.setAttribute('value', users[i].id);
seleUser.appendChild(oOption);
}

YAHOO.util.Event.addListener(seleUser, "change", refreshPrivilege);
}
else {
alert(respJSON.errors[0].message);
}
},
failure: function(error){
alert("读取用户数据错误:" + error.statusText);
}
}, null);
}

function refreshPrivilege() {
var selectedIdx = this.selectedIndex;
var userID = parseInt(this.options[selectedIdx].getAttribute('value'));

//准备POST数据:用户ID
var data = $H( { id : userID }).toJSON();

YAHOO.util.Connect.setDefaultPostHeader(false);
YAHOO.util.Connect.initHeader("Accept", "application/json", true);
YAHOO.util.Connect.initHeader("Content-Type", "application/json; charset=utf-8", true);

var request = YAHOO.util.Connect.asyncRequest('POST', JNOCOA_ROOT_PATH + '/privilege/get.do', {
success: function(resp){
var respJSON = resp.responseText.evalJSON();
if (respJSON.successed) {
menus = respJSON.returnObject.menuIDs;
//清除所有checkbox
for(var i=1; i<=menuTree.getNodeCount(); i++) {
menuTree.getNodeByIndex(i).unhighlight(true);
}
//勾选叶子节点的checkbox,它们的上级节点状态会自动跟着变化,不用设置
for(var i=0; i<menus.size(); i++) {
var node = menuTree. getNodeByProperty('data', menus[i]);
if (!node.hasChildren(true)) {
node.highlight(false);
}
}
} else {
alert(respJSON.errors[0].message);
}
},
failure: function(error){
alert("读取用户权限数据错误:" + error.statusText);
}
}, data);
}

function savePrivilege() {
if (!menuTree) {
return;
}

var selectedIdx = $('userList').selectedIndex;
var userID = parseInt($('userList').options[selectedIdx].getAttribute('value'));
var menuIDs = new Array();
var idx = 0;
for(var i=1; i<=menuTree.getNodeCount(); i++) {
var node = menuTree.getNodeByIndex(i);
if (node.highlightState > 0) {
menuIDs[idx] = node.data;
idx ++;
}
}

var data = $H( { userID : userID, menuIDs : menuIDs }).toJSON();

YAHOO.util.Connect.setDefaultPostHeader(false);
YAHOO.util.Connect.initHeader("Accept", "application/json", true);
YAHOO.util.Connect.initHeader("Content-Type", "application/json; charset=utf-8", true);

var request = YAHOO.util.Connect.asyncRequest('POST', JNOCOA_ROOT_PATH + '/privilege/change.do', {
success: function(resp){
var respJSON = resp.responseText.evalJSON();
if (respJSON.successed) {
alert('已成功修改用户权限。');
} else {
alert(respJSON.errors[0].message);
}
},
failure: function(error){
alert("修改用户权限失败:" + error.statusText);
}
}, data);
}

new YAHOO.util.YUILoader( {
require : [ 'menu', 'event', 'connection', 'datasource', 'datatable', 'treeview' ],
base : '../../js/yui_2.8.1/',
filter : 'RAW',
onSuccess : function() {
YAHOO.util.Event.onContentReady("menubar", function() {
getMenu();
});

YAHOO.util.Event.onContentReady("userList", function() {
loadUsers();
});

YAHOO.util.Event.onContentReady("divMenuTree", function() {
showMenuTree();
});
},
onFailure : function(o) {
alert("YUI模块加载错误: " + YAHOO.lang.dump(o));
}
}).insert();
</script>
</head>

<body class="yui-skin-sam">
<div id="banner"></div>
<div id="menu">
<div id="menubar" class="yuimenubar yuimenubarnav">
<div class="bd">
<ul class="first-of-type">
<li class="yuimenubaritem first-of-type">
<a class="yuimenubaritemlabel">数据录入</a>
</li>
<li class="yuimenubaritem">
<a class="yuimenubaritemlabel">数据修改</a>
</li>
<li class="yuimenubaritem">
<a class="yuimenubaritemlabel">数据检索</a>
</li>
<li class="yuimenubaritem">
<a class="yuimenubaritemlabel">报表</a>
</li>
<li class="yuimenubaritem">
<a class="yuimenubaritemlabel">系统</a>
</li>
</ul>
</div>
</div>
</div>
<div id="desktop">
<div id="pageTitle">用户权限管理</div>
<table id="pageTable">
<tr id="user">
<th width="10%">用户:</th>
<td>
<select id="userList">
<option value="-1">请选择用户</option>
</select>
<button onclick="savePrivilege()">保存</button>
</td>
</tr>
<tr id="privilege">
<th>权限:</th>
<td><div id="divMenuTree" class="ygtv-checkbox"></div></td>
</tr>
</table>
</div>

<div id="footer">
<table width="100%">
<tr>
<td id="loginUser" width="200px"></td>
<td width="500px"></td>
<td width="100px" align="right"><a href="javascript:logout();">退出</a></td>
</tr>
</table>
</div>
</body>

</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值