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

Posted qdjianghao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了layUI之DataTable组件V1.0(父子表管理传值/数据表格与select&laydate结合等)相关的知识,希望对你有一定的参考价值。

目录

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结合等)的主要内容,如果未能解决你的问题,请参考以下文章

layui之日期和时间组件

Vue组件通信之非父子组件传值

Vue父子组件通信之$emit(基于vue2.5,ES6)

vue组件通信之非父子组件通信

使用layui框架实战之栅格系统和菜单评分组件运用心得

react之父子组件传递