您好,登錄后才能下訂單哦!
如何使用Bootstrap-table實現動態合并相同行?相信很多新手小白還沒學會這個技能,通過這篇文章的總結,希望你能學會學會這個技能。以下資料是實現的步驟。
有時候表格的需求就是奇奇怪怪的,最近要做的表格需要實現當緊挨著的記錄的某一列的行元素內容相同,就將其合并。要是不是相同的就不合并。如果表格數據的順序不需要被改變,這個樣子是可以很簡單就完成的(只需要計算出所有相同元素出現的次數即可,不需要考慮是否緊挨著),但是當可以改變排序的時候,這個時候就有點兒問題了。可能表述的有點兒不明白,下面具體看圖描述問題吧。
具體的需求,假設現在有三條記錄,后臺按照順序x排好后傳遞給前臺頁面進行顯示。
頁面拿到數據后將相同行進行合并后可以得到右邊圖的效果,但是如果現在在頁面選擇了一個排序按鈕后,現在的排序被打亂了,又該怎樣去實現合并?
這里值得思考的是,后面每個列的最多的合并次數是基于前一個列的合并的次數來的,所以這里是個切入點,記錄下第一列所有緊挨著的相同行內容出現的次數,然后遍歷,去計算第二列所有緊挨著的相同行內容出現的次數,然后遍歷,去計算第三列所有緊挨著的相同行內容出現的次數,依次下去。。。。。將每一列緊挨著的相同元素的次數都記錄下來,然后拿到了這些次數,最后使用bootstrapTable自帶的mergeCells方法去合并即可。越來越覺得數據結構以及算法重要性,最近太多寫的程序都涉及到一些邏輯的算法,還是上學時要把這兩個學好呀~~~~~~~
下面看看代碼:
<%-- 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(); //網站的訪問跟路徑 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"> <%--設置IE渲染方式(文檔)默認為最高(這部分可以選擇添加也可以不添加)--%> <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/> <title>實現表格同名合并</title> <!--圖標樣式--> <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,//是否使用緩存,默認為true,所以一般情況下需要設置一下這個屬性(*) pagination: true,//是否顯示分頁(*) sortable: false,//是否啟用排序 sortOrder: "asc",//排序方式 //queryParams: queryParams,//傳遞參數(*) sidePagination: "server",//分頁方式:client客戶端分頁,server服務端分頁(*) pageNumber: 1,//初始化加載第一頁,默認第一頁 pageSize: 10,//每頁的記錄行數(*) pageList: [10, 25, 50, 100],//可供選擇的每頁的行數(*) // search: true,//是否顯示表格搜索,此搜索是客戶端搜索,不會進服務端 contentType: "application/x-www-form-urlencoded", strictSearch: true, showColumns: true,//是否顯示內容列下拉框 showRefresh: true,//是否顯示刷新按鈕 minimumCountColumns: 2,//最少允許的列數 clickToSelect: true,//是否啟用點擊選中行 //這里如果要固定表頭的話 就把height開啟 //height: 700,//行高,如果沒有設置height屬性,表格自動根據記錄條數覺得表格高度 width:'50%', uniqueId: "id",//每一行的唯一標識,一般為主鍵列 showToggle: true,//是否顯示詳細視圖和列表視圖的切換按鈕 cardView: false,//是否顯示詳細視圖 detailView: false,//是否顯示父子表 onLoadSuccess: function (data) { //數據加載成功后 進行合并 這里我只是同名合并projName subProj phase 如果需要合并更多的字段 仿照添加對應的代碼就可以了 mergeTable(data,"table"); }, columns: [ { field: 'projName', title: 'projName', }, { field: 'subProj', title: 'subProj' }, { field: 'phase', title: 'phase' }, { field: 'workItem', title: 'workItem', }, { field: 'completion', title: 'completion', }, ], }); }); //全局變量 ***如果每次只是發送ajax請求對table進行局部更新,則每次要合并前前都應該清空這三個變量 不然全局變量會一值追加結果 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的次數進行分割 //去掉末尾的逗號 有時候也可以不用去掉 還是去掉了我這里 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(","); //根據次數進行表格合并 //合并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; } } //排序后緊挨在一起 進行同名合并 /** * 對于表格合并,首先要進行排序,即將同名的屬性的記錄排序緊挨在一起,這樣才能最好的顯示出合并想要的效果。 * 因為此方法是拿第一個數據與后面的數據依次比較, * 例如,第一條記錄的projName與第二條記錄的projName來進行比較,兩者相同,則繼續第一條記錄的projName與第三條記錄的projName來進行比較, * 當不相同時,記錄下此projName對應的值出現的次數,然后再開始從第三條記錄的projName與第四條記錄的projName來進行比較,依次循環下去,記 * 錄下相同內容的值出現的次數,到時候,再根據這些次數來進行合并 * * 此方法主要是先拿到每個同名屬性的值的相等次數,把次數利用全局變量存下來 * * @param datas --表格數據,一般為表格的rows數據 * @param startIndex --開始下標 * @param size --從開始下標起,到size結束,遍歷合并多少個 * @param fieldName --計算算哪個列 * @param target --table表格對象 */ function mergeCells(datas,startIndex,size,fieldName,target) { //console.log("startIndex:"+startIndex+"size:"+size+"---合并列:"+fieldName) //聲明一個數組計算相同屬性值在data對象出現的次數和 //這里不能使用map,因為如果涉及到排序后,相同的屬性并不是緊挨在一起,那么后面的次數會覆蓋前面的次數,故這里用數組 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; //如果是最后一個元素 把最后一個元素的次數也裝進去 if(i == size-1-1){ sortArr.push(1); } }else{ sortArr.push(j - i); //如果j是最后一個元素 把最后一個元素的次數裝進去 if(j == size - 1){ sortArr.push(1); } } break; }else { //相同屬性值相同 直到最后一次的時候才會裝 否則在他們的值不同時再裝進去 if (j == size - 1) { sortArr.push(j - i+1); //這里的賦值感覺有點多余 算了現就這個樣子吧 不影響功能 i = j; } } } } //遍歷數組,將值裝追加到對應的字符串后面 for(var prop in sortArr){ /*這里在ie8上運行的時候 出現坑 最好遍歷數組不要用for in 這里我用了就懶得換了 下面加上如果prop是indexOf就停止 就解決了ie8出現的問題*/ 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("進入projName--此時開始index-"+startIndex+"--結束index--"+(startIndex+sortArr[prop])*1); startIndex = 0; //subProjName每次進去的startIndex為前面次數的和 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{ //當projName的次數為1就不進入循環 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("進入subProj--此時開始index-"+startIndex+"--結束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自帶的合并單元格的方法,也是很好用的,也是基于此基礎上才能完成。
$('#table').bootstrapTable('mergeCells',{index:index, field:"projName", colspan: 1, rowspan: count});
上述就是小編為大家分享的使用Bootstrap-table實現動態合并相同行的方法了,如果您也有類似的疑惑,不妨參照上述方法進行嘗試。如果想了解更多相關內容,請關注億速云行業資訊。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。