layUI之DataTable數(shù)據(jù)表格組件
[TOC]
概述
? 公司項(xiàng)目中對(duì)于表格操作的要求較多免猾,比如“父子表格關(guān)聯(lián)進(jìn)行數(shù)據(jù)傳遞”肌幽、“表格中使用select組件”、“表格中使用日期控件”瞭稼、“表格輸入格式驗(yàn)證”跨新、“數(shù)據(jù)表格新增(刪除)一行”等等...
? 而這些內(nèi)容在LayUI中都是不被支持的十性,迫于無奈自行進(jìn)行了當(dāng)前dataTable組件的封裝慧库。后續(xù)有什么功能再進(jìn)行補(bǔ)充...
? PS:組件代碼是自己一行一行敲得旺芽,教程是自己一個(gè)字一個(gè)字?jǐn)]的季稳。有任何欠妥之處擅这,多多擔(dān)待~
一、下載與引用
- 下載DataTable.js ??下載鏈接 ?密碼:uzfh
- 在頁面中進(jìn)行模塊化引用
代碼示例
<script>
layui.config({
base: '../../common/' //靜態(tài)資源所在路徑
}).extend({
dataTable:"../lib/extend/dataTable"
}).use(["dataTable"],function(){
var dt = layui.dataTable;
});
</script>
二景鼠、組件功能介紹
? 組件成功引入以后仲翎,就可以進(jìn)行使用和開發(fā)了,使用主要分為這么幾步:
- 父表格渲染(正常的列表顯示)
- 子表格渲染(子表格的數(shù)據(jù)主要用于父表格新增數(shù)據(jù)時(shí)彈窗選取)
- 組件其他特色功能(輸入數(shù)據(jù)驗(yàn)證铛漓、新增刪除行溯香、表格集成select/date組件等...)
?下面就讓我們逐一開始講解吧....
三、父表格渲染
1. HTML中聲明空table一個(gè)(父表格):
?這一步與往常使用layUI的table一致浓恶,沒什么好額外強(qiáng)調(diào)的玫坛。
<table class="layui-hide" id="dataList" lay-filter="dataList"></table>
2. JS 中對(duì)父表格進(jìn)行渲染:
?注: 在【一、下載與引用】中已對(duì)dataTable.js進(jìn)行了引入包晰,且聲明組件對(duì)象為dt
,則后續(xù)將不再引入聲明湿镀,統(tǒng)一使用dt
表示組件對(duì)象
dt.renderParentTable({
// 父表格配置屬性
});
?【鄭重聲明】
1、聲明方法中支持傳入絕大部分layUI數(shù)據(jù)表格的屬性伐憾,詳細(xì)支持屬性請(qǐng)看下表勉痴。
2、暫時(shí)不支持的屬性后續(xù)應(yīng)該也會(huì)支持(本條不負(fù)法律責(zé)任塞耕,支不支持純看心情,最終解釋權(quán)歸jh所有嘴瓤,不服打我呀略略略...)
3. 父表格渲染屬性:
?先看一段史上最全的父表格聲明渲染代碼(保險(xiǎn)起見扫外,所有屬性全部必填,不要隨便省略):
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" 數(shù)值
* format:"tel" 手機(jī)號(hào)
* format:"money" 金額
* format:"mail" 郵箱
*/
, {field: 'mobile',title: 'mobile',minWidth: 150,align: "center",edit: 'text',format:"tel"}
]
]
});
?大體知道怎么用了吧廓脆,接下來我們看看這些屬性都是啥:
屬性名 | 作用 | 格式 | 備注 |
---|---|---|---|
id | 主表ID | String | 即主表HTML中的id筛谚,例:"#datalist" |
data | 主表渲染數(shù)據(jù) | Object | 1.公司框架要求,主表只能使用data渲染停忿,不支持URL請(qǐng)求 2.數(shù)據(jù)格式需包含 totalCount 和list 兩項(xiàng)3.例: { ?totalCount:2驾讲, ?list:[ ??//Array行數(shù)據(jù) ?] } |
compareKey | 父子表比對(duì)字段 | String | 子表選擇數(shù)據(jù)傳入父表時(shí),憑此字段queding |
page | 是否開啟分頁 | Boolean | 同layUI-table |
limits | 分頁列表 | Array | 同layUI-table |
limit | 每頁行數(shù) | int | 同layUI-table |
cols | 設(shè)置表頭 | Array | 1、二維數(shù)組吮铭,同layUI-table时迫。 2、部分新增配置屬性將在后續(xù)詳細(xì)功能講解谓晌。 |
?好了掠拳,經(jīng)過這樣的一通操作,父表就可以成功的渲染出來了纸肉,開心嗎溺欧?
四、子表彈出渲染
1. HTML中聲明空table(子表)柏肪,并隱藏:
<div id="div1" style="display: none;">
<table class="layui-hide" id="dataList1" lay-filter="dataList1"></table>
</div>
2. 點(diǎn)擊按鈕渲染子表并彈出:
?看到上面父表效果圖中姐刁,有一個(gè)【選擇數(shù)據(jù)新增】了嗎?我們要做的事點(diǎn)擊這個(gè)按鈕烦味,彈出子表聂使。(至于怎么做點(diǎn)擊事件,不用我說吧~)
?點(diǎn)擊事件函數(shù)中你需要寫這些東西:
dt.renderDetaiTable({
detailId:"#div1", // 打開的彈出層id
title: '添加新模型', // 打開的彈出層標(biāo)題
width:"850px",
height:"450px",
table:{ // 彈出層中表格配置
tableId:"#dataList1", // 子表id
url:setter.baseurl+"sys/user", // 子表請(qǐng)求的url
where:{
"token":setter.token,
}, // 需傳遞后臺(tái)的其他參數(shù)
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"}
]
]
}
});
?子表的屬性要比父表多很多拐叉!精華全部都在這里岩遗,接下來我們一個(gè)一個(gè)的分析,不要眨眼哦~
3. 子表屬性詳解:
屬性名 | 作用 | 格式 | 備注 |
---|---|---|---|
detailId | 子表所在div的id | String | 是包裹子表的彈層div哦凤瘦,不是table |
title | 彈窗的標(biāo)題 | String | |
width | 彈窗的寬度 | String | 要帶px哦 |
height | 彈窗的高度 | String | 要帶px哦 |
table | 子表table的配置 | Object | 在layUI的table屬性基礎(chǔ)上宿礁,拓展了很多,請(qǐng)看下表↓↓↓ |
>>> table屬性詳解:
屬性名 | 作用 | 格式 | 備注 |
---|---|---|---|
tableId | 子表id | String | 這個(gè)是子表table的id哦 |
url | 子表請(qǐng)求數(shù)據(jù)的url | String | 與父表不同的是蔬芥,子表采用Ajax請(qǐng)求 |
where | 請(qǐng)求數(shù)據(jù)其他參數(shù) | Object | 同layUI梆靖,比如我司請(qǐng)求數(shù)據(jù)必備的token |
page | 子表是否分頁 | Boolean | 同Layui |
limits | 子表分頁列表 | Array | 同Layui |
limit | 子表每頁條數(shù) | int | 同Layui |
compareKey | 父子表比對(duì)字段 | String | 與父表的compareKey配合,共同判斷數(shù)據(jù)字符重復(fù) |
map | 父子表字段映射 | Array | 1.父子表關(guān)聯(lián)字段列表笔诵,數(shù)組格式 2.數(shù)組每一項(xiàng)為一個(gè)對(duì)象返吻,包含parent和detail兩個(gè)屬性 3.例:{parent:"mobile",detail:"mob"} 表示將把子表的mob字段,賦值給父表的mobile字段 4.不在數(shù)組中的字段將不會(huì)關(guān)聯(lián)傳遞 |
cols | 子表表頭配置 | Array | 二維數(shù)組乎婿,同Layui |
?好了测僵,經(jīng)過這樣的一通配置,點(diǎn)擊按鈕將彈出子表并加載數(shù)據(jù):
?當(dāng)你選中數(shù)據(jù)谢翎,點(diǎn)擊確定時(shí)捍靠,將自動(dòng)把子表所選數(shù)據(jù)添加到父表中。(當(dāng)然森逮,只能添加父子表compareKey不相同的字段)
五榨婆、父表增/刪/改/查
1. 父表開啟編輯功能并進(jìn)行輸入驗(yàn)證:
?父表開啟編輯功能的方式,采用layUI原生的編輯功能褒侧,即父表哪個(gè)字段需要編輯良风,可以在cols
的對(duì)應(yīng)列中谊迄,添加edit: 'text'
屬性開啟編輯功能。
?與layUI原生編輯不同的是烟央,本組件編輯時(shí)將進(jìn)行輸入驗(yàn)證统诺,包括以下幾種:
- 添加
format
屬性,對(duì)對(duì)應(yīng)的字段進(jìn)行輸入格式驗(yàn)證吊档,驗(yàn)證不通過回退輸入 - 父表的
compareKey
字段不可為空篙议,且不可與已有的compareKey
字段重復(fù),驗(yàn)證不通過回退輸入
cols:[[
/**
* 本行未添加edit: 'text'屬性怠硼,不允許編輯
*/
{field: 'time',title: 'time'}
/**
* 本行未添加edit: 'text'屬性鬼贱,允許編輯,且format屬性支持格式驗(yàn)證香璃,詳細(xì)如下:
* format:"int" 整形
* format:"num" 數(shù)值
* format:"tel" 手機(jī)號(hào)
* format:"money" 金額
* format:"mail" 郵箱
*/
, {field: 'mobile',title: 'mobile',edit: 'text',format:"tel"}
]]
2. 父表新增空行數(shù)據(jù):
?上述【二这难、子表彈出渲染】中,我們?cè)敿?xì)講述了如何從子表中選擇并新增數(shù)據(jù)葡秒。但很多時(shí)候姻乓,我們也需要新增空行數(shù)據(jù)自行編輯;
?本組件也為大家提供了這個(gè)功能眯牧,要新增之前需開啟字段的編輯功能蹋岩。當(dāng)然,你不開啟也行学少,只不過這個(gè)字段無法錄入數(shù)據(jù)(后續(xù)通過彈出選擇剪个、select選擇,date選擇的除外)
?編輯時(shí)的驗(yàn)證對(duì)新增依然有效版确,再強(qiáng)調(diào)一遍扣囊,compareKey
字段不可為空不可重復(fù)。
?好了绒疗,該強(qiáng)調(diào)的強(qiáng)調(diào)完了侵歇,新增空行非常簡(jiǎn)單,點(diǎn)擊按鈕調(diào)用組件提供的現(xiàn)場(chǎng)功能即可:
dt.addParentRow();
3. 刪除表格數(shù)據(jù):
?刪除非常簡(jiǎn)單吓蘑,選中你要?jiǎng)h除的行惕虑,調(diào)用組件提供的現(xiàn)成方法即可。刪除時(shí)將返回所有被刪除的行:
var delRows = dt.delParentRow();
console.log(delRows); // 所有被刪除的行
4. 獲取表格所有行數(shù)據(jù):
?組件提供現(xiàn)成方法:
dt.getParentTableRows()
5. 根據(jù)指定條件磨镶,對(duì)表格進(jìn)行搜索:
?調(diào)用組件現(xiàn)成方法溃蔫,并傳入你要搜索的所有值(鍵值對(duì)),當(dāng)然傳入空表示清空搜索:
dt.searchParentTable({
"username":$(".searchName").val(),
"mobile":$(".searchMob").val()
});
六、其他特色功能
1. 表格指定字段棋嘲,支持彈窗選擇:
?有這么一種情況酒唉,比如說:新增一行數(shù)據(jù)時(shí)矩桂,用戶名字段不允許用戶手動(dòng)輸入沸移,必須選擇數(shù)據(jù)庫中已有的數(shù)據(jù)痪伦。
?【功能示例】
?下表新增一行空數(shù)據(jù),當(dāng)我點(diǎn)擊用戶名字段時(shí)雹锣,彈出一個(gè)選擇窗:
?當(dāng)點(diǎn)擊選擇時(shí)网沾,會(huì)將指定字段填入主表的
username
字段中:?當(dāng)然,如果
username
是compareKey
的話蕊爵,也是不允許重復(fù)的哦就是這么毫無漏洞hiahiahia?好了辉哥,功能了解完成后,我們開始操作吧攒射!需要做的比較多醋旦,大家一步步的記清楚哦:
?① 制作一個(gè)點(diǎn)擊需要打開的HTML頁面
?里面的html和js代碼你可以隨便寫。但是當(dāng)點(diǎn)擊選擇的時(shí)候会放,你必須要關(guān)閉當(dāng)前彈窗饲齐,同時(shí)將所選數(shù)據(jù)存入localStorage中:
table.on('tool(dataList)', function (obj) {
var layEvent = obj.event;
if (layEvent === 'choose') {
// 將所選數(shù)據(jù)存入localStorage中,這里使用的是layUI提供的存儲(chǔ)方式咧最,不懂的可以去看文檔
layui.data(setter.tableName, {
key: 'chooseValue'
,value: obj.data
});
// 存完以后關(guān)閉彈窗
var index = parent.layer.getFrameIndex(window.name);
setTimeout(function(){parent.layer.close(index)}, 300);
}
});
?② 主表中點(diǎn)擊指定單元格捂人,彈出HTML頁面
主表的cols
中為指定字段添加event屬性:
cols:[[
{field: 'username',title: 'username',event:'chooseUser'}
]]
為event
屬性添加事件監(jiān)聽:
即,點(diǎn)擊單元格彈窗矢沿,其他的都不重要滥搭,彈窗的end非常重要,在這個(gè)回調(diào)中你需要做這些事情:
?a. 取到我們存在localStorage中的數(shù)據(jù)
var chooseUser = layui.data(setter.tableName).chooseValue;
?b. 調(diào)用組件的updateParentTableRow()
方法捣鲸,并傳入表格行對(duì)象瑟匆、行this、選中數(shù)據(jù)的字段與表格字段的對(duì)應(yīng)關(guān)系:
dt.updateParentTableRow(obj,this,chooseUser,{
chooseField:"username", // 選中對(duì)象的字段
tableField:"username", // 對(duì)應(yīng)表格的字段
});
?c. 用完即毀摄狱。 銷毀存在localStorage中的數(shù)據(jù)脓诡! 這一步你必須要做,不然后果自負(fù)....
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 - 表格行對(duì)象
* param2- this
* param3 - 選中的數(shù)據(jù)
* param4 - 其他參數(shù)
*/
dt.updateParentTableRow(obj,this,chooseUser,{
chooseField:"username", // 選中對(duì)象的字段
tableField:"username", // 對(duì)應(yīng)表格的字段
});
layui.data(setter.tableName, {
key: 'chooseValue'
,remove: true
});
}
})
}
});
?當(dāng)然祝谚,你也可以將這個(gè)功能用在普通input的選擇上,使用思路相同酣衷,將數(shù)據(jù)先存到localStorage中交惯,在頁面銷毀的時(shí)候?yàn)檩斎肟驈?fù)制。 只不過就不用調(diào)用updateParentTableRow()
方法了穿仪,用完即毀就行……
2. 表格集成select組件:
?話不多說席爽,先看效果圖
? 這個(gè)組件,使用起來代碼比較多啊片,也比較復(fù)雜只锻。 但是相對(duì)于js中封裝的那些DOM操作,大家還是忍忍吧~
? a. 為表格需要使用select的字段添加templet
和event
紫谷。注意field
應(yīng)為select的顯示字段齐饮,即<option></option>
之間的文字捐寥。
? 同時(shí)添加一個(gè)空字段,表示select的value
字段祖驱。
? 也就是說握恳,數(shù)據(jù)表格加載的JSON數(shù)據(jù)中,必須包含value和顯示的文字
/* 數(shù)據(jù)表格的JSON數(shù)據(jù)捺僻,已省略其他字段乡洼。
* {
* 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為后臺(tái)數(shù)據(jù)中,select顯示的文字匕坯,非value
{{d.sextext}}<i class="layui-icon table-select-icon"></i>
</script>
? c. 為綁定的event
添加事件束昵,使用Ajax請(qǐng)假select的數(shù)據(jù),并調(diào)用組件的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的數(shù)據(jù)
value:"id", // select數(shù)據(jù)中表示value的字段
text:"value", // select中表示顯示的字段
valueField:"sexvalue" , // 數(shù)據(jù)表格中表示value的字段
textField:"sextext", // 數(shù)據(jù)表格中表示顯示的字段
});
}
})
? 后臺(tái)返回的數(shù)據(jù)sexData
的格式:
[
{
"id": 1,
"value": "女"
}
。泞歉。逼侦。
]
? d. 由于select會(huì)被遮擋,所以需要把下面這段CSS放入到頁面中腰耙。后續(xù)可能考慮放到通用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日期組件:
? 老規(guī)矩,效果圖鎮(zhèn)樓:
? 這個(gè)效果的實(shí)現(xiàn)思路挺庞,與集成select的思路類似晰赞,下面一步一步的來分析:
? a. 頁面中導(dǎo)入laydate組件,這個(gè)大家都懂:
layui.config({
base: '../../common/' //靜態(tài)資源所在路徑
}).extend({
index: 'lib/index', //主入口模塊
dataTable:"../lib/extend/dataTable"
}).use(["dataTable",'laydate'],function(){
var dt = layui.dataTable,
form = layui.form,
laydate = layui.laydate;
})
? b. 為表格需要使用select的字段添加templet
和event
选侨。
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回調(diào)函數(shù)中的內(nèi)容非常重要哦~):
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);
}
});
}
});
? 截止現(xiàn)在掖鱼,laydate組件也可以老老實(shí)實(shí)的展示在數(shù)據(jù)表格中啦~
七、最后說點(diǎn)啥
? 1援制、 組件是針對(duì)我們公司需求進(jìn)行設(shè)計(jì)的戏挡,可能其他人用起來不一定那么順手,大家可以取其精華晨仑、去其糟粕褐墅。
? 2、 時(shí)間能力有限洪己,部分功能不算太完善妥凳,后續(xù)還會(huì)慢悠悠的進(jìn)行完善,大家也不用太期待了~
? 3答捕、 愿世界和平......