kendo UI之TreeList、DataSource常用方法总结
1.Kendo UI 简介
Kendo UI 是一个基于 HTML5 和 jQuery 的 UI 框架用来开发时尚Web应用。这个UI框架包括的很多 UI 控制项,数据显示组件,和自适应的手机框架,并支持数据绑定,使用模板,拖放功能。
本人主要使用的是Kendo UI Web端的jQuery的组件,因此本文所有的官网链接都指向的是Kendo UI for jQuery
Kendo UI for jQuery官网链接:https://www.telerik.com/kendo-jquery-ui
Kendo UI for jQuery在线样例:https://demos.telerik.com/kendo-ui/
Kendo UI for jQuery在线文档:https://docs.telerik.com/kendo-ui/introduction
从Kendo UI for jQuery官网链接我们可以看到一些demo样例和下载链接;
从Kendo UI for jQuery在线样例我们可以快速上手,拷贝修改Demo代码即可做出自己的web界面;
从Kendo UI for jQuery在线文档我们可以系统深入的学习Kendo UI,在线样例中的Demo仅仅是介绍了怎么使用
,更深层次的用法需要我们在在线文档中去找寻。它既是我们工作中的KendoUI工具手册。在工作中我常需要看 [API REFERENCE → JavaScript]、[WIDGETS]下的资料(如下图)
2.Kendo UI常用的功能总结
通过看demo可以很快做出很漂亮的界面,但是demo中使用到的功能还是少,并且有些显示文本或样式需要修改成自定义的,这时我们就需要从api 文档中查找相应的方法,但是api文档很庞大,找起来需要耗时间,现我将我在用TreeList时碰到的用法总结如下。
下面是一个简版的使用TreeList控件的完整的代码
<html>
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.1.528/styles/kendo.common-bootstrap.min.css">
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.1.528/styles/kendo.bootstrap.min.css">
<link href="https://codeseven.github.io/toastr/build/toastr.min.css" rel="stylesheet" type="text/css" />
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://cdn.kendostatic.com/2014.3.1316/js/jszip.min.js"></script>
<script src="http://cdn.kendostatic.com/2014.3.1316/js/kendo.all.min.js"></script>
<script src="https://codeseven.github.io/toastr/build/toastr.min.js"></script>
<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
<style type="text/css">
.btnFR{float:right};
.k-icon{
vertical-align:middle!important;
}
.k-button.k-button-icontext .k-icon, .k-button.k-button-icontext .k-image {
vertical-align: middle;
}
.form-control {
display: block;
width: 90%;
height: calc(1.5em + .75rem + 2px);
padding: .375rem .75rem;
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #495057;
background-color: #fff;
background-clip: padding-box;
border: 1px solid #ced4da;
border-radius: .25rem;
transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out;
}
.k-i-none{
opacity:0;
}
</style>
</head>
<body>
<div class="container-fluid">
<div class="group box">
<div id="treeList"></div>
</div>
</div>
<script type="text/javascript">
$(function(){
$("#treeList").kendoTreeList({
toolbar:["create","createchild","edit","destroy",
{
name:'batchDel',
text:"批量删除",
className:"btnFR",
imageClass:"k-delete",
click:function(e){
e.preventDefault();
var treeList = $("#treeList").data("kendoTreeList");
var row = treeList.select();
if(row.length==0){
toastr.warning('请选择需要删除的行');
}
var delNames = [];
var delIdList = [];
for(var i=0;i<row.length;i++){
var item = treeList.dataItem(row[i]);
delNames.push(item.name);
var delId = {id:item.id};
delIdList.push(delId);
}
swal({
title: "确定删除["+delNames.join(",")+"]么?",
icon: "warning",
buttons: true,
dangerMode: true,
})
.then((willDelete) => {
if (willDelete) {
$.ajax({
url:"/delMethod",
data:delIdList,
dataType:"json",
type:"POST",
success: function (data) {
toastr.success('删除成功');
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
toast.error("删除失败");
}
});
}
});
}
}
],
resizable:true,
selectable:"multiple",
scrollable:true,
columns:[
{field:"id",title:"主键",hidden:true},
{
field:"name",title:"名称",expandable:true,width:"350px",
template:function(item){
if(item.name.length>14){
return "<a title='"+item.name+"' name='nameCol' href='#'>"+item.name.substr(0,14)+"...</a>";
}else{
return "<a title='"+item.name+"' name='nameCol' href='#'>"+item.name+"...</a>";
}
}
},
{
field:"isvisiable",title:"是否可见",
template:function(item){
if(item.isvisiable=1)
return "是";
else
return "否";
},
//点击编辑/创建子节点按钮,在行级别显示为下拉选择框
editor:function(container,options){
if(options.model.isNew()){
//如果是新创建的节点,默认设置为1
options.model.isvisiable=1;
}
$("<select name='isvisiable' class='form-control'><option value='1' selected>男</option><option value='0'>女</option>")
.apppendTo(container);
}
},
{
field:"description",title:"描述",
//点击编辑/创建子节点按钮,在行级别显示为文本框
editor:function(container,options){
$("<textarea name='description' class='form-control' rows='5' maxlength='100'></textarea>")
.apppendTo(container);
}
},
{
//行级按钮
command:[
{name:"createchild",text:"创建子节点"},
{name:"edit",text:"编辑"},
{
name:"del",text:"删除",imageClass:"k-icon k-delete",
click:function(e){
var tr = $(e.target).closest("tr");
var data = this.dataItem(tr);
var message = "";
if(data.hasChildren==true){
message = "确定要删除["+data.name+"]及其子节点么?";
}else{
message = "确定要删除["+data.name+"]么?";
}
swal({
title: message,
icon: "warning",
buttons: true,
dangerMode: true,
})
.then((willDelete) => {
if (willDelete) {
$.ajax({
url:"/delMethod",
data:[{id:data.id}],
dataType:"json",
type:"POST",
success: function (data) {
toastr.success('删除成功');
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
toast.error("删除失败");
}
});
}
});
}
}
]
}
],
messages:{
//用于修改默认按钮的显示文本(canceledit默认的显示文本是cancel,update默认的显示文本是update
commands:{
canceledit:"取消",
update:"保存"
}
},
dataBound:function(e){
//数据在页面中显示后,会触发该事件
//用于点击名称,展开树节点
$("a[name='nameCol']").unbind("click");
$("a[name='nameCol']").click(function(e){
e.preventDefault();
var tr = $($(this).parent().parent());
if(tr.attr("aria-expanded")=="true"){
$("#treeList").data("kendoTreeList").collapse(tr);
}else{
$("#treeList").data("kendoTreeList").expand(tr);
}
});
},
dataSource:{
transport:{
read:{
method:"POST",
url:"/readTreeNode",
dataType:"json",
cache:false
},
create:function(options){
$.ajax({
url:"/createTreeNode",
dataType:"json",
data:options.data,
cache:false,
success:function(res){
options.success(res);
toastr.success('创建成功');
},
error:function(res){
options.error(res);
toastr.error('创建失败');
}
});
},
update:function(options){
$.ajax({
url:"/updateTreeNode",
dataType:"json",
data:options.data,
cache:false,
success:function(res){
options.success(res);
toastr.success('修改成功');
},
error:function(res){
options.error(res);
toastr.error('修改失败');
}
});
},
destroy:function(options){
$.ajax({
url:"/delTreeNode",
dataType:"json",
data:options.data,
cache:false,
success:function(res){
options.success(res);
toastr.success('删除成功');
},
error:function(res){
options.error(res);
toastr.error('删除失败');
}
});
},
},
schema:{
model:{
id:"id",
parentId:"pid",
fields:{
id:{field:"id",type:"string",editable:false},
pid:{field:"pid",nullable:true,type:"string"},
name:{field:"name",type:"string",validation:{required:true,required:{message:"名称不能为空"}}},
isvisiable:{field:"isvisiable",type:"number",validation:{required:true,required:{message:"名称不能为空"}}},
description:{field:"description",type:"string"}
}
}
}
}
});
});
</script>
</body>
</html>
上面代码展示效果图如下:
下面将重点说明下使用TreeList常用但是在demo中没有样例,并且查询文档很费劲的地方
- TreeList的数据格式(下面是样例)
[
{ “id”: “0”, “name”: “Item0”, “isvisiable”:1, “description”: “Item0”, “pid”: null ,hasChildren:true},
{ “id”: “1”, “name”: “Item1”, “isvisiable”:1, “description”: “Item1”, “pid”: “0” ,hasChildren:true},
{ “id”: “2”, “name”: “Item2”, “isvisiable”:1, “description”: “Item2”, “pid”: “1” ,hasChildren:false},
{ “id”: “3”, “name”: “Item3”, “isvisiable”:1, “description”: “Item3”, “pid”: “1” ,hasChildren:false},
{ “id”: “4”, “name”: “Item4”, “isvisiable”:1, “description”: “Item4”, “pid”: null ,hasChildren:true},
{ “id”: “5”, “name”: “Item5”, “isvisiable”:1, “description”: “Item5”, “pid”: null ,hasChildren:true},
{ “id”: “6”, “name”: “Item6”, “isvisiable”:1, “description”: “Item6”, “pid”: “5” ,hasChildren:true},
{ “id”: “7”, “name”: “Item7”, “isvisiable”:1, “description”: “Item7”, “pid”: “5” ,hasChildren:true},
{ “id”: “8”, “name”: “Item8”, “isvisiable”:1, “description”: “Item8”, “pid”: “7” ,hasChildren:false},
{ “id”: “9”, “name”: “Item9”, “isvisiable”:1, “description”: “Item9”, “pid”: “7” ,hasChildren:false} ]
- 后台成功返回数据,数据格式也正确,但是TreeList一直显示“No records to display”
出现这个情况,我们应注意两点
1).根节点的 parentId是否为null,若不为null,则treeList无法加载数据
2).parentId字段名为其他,则我们需要在schema中声明parentId指定为哪个字段,如下代码
(schema的model属性还能设置校验)
schema:{
model:{
id:"id",
parentId:"pid",
fields:{
id:{field:"id",type:"string",editable:false},
pid:{field:"pidz",nullable:true,type:"string"},
name:{field:"name",type:"string",validation:{required:true,required:{message:"名称不能为空"}}},
isvisiable:{field:"isvisiable",type:"number",validation:{required:true,required:{message:"名称不能为空"}}},
description:{field:"description",type:"string"}
},
expanded:false
}
}
- treeList设置为incell(即行内编辑、新增),有些字段需要自定义样式,那么参照如下代码(在columns中,添加editor即可)
columns:[
{
field:"isvisiable",title:"是否可见",width:"350px",
template:function(item){
if(item.isvisiable=1)
return "是";
else
return "否";
},
//点击编辑/创建子节点按钮,在行级别显示为下拉选择框
editor:function(container,options){
if(options.model.isNew()){
//如果是新创建的节点,默认设置一个性别
options.model.isvisiable=1;
}
$("<select name='isvisiable' class='form-control'><option value='1' selected>男</option><option value='0'>女</option>")
.appendTo(container);
}
}
]
-
toolbar默认的name属性有哪些
toolbar默认的属性有create、createchild、edit、destroy,这些属性直接toolbar[‘create’,‘createchild’,‘edit’,‘destroy’]即可在页面生成对于的button并且有默认的click事件 -
toolbar想自定义按钮如何实现
参照如下代码
toolbar:[
{
name:'batchDel',
text:"批量删除",
className:"btnFR",
imageClass:"k-delete",
click:function(e){
e.preventDefault();
var treeList = $("#treeList").data("kendoTreeList");
var row = treeList.select();
if(row.length==0){
toastr.warning('请选择需要删除的行');
}
var delNames = [];
var delIdList = [];
for(var i=0;i<row.length;i++){
var item = treeList.dataItem(row[i]);
delNames.push(item.name);
var delId = {id:item.id};
delIdList.push(delId);
}
swal({
title: "确定删除["+delNames.join(",")+"]么?",
icon: "warning",
buttons: true,
dangerMode: true,
})
.then((willDelete) => {
if (willDelete) {
$.ajax({
url:"/delMethod",
data:delIdList,
dataType:"json",
type:"POST",
success: function (data) {
toastr.success('删除成功');
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
toast.error("删除失败");
}
});
}
});
}
}
]