项目需求:预实现不同角色对应不同的管理员权限,页面初始加载为角色的默认权限,不可修改,点击修改权限后才可修改权限,并且checkbox的选中效果如文中展示;
前端框架:bootstrap angularjs1
方案1:考虑浏览器的兼容性,checkebox使用图片切换,且将其作为背景图片
实现说明:左侧为角色名称,右侧为对应的管理员权限,本文仅实现权限的初始化选中及修改权限中的点击操作,对于保存,删除等功能未涉及;
- 在页面中采用两层循环,外层循环为权限模块,内层为权限模板对应的权限内容,通过外层的value和内层的module建立关联关系,在循环过程中判断权限id是否包含在存储登陆者对应权限的$scope.selectedPer字符串数组中,如果包含则ng-checked为true,checkbox为选中状态;
- checkbox动态加载,使用label input:<label>标签下的for属性命名一个目标表单id,input中id和label中的for对应,均采用{{perm.id}}动态获取,通过ng-checked和ng-click保证checkbox选中状态及选中状态的及时更新;
- ng-repeat动态生成ng-model:ng-model采用常量+id(checked_perm.id)动态获取,保证唯一性,在js中获取动态ng-model,通过如下形式:$scope["checked_"+id];同时ng-class="{'img-notChecked':!checked_{{perm.id}},'img-checked':checked_{{perm.id}}}"来保证checkbox的样式;未采用ng-init,因其只在页面初始时加载一次;
- checkbox的disabled属性:本文中的效果如下---初始时ng-disabled="true",标签不可选;→点击修改权限按钮,checkbox只要出现disabled标签就不可用,故需要将标签去掉$("input[type='checkbox']").prop("disabled", "");→点击取消或保存后,checkbox标签不可选,因之前标签取消的缘故,需要$("input[type='checkbox']").prop("disabled", "disabled");
- 为保证左右两边的背景保持高度一致,使用table的一行两列;
html
<div class="commonBg overflow no-padding" style="background: #fff;">
<table class="table" style="margin-bottom: 0;min-height: 570px;">
<tr>
<td class="col-xs-2 no-padding" style="background: #F2F2F2;">
<div class="user-group">
<!--左侧角色名称-->
<p ng-class="{'group-active' : role.id==focus}" ng-repeat="role in roles"
ng-click="changeRole(role)" >{{role.roleName}}
</p>
</div>
</td>
<td style="padding: 0 20px 0 36px;">
<div class="col-xs-12 border-line">
<div class="col-xs-9 no-padding text-font20">
{{focusName}}权限
</div>
<div class="col-xs-2 col-xs-push-1 no-padding change-name" ng-click="modifyName()">
<span>角色设置</span>
</div>
</div>
<!--渠道管理-->
<div ng-repeat="perMo in perModule" ng-show="havePerm(perMo.value)">
<div class="col-xs-12 no-padding text-gray marginT30" >
{{perMo.name}}:
</div>
<div class="col-xs-12 no-padding text-gray">
<!--右侧权限循环得到-->
<div class="col-xs-3" ng-repeat="perm in permissions | filter:{'module':perMo.value}"
ng-class="($index)%2==0?'margin20':'marginT10'" style="width: 200px;">
<ul>
<li style="width: 180px;">
<input type="checkbox" id="{{perm.id}}" ng-model="checked_perm.id"
ng-checked="isSelected(perm.id)" ng-click="updateSelection($event, perm.id)"
style="display: none;" ng-disabled="{{disableFlag}}">
<label class="tag-width" for="{{perm.id}}"
ng-class="{'img-notChecked':!checked_{{perm.id}},'img-checked':checked_{{perm.id}}}">
</label>
<span style="padding: 0 5px;" >{{perm.name}}</span>
</li>
</ul>
</div>
</div>
</div>
<div class="col-xs-12 marginT30" style="height: 10px;border-bottom: 1px solid #999;"></div>
<div class="col-xs-2 col-lg-push-5 padding20" id="modifyPower" ng-show="modify">
<btn class="btn btn-block btn-attention-active text-font16 role-width" id="modifyPower"
ng-click="modifyPower()">修改权限
</btn>
</div>
<div class="col-xs-12 padding20" id="saveOrCancel" ng-show="!modify">
<div class="col-xs-2 col-lg-push-4">
<btn class="btn btn-block btn-primary text-font16 role-width" id="save"
ng-click="save()">保存
</btn>
</div>
<div class="col-xs-2 col-lg-push-5">
<btn class="btn btn-block btn-attention-active text-font16 role-width" id="cancel"
ng-click="cancel('1')">取消
</btn>
</div>
</div>
</td>
</tr>
</table>
</div>
js
app.controller("roleManagerCtrl",['$scope','$state','$timeout','$scope','$stateParams','roleManagerService',
function ($scope,$state,$timeout,$scope,$stateParams,roleManagerService) {
//初始化角色列表
$scope.selectedPer = [];
$scope.focus = "";
$scope.$watch('roles',function(){
if($scope.roles.length>0 && CommonUtils.checkNull($scope.focus)){
$scope.getPermIds($scope.roles[0]);//默认展示第一个角色的所拥有的权限
}
})
//得到权限id数组
$scope.getPermIds = function(role){
$scope.focus = role.id;
$scope.focusName = role.roleName;
var selectedPer = role.permissions;
//先清空所有权限
$scope.selectedPer = [];
if(selectedPer!=null && selectedPer.length>0){
for(var i=0; i<selectedPer.length; i++){
$scope.selectedPer.push(selectedPer[i].id);
}
}
//初始化按钮选择
$scope.initPermSelected();
}
$scope.$watch("permissions",function(){
if($scope.permissions.length>0){
//初始化按钮选择
$scope.initPermSelected();
}
})
//按钮选中初始化
$scope.perModuleStr = [];
$scope.initPermSelected = function(){
if($scope.permissions.length>0){
for(var i=0; i<$scope.permissions.length; i++){
$scope["checked_"+$scope.permissions[i].id] = $scope.isSelected($scope.permissions[i].id);
if ($scope.perModuleStr.indexOf($scope.permissions[i].module) == -1) $scope.perModuleStr.push($scope.permissions[i].module);
}
}
}
//角色选择
$scope.updateSelection = function($event, id) {
var checkbox = $event.target;
var action = (checkbox.checked ? 'add' : 'remove');
if (action == 'add' && $scope.selectedPer.indexOf(id) == -1) $scope.selectedPer.push(id);
if (action == 'remove' && $scope.selectedPer.indexOf(id) != -1) $scope.selectedPer.splice($scope.selectedPer.indexOf(id), 1);
$scope["checked_"+id] = $scope.isSelected(id);
};
//判断是否选中
$scope.isSelected = function(id){
return $scope.selectedPer.indexOf(id)>=0;
};
//判断此权限模块里面是否含有权限(只展示含有权限的模块)
$scope.havePerm = function(value){
return $scope.perModuleStr.indexOf(value)>=0;
}
$scope.changeRole = function(role){
if(role != null){
$scope.getPermIds(role);
//默认不可编辑
$scope.notModifyPower();
}
};
$scope.disableFlag = true;
$scope.modify = true;
$scope.modifyPower = function () {
$scope.modify = false;
$("input[type='checkbox']").prop("disabled", "");
}
$scope.notModifyPower = function () {
$scope.modify = true;
$("input[type='checkbox']").prop("disabled", "disabled");
}
$scope.save = function() {
}
$scope.cancel = function(data){
if(data==1){
$scope.modify = true;
$("input[type='checkbox']").prop("disabled", true);
}else if(data==0){
$('#modalSure').modal('hide');
}
}
//以下均为模拟数据
$scope.perModule = roleManagerService.queryPerModule();//初始化权限模块,权限中的大类型
$scope.roles = roleManagerService.queryRoles();//登陆人员具有的权限
$scope.permissions = roleManagerService.queryPermissions();//初始化权限
}]);
css仅展示两张背景图片的样式
.img-notChecked {
background: url(../resource/images/notChecked-icon.png) no-repeat;
background-size: 40px 20px;
position: relative;
top: 11px;
left: 5px;
}
.img-checked {
background: url(../resource/images/checked-icon.png) no-repeat;
background-size: 40px 20px;
position: relative;
top: 11px;
left: 5px;
}
模拟数据仅说明数据类型的关系
实际效果
方案2: css3自定义checkbox,IE9不兼容,仅展示checkbox的实现具体请参考网址:https://www.html5tricks.com/css3-styled-checkbox-radiobox.html
如不想在js中实现,可将html更改为如下代码,js无需任何内容
html代码:
<div class="wrapper">
<label for="chk" class="chkbox" ng-class="{'focus on':checked,'focus':!checked}">
<span class="yes"></span>
<span class="no"></span>
<span class="toggle"></span>
</label>
<input type="checkbox" id="chk" name="chk" class="replaced" ng-model="checked">
</div>
注:此为个人笔记及总结,有误或有更好的解决方案请指正!谢谢