KendoUI TreeList 在线编辑+升级降级功能
效果图
源码
<!DOCTYPE html>
<html>
<head>
<meta name="renderer" content="webkit" />
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<style>
* {
font-size: 14px;
padding: 0px;
margin: 0px;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
</style>
<script src="~/Scripts/jquery-1.10.2.js"></script>
<link href="~/Scripts/plugins/plugins/kendoexam/css/fontawesome-all.min.css" rel="stylesheet">
<link href="~/Scripts/plugins/plugins/kendoexam/css/flag-icon.min.css" rel="stylesheet" />
<link href="~/Scripts/plugins/plugins/kendoexam/css/weather-icons.min.css" rel="stylesheet">
<link href="~/Scripts/plugins/plugins/kendoexam/css/kendo.ui.widgets.icon.css" rel="stylesheet">
<link href="~/Scripts/plugins/plugins/kendoexam/css/kendo-edit.css" rel="stylesheet">
<script src="~/Scripts/bootstrap.min.js"></script>
<link id="Amikoko" href="~/Scripts/plugins/plugins/kendoexam/css/themes/theme_default.min.css?v=1" rel="stylesheet">
<link href="~/Scripts/plugins/plugins/kendoexam/css/amikoko.admin.css" rel="stylesheet">
<script src="~/Scripts/plugins/plugins/kendoexam/js/jquery.min.js"></script>
<script src="~/Scripts/plugins/plugins/kendoexam/js/kendo.all.min.js?v=1"></script>
<script id="IKKI" src="~/Scripts/plugins/plugins/kendoexam/js/global/kendo.zh-CHS.js"></script>
<script src="~/Scripts/plugins/plugins/kendoexam/js/ikki.js"></script>
</head>
<body>
<table>
<tr>
<td style="vertical-align:top; width:200px;">
<div class="card position-absolute ">
<p style="font-weight:bold;font-size:16px;">集团组织</p>
<div class="row no-gutters h-100 overflow-hidden">
<div class="col-xl-3 h-100 overflow-auto">
<div class="card-body">
<p><span class="k-textbox k-space-left w-100"><input id="keywords" name="keywords" type="text" placeholder="关键字搜索"><a class="k-icon k-i-search k-required ml-1" href="javascript:;"></a></span></p>
<div id="treeView"></div>
</div>
</div>
<div class="col-xl-9 h-100 overflow-auto k-alt">
<div class="card-body">
<div id="treeDetail"></div>
</div>
</div>
</div>
</div>
</td>
<td style="vertical-align:top;">
<div class="row no-gutters h-100 overflow-hidden">
<p style="font-weight:bold;font-size:16px;">岗位树形列表</p>
<div class="card-body">
<div id="incellTreeList"></div>
</div>
</div>
</td>
<td style="width:5px;"></td>
<td style="vertical-align:top;">
<div class="row no-gutters h-100 overflow-hidden">
<p style="font-weight:bold;font-size:16px;">岗位汇报关系</p>
<div class="card-body">
<div id="generalTreeList"></div>
</div>
</div>
</td>
</tr>
</table>
<script type="text/javascript">
var treeView;
$(function () {
// 获取数据源生成树形
treeView = $('#treeView').kendoTreeView({
dataSource: {
transport: {
read: function (options) {
options.success({
"result": "y",
"msg": "数据获取错误,请重试!",
"data": [
{
"id": "01",
"text": "董事长办公室",
//"spriteCssClass": "fas fa-university k-required",
"expanded": true,
"items": [
{
"id": "0101",
"text": "总裁办公室",
// "spriteCssClass": "fas fa-user-tie k-required"
"expanded": true,
"items": [
{
"id": "010301",
"text": "执行副总裁办公室",
// "imageUrl": "img/temp/Aries.png",
// "url": "javascript:viewDetails(\"uid001\");",
"checked": true,
"expanded": true,
"items": [
{
"id": "01030101",
"text": "勘探部",
// "imageUrl": "img/temp/Cancer.png",
// "url": "javascript:viewDetails(\"uid004\");"
"expanded": true,
"items": [
{
"id": "0103010101",
"text": "勘探新项目及商务部"
},
{
"id": "0103010102",
"text": "勘探技术质控部"
}
]
}
]
}
]
}
]
}
]
})
}
},
schema: {
data: 'data',
model: {
id: 'id',
children: 'items'
}
}
},
//template:
// '#= item.text #' +
// '# if (!item.url && item.spriteCssClass !== "fas fa-user k-sprite-edit") { #' +
// '<button class="k-button k-button-icontext" οnclick="createTree(\'#= item.id #\', \'#= item.uid #\');"><span class="k-icon k-i-add"></span>新增</button>' +
// '<button class="k-button k-button-icontext" οnclick="updateTree(\'#= item.id #\', \'#= item.text #\', \'#= item.uid #\');"><span class="k-icon k-i-edit"></span>编辑</button>' +
// '<button class="k-button k-button-icontext" οnclick="destroyTree(\'#= item.id #\', \'#= item.text #\', this);"><span class="k-icon k-i-close"></span>删除</button>' +
// '# } #',
dragAndDrop: true,
drop: function (e) {
var source = treeView.dataItem(e.sourceNode),
destination = treeView.dataItem(e.destinationNode);
if (e.valid) {
$.fn.ajaxPost({
ajaxData: {
'sourceId': source.id,
'destinationId': destination.id,
'dropPosition': e.dropPosition
},
isMsg: true
});
}
},
select: function (e) {
if ($(e.node).find('button').length > 0) {
$('#treeDetail').empty();
}
},
dataBound: function () {
if ($('#treeView a.k-state-selected').length === 1) {
location.href = $('#treeView a.k-state-selected').attr('href');
}
}
}).data('kendoTreeView');
// 关键字搜索
$('#keywords').keyup(function () {
treeView.expand($('#treeView li'));
if ($(this).val() !== '') {
$('#treeView li').hide();
$('#treeView .k-in:contains(' + $(this).val() + ')').each(function () {
$(this).parents('li').show();
});
} else {
$('#treeView li').show();
}
});
});
// 增
function createTree(id, uid) {
treeView.append({
text: '<input class="k-textbox" type="text">' +
'<button class="k-button k-button-icontext" οnclick="saveCreateTree(\'' + id + '\', this);"><span class="k-icon k-i-check"></span>保存</button>' +
'<button class="k-button k-button-icontext" οnclick="cancelCreateTree(this);"><span class="k-icon k-i-cancel"></span>取消</button>',
spriteCssClass: 'fas fa-user k-sprite-edit'
}, treeView.findByUid(uid), function (e) {
setTimeout(function () {
treeView.select(e);
e.find('.k-textbox').focus();
}, 10);
});
}
// 增保存
function saveCreateTree(id, dom) {
if ($(dom).prev().val() === '') {
alertMsg('新增节点名称不能为空!', 'error');
} else {
$.fn.ajaxPost({
ajaxData: {
'parentId': id,
'text': $(dom).prev().val()
},
succeed: function () {
refreshTree();
},
isMsg: true
});
}
}
// 增取消
function cancelCreateTree(dom) {
treeView.remove($(dom).closest('li'));
setTimeout(function () {
$('#treeView').blur();
}, 10);
}
// 删
function destroyTree(id, text, dom) {
confirmMsg('删除确认', '你确定要删除<strong class="theme-m mx-1">' + text + '</strong>节点吗?', 'question', function () {
$.fn.ajaxPost({
ajaxData: {
'id': id
},
succeed: function () {
treeView.remove($(dom).closest('li'));
},
isMsg: true
});
});
}
// 改
function updateTree(id, text, uid) {
treeView.insertBefore({
text: '<input class="k-textbox" type="text" value="' + text + '">' +
'<button class="k-button k-button-icontext" οnclick="saveUpdateTree(\'' + id + '\', this);"><span class="k-icon k-i-check"></span>保存</button>' +
'<button class="k-button k-button-icontext" οnclick="cancelUpdateTree(this);"><span class="k-icon k-i-cancel"></span>取消</button>',
spriteCssClass: 'fas fa-user k-sprite-edit'
}, treeView.findByUid(uid));
setTimeout(function () {
treeView.select(treeView.findByUid(uid).prev());
treeView.findByUid(uid).hide().prev().find('.k-textbox').focus();
}, 10);
}
// 改保存
function saveUpdateTree(id, dom) {
if ($(dom).prev().val() === '') {
alertMsg('编辑节点名称不能为空!', 'error');
} else {
$.fn.ajaxPost({
ajaxData: {
'id': id,
'text': $(dom).prev().val()
},
succeed: function () {
refreshTree();
},
isMsg: true
});
}
}
// 改取消
function cancelUpdateTree(dom) {
$(dom).closest('li').next().show();
treeView.remove($(dom).closest('li'));
setTimeout(function () {
$('#treeView').blur();
}, 10);
}
// 显示详情
function viewDetails(id) {
//new kendo.data.DataSource({
// transport: {
// read: function (options) {
// $.fn.ajaxPost({
// ajaxUrl: 'json/grid.json',
// succeed: function (res) {
// options.success(res);
// },
// failed: function (res) {
// options.error(res);
// }
// });
// }
// },
// schema: {
// data: 'data'
// },
// change: function () {
// //$('#treeDetail').html(kendo.template($('#detailsTemplate').html())(this.get(id)));
// }
//}).read();
}
</script>
<script type="text/javascript">
$(function () {
// 单元格编辑树形列表
$('#incellTreeList').kendoTreeList({
dataSource: new kendo.data.TreeListDataSource({
transport: {
//create: function (options) { createItem(options, '~/Scripts/plugins/plugins/kendoexam/json/response.json') },
//destroy: function (options) { destroyItem(options, '~/Scripts/plugins/plugins/kendoexam/json/response.json') },
//update: function (options) { updateItem(options, '~/Scripts/plugins/plugins/kendoexam/json/response.json') },
read: function (options) {
options.success(
{
"result": "y",
"msg": "",
"total": 20,
"data": [
{
"id": "01",
"userName": "user000",
"realName": "勘探部经理",
"nickName": "执行副总裁",
"parentId": null,
"hasChildren": true
},
{
"id": "0101",
"userName": "user000",
"realName": "勘探新项目及商务经理",
"nickName": "",
"parentId": "01",
"hasChildren": false
},
{
"id": "0102",
"userName": "user000",
"realName": "勘探部技术质控经理",
"nickName": "",
"parentId": "01",
"hasChildren": false
}
]
});
}
},
batch: true,
schema: {
total: 'total',
data: 'data',
model: {
id: 'id',
parentId: 'parentId',
expanded: false,
fields: {
userName: { type: 'string' },
realName: { type: 'string' },
nickName: { type: 'string' },
parentId: {
nullable: true
},
hasChildren: { type: 'boolean' }
}
}
}
}),
toolbar: [
{ name: 'create' },
{ name: 'save' },
{ name: 'cancel' }
],
columns: [
{ field: 'realName', title: '岗位', width: '160px' },
{ field: 'nickName', title: '上级岗位', width: '150px' },
{
title: '操作', width: '260px',
command: [
{
name: 'up', text: '升级',
click: function (e) {
e.preventDefault();
//当前的
var curData = this.dataItem($(e.target).closest('tr'));
var treeList = $("#incellTreeList").data("kendoTreeList");
var pdata = null;
//所有的
var datas = treeList.dataItems();
//找父
for (var i = 0; i < datas.length; i++) {
if (datas[i].id == curData.parentId) {
pdata = datas[i];
break;
}
}
if (pdata == null) {
alert("已是顶级");
return;
}
//和父平级
curData.parentId = pdata.parentId;
//判断是否有子节点,用来去掉前面的黑点图表
for (var i = 0; i < datas.length; i++) {
var dataItem = datas[i];
var hasChild = false;
for (var j = 0; j < datas.length; j++) {
var jData = datas[j];
if (dataItem.id != jData.id && jData.parentId == dataItem.id) {
hasChild = true;
break;
}
}
dataItem.hasChildren = hasChild;
}
//控件重载
treeList.refresh();
}
},
{
name: 'down', text: '降级',
click: function (e) {
e.preventDefault();
debugger;
//当前的数据
var curData = this.dataItem($(e.target).closest('tr'));
//当前的索引
var curIndex = $(e.target).closest('tr').index();
if (curIndex == 0) {
alert("无上级");
return;
}
var treeList = $("#incellTreeList").data("kendoTreeList");
//上级数据
var pdata = treeList.dataItem(treeList.items()[curIndex - 1]);
if (curData.parentId == pdata.id) {
alert("已是末级");
return;
}
pdata.hasChildren = true;
//上一个做父
curData.parentId = pdata.id;
//控件重载
treeList.refresh();
}
},
{ name: 'createchild' },
{ name: 'destroy' }
]
}
],
columnMenu: false,
reorderable: false,
resizable: false,
navigatable: false,
editable: {
mode: 'incell'
},
dataBound: function (e) {
var items = e.sender.items();
for (var i = 0; i < items.length; i++) {
var dataItem = e.sender.dataItem(items[i]);
if (dataItem.isNew() && dataItem.id == "") {
dataItem.id = guid();
}
$(items[i]).find('[data-command="detail"], [data-command="createchild"], [data-command="destroy"]').show();
}
//展开所有节点
$("#incellTreeList").data("kendoTreeList").expand(".k-i-expand");
}
});
});
function guid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
</script>
<script type="text/javascript">
$(function () {
// 普通树形列表
$('#generalTreeList').kendoTreeList({
dataSource: new kendo.data.TreeListDataSource({
transport: {
read: function (options) {
options.success(
{
"result": "y",
"msg": "数据获取错误,请重试!",
"total": 20,
"data": [
{
"id": "01",
"realName": "上级:执行副总裁",
"nickName": "李坤",
"parentId": null,
"hasChildren": false
},
{
"id": "02",
"realName": "当前:勘探部经理",
"nickName": "张三",
"parentId": null,
"hasChildren": false
},
{
"id": "03",
"realName": "下级:勘探新项目及商务经理",
"nickName": "李四",
"parentId": null,
"hasChildren": false
},
{
"id": "04",
"realName": "",
"nickName": "王麻子",
"parentId": null,
"hasChildren": false
},
]
}
);
}
},
schema: {
total: 'total',
data: 'data',
model: {
id: 'id',
parentId: 'parentId',
expanded: true,
fields: {
userName: { type: 'string' },
realName: { type: 'string' },
parentId: {
nullable: true
},
hasChildren: { type: 'boolean' }
}
}
}
}),
columns: [
{
locked: true, field: 'realName', title: '岗位', width: '220px',
headerAttributes: { 'class': 'align-middle' }
},
{
field: 'nickName', title: '人员', width: '110px',
headerAttributes: { 'class': 'align-middle' }
}
],
//pageable: {
// buttonCount: 5,
// input: true,
// pageSizes: [5, 10, 15, 20, 25, 30, 50, 100, 'all'],
// refresh: true
//},
//sortable: {
// mode: 'multiple'
//},
columnMenu: false,
filterable: false,
reorderable: false,
resizable: false,
navigatable: false,
selectable: 'multiple, row'
});
});
</script>
</body>
</html>