您好,登錄后才能下訂單哦!
如何使用Bootstrap-table實現(xiàn)動態(tài)合并相同行?相信很多新手小白還沒學(xué)會這個技能,通過這篇文章的總結(jié),希望你能學(xué)會學(xué)會這個技能。以下資料是實現(xiàn)的步驟。
有時候表格的需求就是奇奇怪怪的,最近要做的表格需要實現(xiàn)當(dāng)緊挨著的記錄的某一列的行元素內(nèi)容相同,就將其合并。要是不是相同的就不合并。如果表格數(shù)據(jù)的順序不需要被改變,這個樣子是可以很簡單就完成的(只需要計算出所有相同元素出現(xiàn)的次數(shù)即可,不需要考慮是否緊挨著),但是當(dāng)可以改變排序的時候,這個時候就有點兒問題了??赡鼙硎龅挠悬c兒不明白,下面具體看圖描述問題吧。
具體的需求,假設(shè)現(xiàn)在有三條記錄,后臺按照順序x排好后傳遞給前臺頁面進(jìn)行顯示。
頁面拿到數(shù)據(jù)后將相同行進(jìn)行合并后可以得到右邊圖的效果,但是如果現(xiàn)在在頁面選擇了一個排序按鈕后,現(xiàn)在的排序被打亂了,又該怎樣去實現(xiàn)合并?
這里值得思考的是,后面每個列的最多的合并次數(shù)是基于前一個列的合并的次數(shù)來的,所以這里是個切入點,記錄下第一列所有緊挨著的相同行內(nèi)容出現(xiàn)的次數(shù),然后遍歷,去計算第二列所有緊挨著的相同行內(nèi)容出現(xiàn)的次數(shù),然后遍歷,去計算第三列所有緊挨著的相同行內(nèi)容出現(xiàn)的次數(shù),依次下去。。。。。將每一列緊挨著的相同元素的次數(shù)都記錄下來,然后拿到了這些次數(shù),最后使用bootstrapTable自帶的mergeCells方法去合并即可。越來越覺得數(shù)據(jù)結(jié)構(gòu)以及算法重要性,最近太多寫的程序都涉及到一些邏輯的算法,還是上學(xué)時要把這兩個學(xué)好呀~~~~~~~
下面看看代碼:
<%-- Created by IntelliJ IDEA. User: Administrator Date: 2018/6/20 Time: 14:21 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <% String scheme = request.getScheme(); String serverName = request.getServerName(); String contextPath = request.getContextPath(); int port = request.getServerPort(); //網(wǎng)站的訪問跟路徑 String baseURL = scheme + "://" + serverName + ":" + port + contextPath; request.setAttribute("baseURL", baseURL); %> <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1"> <%--設(shè)置IE渲染方式(文檔)默認(rèn)為最高(這部分可以選擇添加也可以不添加)--%> <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/> <title>實現(xiàn)表格同名合并</title> <!--圖標(biāo)樣式--> <link rel="stylesheet" type="text/css" href="${baseURL}/Bootstrap/bootstrap/css/bootstrap.min.css" /> <link href="${baseURL}/Bootstrap/bootstrap-table/bootstrap-table.css" rel="stylesheet" /> <script src="${baseURL}/Bootstrap/bootstrap/assets/js/jquery-1.10.2.min.js"></script> <script src="${baseURL}/Bootstrap/bootstrap/assets/js/bootstrap.min.js"></script> <script src="${baseURL}/Bootstrap/bootstrap-table/bootstrap-table.js"></script> <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> <!--[if lt IE 9]> <script src="${baseURL}/Bootstrap/bootstrap/assets/js/html5shiv.js"></script> <script src="${baseURL}/Bootstrap/bootstrap/assets/js/respond.min.js"></script> <![endif]--> <style type="text/css"> </style> </head> <body> <div> <table id="table"></table> </div> </body> <script type="text/javascript"> $(function () { //初始化Table $('#table').bootstrapTable({ url: '${baseURL}/Views/cc.json',//請求后臺的URL(*) 這里我用的是一個json文件 method: 'get',//請求方式(*) toolbar: '#toolbar',//工具按鈕用哪個容器 striped: true,//是否顯示行間隔色 cache: false,//是否使用緩存,默認(rèn)為true,所以一般情況下需要設(shè)置一下這個屬性(*) pagination: true,//是否顯示分頁(*) sortable: false,//是否啟用排序 sortOrder: "asc",//排序方式 //queryParams: queryParams,//傳遞參數(shù)(*) sidePagination: "server",//分頁方式:client客戶端分頁,server服務(wù)端分頁(*) pageNumber: 1,//初始化加載第一頁,默認(rèn)第一頁 pageSize: 10,//每頁的記錄行數(shù)(*) pageList: [10, 25, 50, 100],//可供選擇的每頁的行數(shù)(*) // search: true,//是否顯示表格搜索,此搜索是客戶端搜索,不會進(jìn)服務(wù)端 contentType: "application/x-www-form-urlencoded", strictSearch: true, showColumns: true,//是否顯示內(nèi)容列下拉框 showRefresh: true,//是否顯示刷新按鈕 minimumCountColumns: 2,//最少允許的列數(shù) clickToSelect: true,//是否啟用點擊選中行 //這里如果要固定表頭的話 就把height開啟 //height: 700,//行高,如果沒有設(shè)置height屬性,表格自動根據(jù)記錄條數(shù)覺得表格高度 width:'50%', uniqueId: "id",//每一行的唯一標(biāo)識,一般為主鍵列 showToggle: true,//是否顯示詳細(xì)視圖和列表視圖的切換按鈕 cardView: false,//是否顯示詳細(xì)視圖 detailView: false,//是否顯示父子表 onLoadSuccess: function (data) { //數(shù)據(jù)加載成功后 進(jìn)行合并 這里我只是同名合并projName subProj phase 如果需要合并更多的字段 仿照添加對應(yīng)的代碼就可以了 mergeTable(data,"table"); }, columns: [ { field: 'projName', title: 'projName', }, { field: 'subProj', title: 'subProj' }, { field: 'phase', title: 'phase' }, { field: 'workItem', title: 'workItem', }, { field: 'completion', title: 'completion', }, ], }); }); //全局變量 ***如果每次只是發(fā)送ajax請求對table進(jìn)行局部更新,則每次要合并前前都應(yīng)該清空這三個變量 不然全局變量會一值追加結(jié)果 var projNameCount=""; var subProjNameCount=""; var phaseCount=""; //合并表格 function mergeTable(data,tableId){ //每次合并表格前 都要將全局變量清空 projNameCount=""; subProjNameCount=""; phaseCount=""; mergeCells(data.rows,0,data.rows.length,"projName",$('#'+tableId)); //對projName,subProjName,phase的次數(shù)進(jìn)行分割 //去掉末尾的逗號 有時候也可以不用去掉 還是去掉了我這里 projNameCount = projNameCount.substring(0,projNameCount.length-1); subProjNameCount = subProjNameCount.substring(0,subProjNameCount.length-1); phaseCount = phaseCount.substring(0,phaseCount.length-1); //console.log(projNameCount+"+"+subProjNameCount+"+"+phaseCount); var strArr1 = projNameCount.split(","); var strArr2 = subProjNameCount.split(","); var strArr3 = phaseCount.split(","); //根據(jù)次數(shù)進(jìn)行表格合并 //合并projName var index = 0; for(var i=0;i<strArr1.length;i++){ var count = strArr1[i] * 1; $('#'+tableId).bootstrapTable('mergeCells',{index:index, field:"projName", colspan: 1, rowspan: count}); index += count; } //合并subProjName var index = 0; for(var i=0;i<strArr2.length;i++){ var count = strArr2[i] * 1; $('#'+tableId).bootstrapTable('mergeCells',{index:index, field:"subProjName", colspan: 1, rowspan: count}); index += count; } //合并phaseName var index = 0; for(var i=0;i<strArr3.length;i++){ var count = strArr3[i] * 1; $('#'+tableId).bootstrapTable('mergeCells',{index:index, field:"phaseName", colspan: 1, rowspan: count}); index += count; } } //排序后緊挨在一起 進(jìn)行同名合并 /** * 對于表格合并,首先要進(jìn)行排序,即將同名的屬性的記錄排序緊挨在一起,這樣才能最好的顯示出合并想要的效果。 * 因為此方法是拿第一個數(shù)據(jù)與后面的數(shù)據(jù)依次比較, * 例如,第一條記錄的projName與第二條記錄的projName來進(jìn)行比較,兩者相同,則繼續(xù)第一條記錄的projName與第三條記錄的projName來進(jìn)行比較, * 當(dāng)不相同時,記錄下此projName對應(yīng)的值出現(xiàn)的次數(shù),然后再開始從第三條記錄的projName與第四條記錄的projName來進(jìn)行比較,依次循環(huán)下去,記 * 錄下相同內(nèi)容的值出現(xiàn)的次數(shù),到時候,再根據(jù)這些次數(shù)來進(jìn)行合并 * * 此方法主要是先拿到每個同名屬性的值的相等次數(shù),把次數(shù)利用全局變量存下來 * * @param datas --表格數(shù)據(jù),一般為表格的rows數(shù)據(jù) * @param startIndex --開始下標(biāo) * @param size --從開始下標(biāo)起,到size結(jié)束,遍歷合并多少個 * @param fieldName --計算算哪個列 * @param target --table表格對象 */ function mergeCells(datas,startIndex,size,fieldName,target) { //console.log("startIndex:"+startIndex+"size:"+size+"---合并列:"+fieldName) //聲明一個數(shù)組計算相同屬性值在data對象出現(xiàn)的次數(shù)和 //這里不能使用map,因為如果涉及到排序后,相同的屬性并不是緊挨在一起,那么后面的次數(shù)會覆蓋前面的次數(shù),故這里用數(shù)組 var sortArr = new Array(); for (var i = startIndex; i < size ; i++) { for (var j = i + 1; j < size; j++) { if (datas[i][fieldName] != datas[j][fieldName]){ //相同屬性值不同 if (j - i > 1) { sortArr.push(j - i); i = j - 1; //如果是最后一個元素 把最后一個元素的次數(shù)也裝進(jìn)去 if(i == size-1-1){ sortArr.push(1); } }else{ sortArr.push(j - i); //如果j是最后一個元素 把最后一個元素的次數(shù)裝進(jìn)去 if(j == size - 1){ sortArr.push(1); } } break; }else { //相同屬性值相同 直到最后一次的時候才會裝 否則在他們的值不同時再裝進(jìn)去 if (j == size - 1) { sortArr.push(j - i+1); //這里的賦值感覺有點多余 算了現(xiàn)就這個樣子吧 不影響功能 i = j; } } } } //遍歷數(shù)組,將值裝追加到對應(yīng)的字符串后面 for(var prop in sortArr){ /*這里在ie8上運(yùn)行的時候 出現(xiàn)坑 最好遍歷數(shù)組不要用for in 這里我用了就懶得換了 下面加上如果prop是indexOf就停止 就解決了ie8出現(xiàn)的問題*/ if(prop == "indexOf"){ continue; } if(fieldName == "projName"){ var count = sortArr[prop] * 1; projNameCount += count +","; } if(fieldName == "subProjName"){ var count = sortArr[prop] * 1; subProjNameCount += count +","; } if(fieldName == "phaseName"){ var count = sortArr[prop] * 1; phaseCount += count +","; } } for(var prop in sortArr){ if(prop == "indexOf"){ continue; } if(fieldName == "projName"){ //console.log("進(jìn)入projName--此時開始index-"+startIndex+"--結(jié)束index--"+(startIndex+sortArr[prop])*1); startIndex = 0; //subProjName每次進(jìn)去的startIndex為前面次數(shù)的和 if(subProjNameCount.length>0){ //console.log("subProjNameCount-"+subProjNameCount); var temp = subProjNameCount.substring(0,subProjNameCount.length-1); var strArr1 = temp.split(","); for(var i=0;i<strArr1.length;i++){ var count = strArr1[i] * 1; startIndex += count; } } if(sortArr[prop] >1){ mergeCells(datas,startIndex,startIndex+sortArr[prop],"subProjName",target); }else{ //當(dāng)projName的次數(shù)為1就不進(jìn)入循環(huán) subProjNameCount +=1+","; phaseCount +=1+","; } } if(fieldName == "subProjName"){ startIndex = 0; if(phaseCount.length>0){ //console.log("phaseCount-"+phaseCount); var temp = phaseCount.substring(0,phaseCount.length-1); //phaseCount = phaseCount + ","; var strArr1 = temp.split(","); for(var i=0;i<strArr1.length;i++){ var count = strArr1[i] * 1; startIndex += count; } } if(sortArr[prop] >1){ //console.log("進(jìn)入subProj--此時開始index-"+startIndex+"--結(jié)束index--"+(startIndex+sortArr[prop])*1); mergeCells(datas,startIndex,startIndex+sortArr[prop],"phaseName",target) }else{ phaseCount +=1+","; } } } } </script> </html>
上面就是完整的代碼了,效果圖如下:(此代碼只需要計算projName,subProj,phase的合并就可以了,后面workitem不需要再合并了,因為后臺查詢的就是每一條workitem記錄)
其中對于bootstrap-table自帶的合并單元格的方法,也是很好用的,也是基于此基礎(chǔ)上才能完成。
$('#table').bootstrapTable('mergeCells',{index:index, field:"projName", colspan: 1, rowspan: count});
上述就是小編為大家分享的使用Bootstrap-table實現(xiàn)動態(tài)合并相同行的方法了,如果您也有類似的疑惑,不妨參照上述方法進(jìn)行嘗試。如果想了解更多相關(guān)內(nèi)容,請關(guān)注億速云行業(yè)資訊。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。