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"}
]]

開啓編輯功能的字段
不符合format要求的提示
compareKey字段不可重複不可爲空

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組件:

 話不多說,先看效果圖
表格集成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日期組件:

  老規矩,效果圖鎮樓:
表格集成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、 願世界和平......

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章