2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > layui table处理奇葩后台数据实现复杂表头固定列功能

layui table处理奇葩后台数据实现复杂表头固定列功能

时间:2021-04-06 13:41:22

相关推荐

layui table处理奇葩后台数据实现复杂表头固定列功能

公司要求在手机上实现复杂表头表格,可以第一列固定,其他滑动的table功能,我看了下,在elementui中有这个功能,但是它的多级表头需要实现上下级的对象关系,而后台给我们返回的数据都是用colspan,rowspan渲染表头的,所以这个插件无法使用。

然后退而求其实,使用比较简单的layui中的table,因为它的ui做的还可以。

layui table 的复杂多级表头是支持表头使用rowspan和colspan 的。

文档:/doc/modules/table.html

但是要实现固定列功能,就必须让表头的filed关键字绑定数据的key,有些像jq table和bootstrap table,都是初始化表头,设置关键字,然后自动配上数据渲染table。

我是要实现这样的表格(只是模板,每个表头配置的都不同),复杂表头,第一列固定:

奇葩的是,后台在设计程序的时候,表头和数据是分开的,他的意思就是表头单独渲染,然后数据部分根据顺序写table就行了:

分别为: 数据,表头,表描述

数据就是普通的键值对数据;

表头就是按tr给的对象,每一行的内容文字,和对应的calspan,rowspan

表描述就是告你表的标题,和表格的数据顺序是按colModel的数据展示的

虽然他安排的明明白白,按表头和表body分别渲染确实无问题,但是我要使用layui table实现复杂表头和列固定,表头就必须和数据key绑定,而表头给出的乱七八糟的colspan,rowspan以后的,处理起来很麻烦,要把它屡清楚很费脑细胞。

开始靠前端处理数据:

首先要搞清楚,colspan为1的一般都是需要绑定数据展示的,但数据中colspan为1的多行表头顺序并不能确定,所以无法按顺序为他们绑定key,此时,我想到了通过占位符,让每一行的总对象数都相同

先看看原始数据:

//循环表头数据for(var i=0;i<headers.length;i++){var array=[];var header1=headers[i].colomnVos;//console.log(header1)//循环每列表头中的数据for(var j=0;j<header1.length;j++){var obj={}//此时只是构造对象的雏形,还不能绑定fieldobj={title:header1[j].name,rowspan:header1[j].rowspan,colspan:header1[j].colspan,style:{height:'auto'},align:'center',fake:false}array.push(obj)//关键:如果colspan不为1的话,就在它后面加几个占位对象if(header1[j].colspan!=1){var thisColspan=header1[j].colspan;for(var k=1;k<thisColspan;k++){obj={fake:true}array.push(obj)}}}tableCols.push(array);}//打印这个阶段的样子var fuzhi=JSON.stringify(tableCols);var fuzhi1=JSON.parse(fuzhi)console.log(fuzhi1)

再看看处理后的数据:

此时发现,已经插入了占位对象了,但是每一行的对象总数还是不一样,这是因为有的表头rowspan并以一定为1

比如地市这一列直接跨了3行,那下面的即使把rowspan全部展开添加占位对象也会少一个对象,所以除了rowspan,还需要考虑colspan的问题。

现在可以确定的第一行的表头不管怎样,不需要考虑rowspan,将colspan全部展开必定代表表格的最大列数,那么我可以以最大列数开始纵向循环,如果上一级表头rowspan不是1,则在下面rowspan级表头这个位置也插入一个占位对象,描述很难,直接上代码:

//从第一个开始纵向循环,maxHeaderLength是表数据中获取的最大列数for(var i=0;i<maxHeaderLength;i++){for(var j=0;j<tableCols.length;j++){var header1=tableCols[j];if(!!header1[i]){//此时,可以判断colspan为1的都有自己的数据,为其绑定fieldif(header1[i].colspan==1){if(i==0){header1[i].field=pageConfVo[i];header1[i].fixed='left'}else{header1[i].field=pageConfVo[i];}}//关键:如果rowspan不为1,就在下面的表头中分别插入一个占位对象if(header1[i].rowspan>1){for(var k=0;k<header1[i].rowspan-1;k++){tableCols[j+k+1].splice(i, 0, {fake:true});}}}}}var aaa=JSON.stringify(tableCols)console.log(JSON.parse(aaa))

这时,再看下数据:

这就大功告成啦,可以保证每一行表头中,colspan为1所对应的列都是唯一的,所以就可以直接给他们赋值field的了。

赋值好后当然要把没用的占位对象删掉:

//最后for(var i=0;i<tableCols.length;i++){var header2=tableCols[i];for(var j=0;j<header2.length;j++){if(header2[j].fake){header2.splice(j--,1);}}}console.log(tableCols)

最后的结果:

又回到了原始状态,但是不同的是该绑定数据key的列都绑定上了。

很不容易呀,下来粘下完整代码:

<!DOCTYPE html><html><head><meta charset="utf-8"><title>Layui</title><meta name="renderer" content="webkit"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"><link rel="stylesheet" href="../lib/layui/css/layui.css" media="all"><script src="../js/ipAddress.js" type="text/javascript" charset="utf-8"></script><!-- 注意:如果你直接复制所有代码到本地,上述css路径需要改成你本地的 --><style type="text/css">#title{font-size:16px;font-weight:bold;text-align: center;line-height: 30px;padding:10px}.layui-table-header{}.shuoming{line-height: 26px;background: #E8F4FF;border-bottom:1px solid #ddd;padding:10px;font-size:13px}.shuoming .s1{color:white;background:#439FFF;display: inline-block;padding:0 10px;border-radius: 10px;margin-right:10px;}thead .layui-table-cell{height:40px !important;white-space:normal;padding:0;}.span{}.tip{line-height:60px;color:#aaa;font-size:16px;text-align: center;display: none;}</style></head><body><div class="shuoming"><span class="s1">指标说明</span><span>指标口径请参阅市场部崔炎下发的指标说明,对指标有疑问或建议,请联系市场部崔炎或业支部陈哲。</span></div><div id="title"></div><table id="demo" lay-filter="test"></table><div class="tip">暂无数据</div><script src="../js/jquery-3.3.1.min.js" type="text/javascript" charset="utf-8"></script><script src="../lib/layui/layui.js" charset="utf-8"></script><!-- 注意:如果你直接复制所有代码到本地,上述 JS 路径需要改成你本地的 --><script>var tablevar tableCols=[];var height=0;var qryDate="";var sign="";var areaCode="";var tableCode="";var type="";//表的裂数var maxHeaderLength=0;//表头文字长度var maxTextLength=0;//var url=baseUrl+'tongbao/getTongBaoDataJson.action';var url='../static/data.json';$(function(){var args=getQueryStringArgs();qryDate=args.qryDate;sign=args.sign;areaCode=args.areaCode;tableCode=args.tableCode;type=args.type;$.ajax({type: 'get',url: url,data:{qryDate:qryDate,sign:sign,areaCode:areaCode,tableCode:tableCode,type:type},dataType: 'json',async:false,success: function(res){console.log(res)if(res.data.length==0){$(".tip").show();}var data =res.data[0];var headers=data.headThVos;var pageConfVo= data.pageConfVo.colModels;maxHeaderLength=parseInt(data.pageConfVo.colCount);$("#title").html(data.pageConfVo.cTitle)//循环表头数据for(var i=0;i<headers.length;i++){var array=[];var header1=headers[i].colomnVos;//console.log(header1)//循环每列表头中的数据for(var j=0;j<header1.length;j++){var obj={}if(header1[j].name.length>maxTextLength){maxTextLength=header1[j].name.length;}//此时只是构造对象的雏形,还不能绑定fieldobj={title:header1[j].name,rowspan:header1[j].rowspan,colspan:header1[j].colspan,style:{height:'auto'},align:'center',fake:false}array.push(obj)//关键:如果colspan不为1的话,就在它后面加几个占位对象if(header1[j].colspan!=1){var thisColspan=header1[j].colspan;for(var k=1;k<thisColspan;k++){obj={fake:true}array.push(obj)}}}tableCols.push(array);}//打印这个阶段的样子var fuzhi=JSON.stringify(tableCols);var fuzhi1=JSON.parse(fuzhi)console.log(fuzhi1)//从第一个开始纵向循环,maxHeaderLength是表数据中获取的最大列数for(var i=0;i<maxHeaderLength;i++){for(var j=0;j<tableCols.length;j++){var header1=tableCols[j];if(!!header1[i]){//此时,可以判断colspan为1的都有自己的数据,为其绑定fieldif(header1[i].colspan==1){if(i==0){header1[i].field=pageConfVo[i];header1[i].fixed='left'}else{header1[i].field=pageConfVo[i];}}//关键:如果rowspan不为1,就在下面的表头中分别插入一个占位对象if(header1[i].rowspan>1){for(var k=0;k<header1[i].rowspan-1;k++){tableCols[j+k+1].splice(i, 0, {fake:true});}}}}}var aaa=JSON.stringify(tableCols)console.log(JSON.parse(aaa))//最后for(var i=0;i<tableCols.length;i++){var header2=tableCols[i];for(var j=0;j<header2.length;j++){if(header2[j].fake){header2.splice(j--,1);}}}console.log(tableCols)},error:function(data) {//console.log(data.msg);},});})layui.use('table', function(){table = layui.table;//console.log(height)//第一个实例table.render({id:"itest",where: {qryDate:qryDate,sign:sign,areaCode:areaCode,tableCode:tableCode,type:type},elem: '#demo',size: 'sm',//,height: heighturl: url ,//数据接口parseData: function(res){ //res 即为原始返回的数据//console.log(res)var data=res.data[0];var count=data.contents.length;var data1=data.contents;//console.log(height)return {"code": res.code, //解析接口状态"msg": res.msg, //解析提示文本"count": count, //解析数据长度"data": data1 //解析数据列表};},page: false, //开启分页cols: tableCols,cellMinWidth:100,done: function(res, curr, count){//如果是异步请求数据方式,res即为你接口返回的信息。//如果是直接赋值的方式,res即为:{data: [], count: 99} data为当前页数据、count为数据总长度console.log(res);//得到当前页码console.log(curr); //得到数据总量console.log(count);console.log(maxTextLength)if(maxTextLength>16){$("thead .layui-table-cell").css("fontSize",'10px')}},error:function(){}});});/* window.onresize = () => {return (() => {if(document.documentElement.clientHeight>document.documentElement.clientWidth){that.titleHeight=50;}else{that.titleHeight=40;}window.screenHeight = document.documentElement.clientHeightheight = window.screenHeight-250;//console.log(window.screenHeight)//console.log(height)//table.resize('itest');table.reload('itest', {}, false)})() }*/function getQueryStringArgs() {//取得查询字符串并去掉开头的问号var qs = (location.search.length > 0 ? location.search.substring(1) : ""),//保存数据的对象args = {},//取得每一项items = qs.length ? qs.split("&") : [],item = null,name = null,value = null,//在 for 循环中使用i = 0,len = items.length;//逐个将每一项添加到 args 对象中for(i = 0; i < len; i++) {item = items[i].split("=");name = decodeURIComponent(item[0]);value = decodeURIComponent(item[1]);if(name.length) {args[name] = value;}}return args;}</script></body></html>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。