Skip to content

Commit

Permalink
feature:render支持checkedKey和disabledKey
Browse files Browse the repository at this point in the history
  • Loading branch information
wangerzi committed May 17, 2019
1 parent 821889f commit 1804db4
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 57 deletions.
10 changes: 5 additions & 5 deletions README.md
Expand Up @@ -46,7 +46,7 @@ layui自身提供一个tree树形菜单,但是并不适用于权限控制中
- [x] 树转下拉树支持自定义初始递归id
- [x] render() 函数支持自定义子节点列表字段
- [ ] layer 中的 authtree 渲染说明(特别说明 iframe 中的渲染问题和修改BUG后浏览器缓存问题)
- [ ] render() 函数支持 checkedId 功能
- [x] render() 函数支持 checkedId 功能
- [x] render() 函数调用/点击时自动给所有已渲染的树 autoWidth()
- [x] 主题配置及相关说明
- [ ] 叶子节点横排
Expand Down Expand Up @@ -223,9 +223,9 @@ opt 参数如下:
| openIconContent | 展开的前显字符配置(默认是方向向下的三角形,就像这样▼) ||
| closeIconContent | 折叠的前显字符配置(默认是方向向右的三角形,就像这样▶) ||
| prefixChildStr | 有子节点的前显字符配置 | ├─ |
| checkedKey | 渲染 checked(选中状态)的属性名称 | checked |
| checkedKey | 渲染 checked(选中状态)的属性名称,支持数组 | checked |
| childKey | 渲染 子节点的属性名称 | list |
| disabledKey | 渲染 disabled(禁止选中状态)的属性名称 | disabled |
| disabledKey | 渲染 disabled(禁止选中状态)的属性名称,支持数组 | disabled |
| nameKey | 渲染 title(多选框的外显名称)的属性名称 | name |
| valueKey | 渲染 value(上传d值)的属性名称 | value |
| theme | 主题名称(取自 [已上线主题列表](https://github.com/wangerzi/layui-authtree#%E5%B7%B2%E4%B8%8A%E7%BA%BF%E4%B8%BB%E9%A2%98%E5%88%97%E8%A1%A8)| |
Expand Down Expand Up @@ -253,8 +253,8 @@ opt 参数如下:
| ---------------- | ------------------------------------------------------------ | -------- |
| childKey | 子节点列表的Key | list |
| valueKey | 值的key | value |
| checkedKey | 选中的key - 仅支持字符串 | checked |
| disabledKey | 禁用的key | disabled |
| checkedKey | 选中的key - 支持数组 | checked |
| disabledKey | 禁用的key - 支持数组 | disabled |
| prefixChildStr | 有子节点的名称显示前缀 | ├─ |
| prefixNoChildStr | 没有子节点的名称显示前缀 ||
| prefixDeptStr | 树的深度影响的子节点显示前缀 | |
Expand Down
2 changes: 1 addition & 1 deletion index.html
Expand Up @@ -150,7 +150,7 @@
<div class="layui-input-block">
<select name="authid" class="layui-input" lay-filter="{{d.layFilter}}">
{{# layui.each(d.list, function(index, item) { }}
<option value="{{item.value}}" selected="{{item.checked?'selected':'false'}}" disabled="{{item.disabled?'disabled':'false'}}">{{item.name}}</option>
<option value="{{item.value}}" {{item.checked?'selected':''}} {{item.disabled?'disabled':''}}>{{item.name}}</option>
{{# });}}
</select>
</div>
Expand Down
3 changes: 3 additions & 0 deletions index.js
Expand Up @@ -147,6 +147,7 @@ function treeConvertSelect(url) {
// 更多传入参数及其具体意义请查看文档
var selectList = authtree.treeConvertSelect(res.data.trees, {
childKey: 'list',
// checkedKey: ['glygl-tjgly'],
});
console.log(selectList);
// 渲染单选框
Expand Down Expand Up @@ -319,6 +320,8 @@ layui.use(['jquery', 'authtree', 'form', 'layer'], function(){
// ,openall: true
// ,hidechoose: true
// ,checkType: 'radio'
// ,checkedKey: 'checked'
// ,disabledKey: 'disabled'
// ,checkSkin: 'primary'
,'theme': 'auth-skin-default'
// ,'themePath': 'themes/'
Expand Down
118 changes: 68 additions & 50 deletions layui_exts/authtree.js
Expand Up @@ -70,6 +70,9 @@ layui.define(['jquery', 'form'], function(exports){
// 是否隐藏左侧 单选/多选的选框 -- 特殊需求,一般用于单选树并且不用
var hidechoose = typeof opt.hidechoose !== 'undefined' ? opt.hidechoose : false;
opt.hidechoose = hidechoose;
// 是否开启半选
var halfchoose = typeof opt.halfchoose !== 'undefined' ? opt.halfchoose : false;
opt.halfchoose = halfchoose;
// 有子节点的前显字符配置
opt.prefixChildStr = opt.prefixChildStr ? opt.prefixChildStr : '├─';
// 单选、多选配置
Expand All @@ -86,9 +89,9 @@ layui.define(['jquery', 'form'], function(exports){
opt.closeIconContent = opt.closeIconContent ? opt.closeIconContent : '&#xe623;';
this.closeIconContent = opt.closeIconContent;
// 选中、半选中、未选中节点的图标配置
opt.checkedIconContent = opt.checkedIconContent ? opt.checkedIconContent : '&#xe605;';
opt.checkedIconContent = opt.checkedIconContent ? opt.checkedIconContent : '\e605';
this.checkedIconContent = opt.checkedIconContent;
opt.halfCheckedIconContent = opt.halfCheckedIconContent ? opt.halfCheckedIconContent : '&#xe605;';
opt.halfCheckedIconContent = opt.halfCheckedIconContent ? opt.halfCheckedIconContent : '\e605';
this.halfCheckedIconContent = opt.halfCheckedIconContent;
opt.notCheckedIconContent = opt.notCheckedIconContent ? opt.notCheckedIconContent : '&#xe605;';
this.notCheckedIconContent = opt.notCheckedIconContent;
Expand Down Expand Up @@ -260,31 +263,48 @@ layui.define(['jquery', 'form'], function(exports){
var str = '<div class="auth-single">';

// 参数配置
var checkedKey = opt.checkedKey;
var childKey = opt.childKey;
var disabledKey = opt.disabledKey;
var nameKey = opt.nameKey;
var valueKey = opt.valueKey;

var _this = this;
layui.each(tree, function(index, item){
var hasChild = (item[childKey]&&(item[childKey].length || !$.isEmptyObject(item[childKey].length))) ? 1 : 0;
// 注意:递归调用时,this的环境会改变!
var append = hasChild ? obj.renderAuth(item[childKey], dept+1, opt) : '';
var openstatus = openall || (opt.openchecked && item.checked);
var isChecked = _this._getStatusByDynamicKey(item, opt.checkedKey, opt.valueKey);
var isDisabled = _this._getStatusByDynamicKey(item, opt.disabledKey, opt.valueKey);

// '+new Array(dept * 4).join('&nbsp;')+'
str += '<div class="auth-skin"><div class="auth-status" style="display: flex;flex-direction: row;align-items: flex-end;"> '+
(hasChild?'<i class="layui-icon auth-icon '+(openstatus?'active':'')+'" style="cursor:pointer;">'+(openstatus?obj.openIconContent:obj.closeIconContent)+'</i>':'<i class="layui-icon auth-leaf" style="opacity:0;color: transparent;">&#xe626;</i>')+
(dept > 0 ? ('<span>'+opt.prefixChildStr+' </span>'):'')+
'<input class="authtree-checkitem" type="'+opt.checkType+'" name="'+inputname+'" title="'+item[nameKey]+'" value="'+item[valueKey]+'" lay-skin="primary" lay-filter="'+layfilter+'" '+
(item[checkedKey]?' checked="checked"':'')+
(item[disabledKey]?' disabled':'')+
(isChecked?' checked="checked"':'')+
(isDisabled?' disabled':'')+
'> </div>'+
' <div class="auth-child" style="'+(openstatus ?'':'display:none;')+'padding-left:40px;"> '+append+'</div></div>'
});
str += '</div>';
return str;
},
// 通过动态key,获取状态信息,dynamicKey支持:数字/字符时直接取属性,对象时查看是否在数组中
_getStatusByDynamicKey: function(item, dynamicKey, valueKey) {
var isChecked = false;
if (typeof dynamicKey === "string" || typeof dynamicKey === 'number') {
isChecked = item[dynamicKey];
} else if(typeof dynamicKey === 'object') {
if ($.inArray(item[valueKey], dynamicKey) !== -1) {
isChecked = true;
} else {
isChecked = false;
}
} else {
isChecked = false;
}
return isChecked;
},
/**
* 显示到已选中的最高层级
* @param {[type]} dst [description]
Expand Down Expand Up @@ -318,44 +338,25 @@ layui.define(['jquery', 'form'], function(exports){
return [];
}
var child = [];
for (index in list) {
// 筛查符合条件的数据(主键 = startPid)
var item = list[index];
if (typeof item[opt.parentKey] !== 'undefined' && item[opt.parentKey] === startPid) {
// 满足条件则递归
var nextChild = this._listToTree(list, item[opt.primaryKey], currentDept+1, opt);
// 节点信息保存
var node = {};
if (nextChild.length > 0) {
node[opt.childKey] = nextChild;
}
node['name'] = item[opt.nameKey];
node['value'] = item[opt.valueKey];
// 已选中节点的两种渲染方式
if (typeof opt.checkedKey === "string" || typeof opt.checkedKey === 'number') {
node['checked'] = item[opt.checkedKey];
} else if(typeof opt.checkedKey === 'object') {
if ($.inArray(item[opt.valueKey], opt.checkedKey) != -1) {
node['checked'] = true;
} else {
node['checked'] = false;
}
} else {
node['checked'] = false;
}
// 禁用节点的两种渲染方式
if (typeof opt.disabledKey === "string" || typeof opt.disabledKey === 'number') {
node['disabled'] = item[opt.disabledKey];
} else if(typeof opt.disabledKey === 'object') {
if ($.inArray(item[opt.valueKey], opt.disabledKey) != -1) {
node['disabled'] = true;
} else {
node['disabled'] = false;
for (var index in list) {
if (list.hasOwnProperty(index)) {
// 筛查符合条件的数据(主键 = startPid)
var item = list[index];
if (typeof item[opt.parentKey] !== 'undefined' && item[opt.parentKey] === startPid) {
// 满足条件则递归
var nextChild = this._listToTree(list, item[opt.primaryKey], currentDept+1, opt);
// 节点信息保存
var node = {};
if (nextChild.length > 0) {
node[opt.childKey] = nextChild;
}
} else {
node['disabled'] = false;
node['name'] = item[opt.nameKey];
node['value'] = item[opt.valueKey];
// 禁用/选中节点的两种渲染方式
node['checked'] = this._getStatusByDynamicKey(item, opt.checkedKey, opt.valueKey);
node['disabled'] = this._getStatusByDynamicKey(item, opt.disabledKey, opt.valueKey);
child.push(node);
}
child.push(node);
}
}
return child;
Expand Down Expand Up @@ -402,7 +403,10 @@ layui.define(['jquery', 'form'], function(exports){
prefix += opt.prefixDeptStr;
}

for (index in tree) {
for (var index in tree) {
if (!tree.hasOwnProperty(index)) {
continue;
}
var child_flag = 0;
var item = tree[index];
if (opt.childKey in item && item[opt.childKey] && item[opt.childKey].length > 0) {
Expand All @@ -421,8 +425,8 @@ layui.define(['jquery', 'form'], function(exports){
ansList.push({
name: prefix+name,
value: item[opt.valueKey],
checked: item[opt.checkedKey],
disabled: item[opt.disabledKey],
checked: this._getStatusByDynamicKey(item, opt.checkedKey, opt.valueKey),
disabled: this._getStatusByDynamicKey(item, opt.disabledKey, opt.valueKey),
});
// 添加子节点
if (child_flag) {
Expand All @@ -448,16 +452,19 @@ layui.define(['jquery', 'form'], function(exports){
'whiteSpace': 'nowrap',
'maxWidth' : '100%',
});
// 自动刷新多选框半选状态
this.autoNodeRender(dst)
// 自动宽度调整的逻辑
$(dst).find('.layui-form-checkbox,.layui-form-radio,.layui-form-audio').each(function(index, item){
var width = $(this).find('span').width() + $(this).find('i').width() + 25;
if ($(this).is(':hidden')) {
// 比较奇葩的获取隐藏元素宽度的手法,请见谅
$('body').append('<div id="layui-authtree-get-width">'+$(this).html()+'</div>');
$width = $('#layui-authtree-get-width').find('span').width() + $('#layui-authtree-get-width').find('i').width() + 29;
width = $('#layui-authtree-get-width').find('span').width() + $('#layui-authtree-get-width').find('i').width() + 29;
$('#layui-authtree-get-width').remove();
} else {
$width = $(this).find('span').width() + $(this).find('i').width() + 25;
}
$(this).width($width);
$(this).width(width);
// 隐藏 单选/多选的左侧选框隐藏
if (opt.hidechoose) {
$(this).prevAll('i').css({
Expand All @@ -472,6 +479,17 @@ layui.define(['jquery', 'form'], function(exports){
}
});
},
// 自动刷新多选框半选状态
autoNodeRender: function(dst) {
var tree = this.getRenderedInfo(dst);
var opt = tree.opt;
if (opt.halfchoose) {
this._nodeRenderByParent($(dst).find('.auth-single'))
}
document.styleSheets[0].addRule(dst + ' .layui-icon-ok:before', 'content: '+this.checkedIconContent)
},
_nodeRenderByParent: function(leaf) {
},
// 触发自定义事件
_triggerEvent: function(dst, events, other) {
var tree = this.getRenderedInfo(dst);
Expand Down Expand Up @@ -657,7 +675,7 @@ layui.define(['jquery', 'form'], function(exports){

var data = [];
for (i in lastCheckedNode) {
if ($.inArray(lastCheckedNode[i], this.notCheckedNode[dst]) != -1) {
if ($.inArray(lastCheckedNode[i], this.notCheckedNode[dst]) !== -1) {
data.push(lastCheckedNode[i]);
}
}
Expand All @@ -682,7 +700,7 @@ layui.define(['jquery', 'form'], function(exports){

var data = [];
for (i in lastNotCheckedNode) {
if ($.inArray(lastNotCheckedNode[i], this.checkedNode[dst]) != -1) {
if ($.inArray(lastNotCheckedNode[i], this.checkedNode[dst]) !== -1) {
data.push(lastNotCheckedNode[i]);
}
}
Expand Down
2 changes: 1 addition & 1 deletion tree.json
Expand Up @@ -9,7 +9,7 @@
{"name": "添加角色", "value": "yhzgl-jsgl-tjjs", "checked": true, "disabled": false},
{"name": "角色列表", "value": "yhzgl-jsgl-jslb", "checked": false, "disabled": false}
]},
{"name": "管理员管理", "value": "glygl", "checked": false, "disabled": false, "list":[
{"name": "管理员管理", "value": "glygl-tjgly", "checked": false, "disabled": false, "list":[
{"name": "添加管理员", "value": "glygl-tjgly", "checked": false, "disabled": false},
{"name": "管理员列表", "value": "glygl-glylb", "checked": false, "disabled": true},
{"name": "管理员管理", "value": "glygl-glylb", "checked": false, "disabled": true}
Expand Down

0 comments on commit 1804db4

Please sign in to comment.