layUI之DataTable数据表格组件V1.0


概述

  公司项目中对于表格操作的要求较多,比如“父子表格关联进行数据传递”、“表格中使用select组件”、“表格中使用日期控件”、“表格输入格式验证”、“数据表格新增(删除)一行”等等...

  而这些内容在LayUI中都是不被支持的,迫于无奈自行进行了当前dataTable组件的封装。后续有什么功能再进行补充...

  PS:组件代码是自己一行一行敲得,教程是自己一个字一个字撸的。有任何欠妥之处,多多担待~

  PS:这是最初版本的1.0。2.0代码已经更新完毕,文档后续在更新哦~

一、下载与引用

  1. 下载DataTable.js   下载链接  密码:uzfh
  2. 在页面中进行模块化引用

代码示例

<script>
layui.config({
base: '../../common/' //静态资源所在路径
}).extend({
dataTable:"../lib/extend/dataTable"
}).use(["dataTable"],function(){
var dt = layui.dataTable;
});
</script>

二、组件功能介绍

  组件成功引入以后,就可以进行使用和开发了,使用主要分为这么几步:

  1. 父表格渲染(正常的列表显示)
  2. 子表格渲染(子表格的数据主要用于父表格新增数据时弹窗选取)
  3. 组件其他特色功能(输入数据验证、新增删除行、表格集成select/date组件等...)

 下面就让我们逐一开始讲解吧....

三、父表格渲染

1. HTML中声明空table一个(父表格):

 这一步与往常使用layUI的table一致,没什么好额外强调的。

<table class="layui-hide" id="dataList" lay-filter="dataList"></table>
2. JS 中对父表格进行渲染:

 注: 在【一、下载与引用】中已对dataTable.js进行了引入,且声明组件对象为dt,则后续将不再引入声明,统一使用dt表示组件对象

dt.renderParentTable({
// 父表格配置属性
});

 【郑重声明】

1、声明方法中支持传入绝大部分layUI数据表格的属性,详细支持属性请看下表。

2、暂时不支持的属性后续应该也会支持(本条不负法律责任,支不支持纯看心情,最终解释权归jh所有,不服打我呀略略略...)

3. 父表格渲染属性:

 先看一段史上最全的父表格声明渲染代码(保险起见,所有属性全部必填,不要随便省略):

dt.renderParentTable({
id:"#dataList", // 主表id
data:{totalCount:2,
list:[
{"id":1,"username":"zhangsan","email":"zhangsan","sexvalue":"1","sextext":"男","time":"2018-08-22","mobile":13},
{"id":2,"username":"lisi","email":"lisi","sexvalue":"2","sextext":"女","time":"2017-08-24","mobile":14},
{"id":3,"username":"wanger","email":"wanger","sexvalue":"3","sextext":"未知","time":"2018-06-27","mobile":15},
{"id":4,"username":"jianghao","email":"jianghao","sexvalue":"1","sextext":"男","time":"2018-08-22","mobile":16}
]
},
compareKey:"username",
height: "full-100",
page:true,
limits: [1, 2, 3, 4],
limit: 1,
cols:[ // 主表列
[{type: "checkbox",fixed: "left",width: 50}
, {field: 'username',title: 'username',minWidth: 150,align: "center"/*,edit: 'text'*/,event:'chooseUser'}
, {field: 'email',title: 'email', minWidth: 150,align: "center",edit: 'text',format:"mail"}
, {field: 'sexvalue',style:"display:none;",type:"space",width:"0%"}
, {field: 'sextext',title: 'sex', minWidth: 150,align: "center",templet:"#sexTpl",event:'select'}
, {field: 'time',title: 'time', minWidth: 150,align: "center",templet:"#timeTpl",event:'chooseDate'}
/**
* format:"int" 整形
* format:"num" 数值
* format:"tel" 手机号
* format:"money" 金额
* format:"mail" 邮箱
*/
, {field: 'mobile',title: 'mobile',minWidth: 150,align: "center",edit: 'text',format:"tel"}
]
]
});

 大体知道怎么用了吧,接下来我们看看这些属性都是啥:

属性名 作用 格式 备注
id 主表ID String 即主表HTML中的id,例:"#datalist"
data 主表渲染数据 Object 1.公司框架要求,主表只能使用data渲染,不支持URL请求
2.数据格式需包含totalCountlist两项
3.例:
{
 totalCount:2,
 list:[
  //Array行数据
 ]
}
compareKey 父子表比对字段 String 子表选择数据传入父表时,凭此字段queding
page 是否开启分页 Boolean 同layUI-table
limits 分页列表 Array 同layUI-table
limit 每页行数 int 同layUI-table
cols 设置表头 Array 1、二维数组,同layUI-table。
2、部分新增配置属性将在后续详细功能讲解。

 好了,经过这样的一通操作,父表就可以成功的渲染出来了,开心吗?

四、子表弹出渲染

1. HTML中声明空table(子表),并隐藏:
<div id="div1" style="display: none;">
<table class="layui-hide" id="dataList1" lay-filter="dataList1"></table>
</div>
2. 点击按钮渲染子表并弹出:

 看到上面父表效果图中,有一个【选择数据新增】了吗?我们要做的事点击这个按钮,弹出子表。(至于怎么做点击事件,不用我说吧~)

 点击事件函数中你需要写这些东西:

dt.renderDetaiTable({
detailId:"#div1", // 打开的弹出层id
title: '添加新模型', // 打开的弹出层标题
width:"850px",
height:"450px",
table:{ // 弹出层中表格配置
tableId:"#dataList1", // 子表id
url:setter.baseurl+"sys/user", // 子表请求的url
where:{
"token":setter.token,
}, // 需传递后台的其他参数
page:true,
limits: [1, 2, 3, 4],
limit: 1,
compareKey:"username",
map:[ // 父子表映射字段
{parent:"username",detail:"username"},
{parent:"email",detail:"email"},
{parent:"mobile",detail:"mobile"}
],
cols:[
[
{type: "checkbox"}
, {field: 'username',title: 'username',minWidth: 150,align: "center"}
, {field: 'email',title: 'email', minWidth: 150,align: "center"}
, {field: 'mobile',title: 'mobile',minWidth: 150,align: "center"}
]
]
}
});

 子表的属性要比父表多很多!精华全部都在这里,接下来我们一个一个的分析,不要眨眼哦~

3. 子表属性详解:
属性名 作用 格式 备注
detailId 子表所在div的id String 是包裹子表的弹层div哦,不是table
title 弹窗的标题 String
width 弹窗的宽度 String 要带px哦
height 弹窗的高度 String 要带px哦
table 子表table的配置 Object 在layUI的table属性基础上,拓展了很多,请看下表↓↓↓
>>> table属性详解:
属性名 作用 格式 备注
tableId 子表id String 这个是子表table的id哦
url 子表请求数据的url String 与父表不同的是,子表采用Ajax请求
where 请求数据其他参数 Object 同layUI,比如我司请求数据必备的token
page 子表是否分页 Boolean 同Layui
limits 子表分页列表 Array 同Layui
limit 子表每页条数 int 同Layui
compareKey 父子表比对字段 String 与父表的compareKey配合,共同判断数据字符重复
map 父子表字段映射 Array 1.父子表关联字段列表,数组格式
2.数组每一项为一个对象,包含parent和detail两个属性
3.例:{parent:"mobile",detail:"mob"}
表示将把子表的mob字段,赋值给父表的mobile字段
4.不在数组中的字段将不会关联传递
cols 子表表头配置 Array 二维数组,同Layui

 好了,经过这样的一通配置,点击按钮将弹出子表并加载数据:



 当你选中数据,点击确定时,将自动把子表所选数据添加到父表中。(当然,只能添加父子表compareKey不相同的字段

五、父表增/删/改/查

1. 父表开启编辑功能并进行输入验证:

 父表开启编辑功能的方式,采用layUI原生的编辑功能,即父表哪个字段需要编辑,可以在cols的对应列中,添加edit: 'text'属性开启编辑功能。

 与layUI原生编辑不同的是,本组件编辑时将进行输入验证,包括以下几种:

  1. 添加format属性,对对应的字段进行输入格式验证,验证不通过回退输入
  2. 父表的compareKey字段不可为空,且不可与已有的compareKey字段重复,验证不通过回退输入
cols:[[
/**
* 本行未添加edit: 'text'属性,不允许编辑
*/
{field: 'time',title: 'time'}
/**
* 本行未添加edit: 'text'属性,允许编辑,且format属性支持格式验证,详细如下:
* format:"int" 整形
* format:"num" 数值
* format:"tel" 手机号
* format:"money" 金额
* format:"mail" 邮箱
*/
, {field: 'mobile',title: 'mobile',edit: 'text',format:"tel"}
]]





2. 父表新增空行数据:

 上述【二、子表弹出渲染】中,我们详细讲述了如何从子表中选择并新增数据。但很多时候,我们也需要新增空行数据自行编辑;

 本组件也为大家提供了这个功能,要新增之前需开启字段的编辑功能。当然,你不开启也行,只不过这个字段无法录入数据(后续通过弹出选择、select选择,date选择的除外)

 编辑时的验证对新增依然有效,再强调一遍,compareKey字段不可为空不可重复。

 好了,该强调的强调完了,新增空行非常简单,点击按钮调用组件提供的现场功能即可:

dt.addParentRow();
3. 删除表格数据:

 删除非常简单,选中你要删除的行,调用组件提供的现成方法即可。删除时将返回所有被删除的行:

var delRows = dt.delParentRow();
console.log(delRows); // 所有被删除的行
4. 获取表格所有行数据:

 组件提供现成方法:

dt.getParentTableRows()
5. 根据指定条件,对表格进行搜索:

 调用组件现成方法,并传入你要搜索的所有值(键值对),当然传入空表示清空搜索:

dt.searchParentTable({
"username":$(".searchName").val(),
"mobile":$(".searchMob").val()
});

六、其他特色功能

1. 表格指定字段,支持弹窗选择:

 有这么一种情况,比如说:新增一行数据时,用户名字段不允许用户手动输入,必须选择数据库中已有的数据。

 【功能示例】

 下表新增一行空数据,当我点击用户名字段时,弹出一个选择窗:



 当点击选择时,会将指定字段填入主表的username字段中:



 当然,如果usernamecompareKey的话,也是不允许重复的哦就是这么毫无漏洞hiahiahia



 好了,功能了解完成后,我们开始操作吧!需要做的比较多,大家一步步的记清楚哦:

 ① 制作一个点击需要打开的HTML页面

 里面的html和js代码你可以随便写。但是当点击选择的时候,你必须要关闭当前弹窗,同时将所选数据存入localStorage中:

table.on('tool(dataList)', function (obj) {
var layEvent = obj.event;
if (layEvent === 'choose') {
// 将所选数据存入localStorage中,这里使用的是layUI提供的存储方式,不懂的可以去看文档
layui.data(setter.tableName, {
key: 'chooseValue'
,value: obj.data
});
// 存完以后关闭弹窗
var index = parent.layer.getFrameIndex(window.name);
setTimeout(function(){parent.layer.close(index)}, 300);
}
});

 ② 主表中点击指定单元格,弹出HTML页面

主表的cols中为指定字段添加event属性:

cols:[[
{field: 'username',title: 'username',event:'chooseUser'}
]]

event属性添加事件监听:

即,点击单元格弹窗,其他的都不重要,弹窗的end非常重要,在这个回调中你需要做这些事情:

 a. 取到我们存在localStorage中的数据

var chooseUser = layui.data(setter.tableName).chooseValue;

 b. 调用组件的updateParentTableRow()方法,并传入表格行对象、行this、选中数据的字段与表格字段的对应关系:

dt.updateParentTableRow(obj,this,chooseUser,{
chooseField:"username", // 选中对象的字段
tableField:"username", // 对应表格的字段
});

 c. 用完即毁。 销毁存在localStorage中的数据! 这一步你必须要做,不然后果自负....

layui.data(setter.tableName, {
key: 'chooseValue'
,remove: true
});

 最后,完整代码送给大家copy:

table.on('tool(dataList)',function(obj){
if(obj.event == 'chooseUser'){
top.layer.open({
type: 2
,title: '选择用户'
,content: 'modules/common/chooseUser.html'
,area: ['1200px', '600px']
,success: function (layero, index) {},
end:function(){
var chooseUser = layui.data(setter.tableName).chooseValue;
/**
* param1 - 表格行对象
* param2- this
* param3 - 选中的数据
* param4 - 其他参数
*/
dt.updateParentTableRow(obj,this,chooseUser,{
chooseField:"username", // 选中对象的字段
tableField:"username", // 对应表格的字段
}); layui.data(setter.tableName, {
key: 'chooseValue'
,remove: true
});
}
})
}
});

 当然,你也可以将这个功能用在普通input的选择上,使用思路相同,将数据先存到localStorage中,在页面销毁的时候为输入框复制。 只不过就不用调用updateParentTableRow()方法了,用完即毁就行……

2. 表格集成select组件:

 话不多说,先看效果图



  这个组件,使用起来代码比较多,也比较复杂。 但是相对于js中封装的那些DOM操作,大家还是忍忍吧~

  a. 为表格需要使用select的字段添加templetevent。注意field应为select的显示字段,即<option></option>之间的文字。

  同时添加一个空字段,表示select的value字段。

也就是说,数据表格加载的JSON数据中,必须包含value和显示的文字

/* 数据表格的JSON数据,已省略其他字段。
* {
* totalCount:2,
* list:[{sexvalue:'1',sextext:'男'},{sexvalue:'1',sextext:'男'}]
* }
*/
cols:[[
// select的value
{field: 'sexvalue',style:"display:none;",type:"space",width:"0%"}
// select显示的文字
,{field: 'sextext',title: 'sex', minWidth: 150,align: "center",templet:"#sexTpl",event:'select'}
]]

  b. 为绑定的templet添加模板:

<script type="text/html" id="sexTpl">
// d.sextext为后台数据中,select显示的文字,非value
{{d.sextext}}<i class="layui-icon table-select-icon"></i>
</script>

  c. 为绑定的event添加事件,使用Ajax请假select的数据,并调用组件的renderTableSelect()方法,并传入指定属性,详见注释:

var sexData = [];
admin.req({
url:"sex.json",
success:function(r){
sexData = r;
}
})
table.on('tool(dataList)',function(obj){
if(obj.event == 'select'){
dt.renderTableSelect(obj,this,{
data:sexData,// select的数据
value:"id", // select数据中表示value的字段
text:"value", // select中表示显示的字段
valueField:"sexvalue" , // 数据表格中表示value的字段
textField:"sextext", // 数据表格中表示显示的字段
});
}
})

  后台返回的数据sexData的格式:

[
{
"id": 1,
"value": "女"
}
。。。
]

  d. 由于select会被遮挡,所以需要把下面这段CSS放入到页面中。后续可能考虑放到通用css中:

.table-select-icon{position:absolute;right:10px;line-height:34px;color:#d3d3d3}
.table-select-selected dl{display:block}
.table-select dl{position:absolute;left:0;padding:5px 0;z-index:999;min-width:100%;border:1px solid #d2d2d2;max-height:300px;
overflow-y:auto;background-color:#fff;border-radius:2px;box-shadow:0 2px 4px rgba(0,0,0,.12);box-sizing:border-box}
.table-select dl dd{cursor:pointer}
.table-select dl dd,.table-select dl dt{padding:0 10px;line-height:36px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.table-select dl dd.layui-this{background-color:#5FB878;color:#fff}
.table-select dl dd,.table-select dl dt{padding:0 10px;line-height:36px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.table-select dl dd:hover{background-color:#f2f2f2}

好了,这样就可以愉快的使用啦.....

3. 表格集成laydate日期组件:

  老规矩,效果图镇楼:



  这个效果的实现思路,与集成select的思路类似,下面一步一步的来分析:

  a. 页面中导入laydate组件,这个大家都懂:

layui.config({
base: '../../common/' //静态资源所在路径
}).extend({
index: 'lib/index', //主入口模块
dataTable:"../lib/extend/dataTable"
}).use(["dataTable",'laydate'],function(){
var dt = layui.dataTable,
form = layui.form,
laydate = layui.laydate;
})

  b. 为表格需要使用select的字段添加templetevent

cols:[[
{field: 'time',title: 'time',templet:"#timeTpl",event:'chooseDate'}
]]

  c. 为绑定的templet添加模板:

<script type="text/html" id="timeTpl">
<div id="test1">{{d.time}}</div>
</script>

  d. 为绑定的event添加事件(done回调函数中的内容非常重要哦~):

table.on('tool(dataList)',function(obj){
if(obj.event == 'chooseDate'){
var field = $(this).data("field");
laydate.render({
elem: '#test1',
trigger:"click",
show:true,
closeStop: '#test1',
// type:"datetime",
// format:"yyyy-MM-dd HH:mm:ss",
done:function(value){
obj.data[field] = value;
obj.update(obj.data);
}
});
}
});

  截止现在,laydate组件也可以老老实实的展示在数据表格中啦~

七、最后说点啥

  1、 组件是针对我们公司需求进行设计的,可能其他人用起来不一定那么顺手,大家可以取其精华、去其糟粕。

  2、 时间能力有限,部分功能不算太完善,后续还会慢悠悠的进行完善,大家也不用太期待了~

  3、 愿世界和平......

layUI之DataTable组件V1.0(父子表管理传值/数据表格与select&laydate结合等)的更多相关文章

  1. Layui事件监听(表单和数据表格)

    一.表单的事件监听 先介绍一下几个属性的用法 1.lay-filter 事件过滤器 相当于选择器,layui的专属选择器 2.lay-verify 验证属性 属性值可以是 :required必填项, ...

  2. MySql常用操作语句(2:数据库、表管理以及数据操作)

    本文主要内容转自一博文. 另外可供参考资源: SQL语句教程 SQL语法 1.数据库(database)管理  1.1 create 创建数据库 mysql> create database f ...

  3. 基于Qt5.5.0的sql数据库、SDK_tts文本语音朗读的CET四六级单词背诵系统软件的编写V1.0

    作者:小波 QQ:463431476 请关注我的博客园:http://www.cnblogs.com/xiaobo-Linux/ 我的第二款软件:CET四六级单词背诵软件.基于QT5.5.0.sql数 ...

  4. C# 表复制和数据行的复制说明(Clone、ImportRow 、Copy )

    /// <summary> /// 构建测试数据表 /// </summary> /// <returns></returns> private Dat ...

  5. oracle维护表空间和数据文件

    1:重要参考 wiki 2: oracle doc 表空间参考 3:来自dba-oracle的参考 26,27,28,29 一:oracle 表空间概念 表空间是联系数据库的物理磁盘(数据文件)和逻辑 ...

  6. PHP中的表单传值

     前言:试想一下如果PHP没有了表单传值,那么就相当于一个没有表达能力的人,因此表单传值在php中是相当重要的,但是不难,接下来我们一起来探讨一下吧------> (一)什么是表单传值 概念:表 ...

  7. Sqlite 复制表结构和数据

    复制表结构 ; 复制表结构和数据 create table newTb as select * from oldTb:

  8. ThreadLocal父子线程之间的数据传递问题

    一.问题的提出 在系统开发过程中常使用ThreadLocal进行传递日志的RequestId,由此来获取整条请求链路.然而当线程中开启了其他的线程,此时ThreadLocal里面的数据将会出现无法获取 ...

  9. 【转】Oracle 表空间与数据文件

    --============================== --Oracle 表空间与数据文件 --============================== /* 一.概念 表空间:是一个或 ...

  10. ORACLE - 管理表空间和数据文件

    ORACLE表空间是一个逻辑分区,一个数据文件只能属于一个表空间,一个表空间可以拥有多个数据文件. 一般情况下,如果一个实例分配给多个应用使用,需要创建不同的表空间,每个用户使用自己的表空间. 一.表 ...

随机推荐

  1. nodejs的框架koa

    koa:应用程序是一个包含一组中间件函数的对象,它是按照类似堆栈的方式组织和执行的 应用程序: 1.导入 const Koa = require('koa'); 2.创建koa的app实例 const ...

  2. promise一脸懵逼...

    // 要求:封装一个方法,能根据路径读取文件,并把内容返回 const fs=require('fs') const path=require('path') 1. 普通读取文件的方式 1 const ...

  3. Python项目案例开发从入门到实战-1.5Python文件的使用

    Python对文件的操作通常按照三个步骤进行: un 使用open()函数打开(或建立)文件,并返回一个file对象. deux 使用file对象的读写方法对文件进行读写操作. trois 使用fil ...

  4. zookeeper异常

    1. KeeperErrorCode = Unimplemented for /service 在使用curator时,对zk有版本匹配关系. Curator 2.**    <--->  ...

  5. HAL层分析

    1. 安卓HAL模块基本 2. 定义hal层代码的5个特性 1)硬件抽象层具有与硬件的密切相关性. 2) 硬件抽象层具有与操作系统无关性. 3) 接口定义的功能应该包含硬件或者系统所需硬件支持的所有功 ...

  6. SAP BADI总结

    SAP里标准拼法是BAdI,区分大小写.太麻烦,文章里全用大写. BADI技术的底层是接口,类等面向对象开发的内容. Classic BADI是一个BADI包了一个接口.实现它的话,需要一个接口的实现 ...

  7. Linux邮件mail.rc配置,发件服务配置

    Linux邮件mail.rc配置 前提条件 邮箱需要开启smtp功能 关闭selinux和防火墙 1.  安装mailx yum install -y mailx 2.  配置/etc/mail.rc ...

  8. 记一次 .NET某汽车零件采集系统 卡死分析

    一:背景 1. 讲故事 前段时间有位朋友在微信上找到我,说他的程序会出现一些偶发卡死的情况,让我帮忙看下是怎么回事,刚好朋友也抓到了dump,就让朋友把 dump 丢给我,接下来用 windbg 探究 ...

  9. 如何让excel不转换科学技术法

    使用场景: 业务部门从系统导出数据给开发人员,打开后数字全部变为科学计数法 参考文章:https://www.zhihu.com/question/20096750

  10. 人人皆可虚拟,直播还能这么玩?声网推出 MetaLive 元直播解决方案

    视频群聊.在线社交.电商带货.游戏竞技.......越来越多的场景融入了直播这一功能.无可厚非,直播可以拉近人与人间的距离,让彼此间的交流更具象.但传统直播场景更为强调主播个人的表现,用户多以围观.刷 ...