前言css
上次寫了一個可拖動列表的插件,但除了這個特色沒什麼優勢了,接下寫的是咱們經常使用的Bootstrap-table表格插件html
正文vue
官網:https://bootstrap-table.com/jquery
有兩個翻譯API的網址:ajax
https://blog.csdn.net/S_clifftop/article/details/77937356?locationNum=3&fps=1json
https://blog.csdn.net/mrczr/article/details/64441265bootstrap
在使用時須要引入以下幾個文件:數組
bootstrap.min.css緩存
bootstrap-table.css服務器
jquery.js
bootstrap.js
bootstrap-table.js
bootstrap-table-zh-CN.js(中文插件)
客戶端分頁例以下:
// 首先銷燬表格 $('#fwfx_tb').bootstrapTable('destroy'); // 初始化表格,動態從服務器加載數據 $('#fwfx_tb').bootstrapTable({ pagination: true, //啓動分頁 striped: true, //設置爲 true 會有隔行變色效果 cache: false, //是否使用緩存,默認爲true,因此通常狀況下須要設置一下這個屬性(*) pageSize: 20,//初始頁記錄數 sortable: true, //排序 pageList: [10,20], //記錄數可選列表 smartDisplay: false, //程序自動判斷顯示分頁信息 columns: [{ title: '序號', align: 'center', halign: 'center', formatter: function (value, row, index) { return index + 1; } }, { field: 'name', title: '服務名', align: 'center', sortable:true //排序 }, { field: 'sum', title: '金額', align: 'center' }, { field: 'PV', title: '訪問量', align: 'center' } data: tableData });
服務器端分頁例以下:
$('#user_content_tab').bootstrapTable('destroy'); // 初始化表格,動態從服務器加載數據 $('#user_content_tab').bootstrapTable({ url: "admin/query", method: 'post', sidePagination: 'server', //表示服務端請求 queryParams:logUl,//請求服務器時所傳的參數 ajaxOptions:{ //提交ajax請求時的附加參數 headers: { 'token': '94564375541867846'//這裏傳的token是根據你的先後臺交互狀況 } }, toolbar : '#toolbar', // 工具按鈕用哪一個容器 pagination: true, //默認爲false,表格的底部工具欄不會顯示分頁條 queryParamsType:'',//查詢參數組織方式,必須設置爲空,不然沒有頁碼params.pageNumber striped: true, //設置爲 true 會有隔行變色效果 pageSize: 20, //每頁顯示行數 pageList:[10,20,50], maintainSelected: true, //在點擊分頁按鈕或搜索按鈕時,將記住checkbox的選擇項 smartDisplay: false, //程序自動判斷顯示分頁信息 clickToSelect: true, //是否啓用點擊選中行 toolbarAlign: 'right', //指定 toolbar 水平方向的位置 uniqueId: 'userId', //爲每一行指定惟一標識符 idField: 'userId', //指定主鍵列 paginationDetailHAlign:'right',//指定分頁詳細信息在水平方向的位置 columns: [{ title: '序號', align: 'center', halign: 'center', formatter: function (value, row, index) { var options = $table.bootstrapTable('getOptions'); return options.pageSize * (options.pageNumber - 1) + index + 1; } },{ field: 'userId', title: '用戶ID', align: 'center', }, { field: 'username', title: '用戶名稱', align: 'center' }, { field: 'roleName', title: '角色', align: 'center' }, { field: 'createTime', title: '建立時間', align: 'center', formatter : function(value, row, index) { return fmtDate(value) } }, { field: 'status', title: '帳戶狀態', align: 'center' }, { field: 'userId', title: '操做', align: 'center', width: 350, formatter: operateFormatter//在這裏個人目的是添加按鈕 }], formatNoMatches: function(){ return "沒有相關的匹配結果"; }, formatLoadingMessage: function(){ return "請稍等,正在加載中。。。"; }, responseHandler:function(res){ //加載服務器數據以前的處理程序,能夠用來格式化數據,服務器返回的數據要在這裏使用 if(res.resCode == "403"){ localStorage.clear(); parent.location.href = location403; } else if(res.resStatus == 0) { for(var i = 0; i < res.resData.rows.length; i++) { if(res.resData.rows[i].status) { res.resData.rows[i].status = '啓用'; } else { res.resData.rows[i].status = '禁用'; } } var cusData = {//這裏的處理數據是根據你先後臺交互的數據狀況來的 "rows": res.resData.rows, "total": res.resData.total } return cusData; } else { toastr.info(res.resMsg); return; } } }); function logUl(params){ pageNumbers = params.pageNumber; pageSizes = params.pageSize; return { "pageNo": params.pageNumber, "pageSize": params.pageSize, "username": queryVal } } function operateFormatter(value, row, index){ //添加按鈕 var rows = JSON.stringify(row); // 根據傳過來的參數添加不一樣的class var classED = 'enabledE'; var classEDVal; if(row.status == '啓用') { classED = 'enabledD'; classEDVal = '禁用'; } else { classED = 'enabledE'; classEDVal = '啓用'; } // onclick=modif(' + value + "," + rows + "," + index + ') return [ '<div class="modify operationBtn" title="重置密碼" table-data=' + rows + '><i class="glyphicon glyphicon-pencil"></i>重置密碼</div>', '<div class="enabled operationBtn '+ classED + '" title="禁用/啓用" table-data=' + rows + '><i class="glyphicon glyphicon-user"></i>' + classEDVal + '</div>', '<div class="del operationBtn" title="刪除" table-data=' + rows + '><i class="glyphicon glyphicon-trash"></i>刪除</div>' ].join("") }
拖動列來控制列寬的插件:
引入bootstrap-table-resizable.js和colResizable-1.6.min.js
$("#exampleTable").colResizable({ liveDrag: true,//實時顯示滑動位置 gripInnerHtml: "<div class='grip'></div>", //draggingClass: "dragging", postbackSafe: true,//刷新後保留以前的拖拽寬度 headerOnly:true, resizeMode:"overflow", //onResize: onSampleResized });
一些功能實現的樣例:
1.選中
$('#generateClueObjectTable').bootstrapTable('checkBy', { field:"這裏是選中行列字段", values:[這裏選中行是列字段內的值,可多個]});
只可選中一行,使用check.bs.table事件(當用戶選中一行時觸發的事件)
$('#generateClueObjectTable').on('check.bs.table', function (row,element,input) { if (_this.addResearchReportTransObjectJudge) { let selections = $("#generateClueObjectTable").bootstrapTable('getSelections'); if (selections.length > 1) { $('#generateClueObjectTable').bootstrapTable('uncheck',input[0].dataset.index); _this.$message.error('只能選擇一個對象'); } } });
2.禁止全選操做,例:
check-all.bs.table 全選事件
$('#generateClueObjectTable').on('check-all.bs.table', function (row,element,input) { if(_this.addResearchReportTransObjectJudge) { $("#generateClueObjectTable").bootstrapTable('uncheckAll');//阻止全選 } });
3.爲複選框(checkbox)禁用或選中,例:
在複選框(checkbox)列中使用formatter
formatter: function (value, row, index) { return { disabled : true //設置是否可用 checked : true//設置選中 } }
4.在表格中嵌套表格,例:
columns:[{ title: '部門', align: 'left', sortable: false, formatter: function (value, row, index) { return row.deptName; } },{ field: '', title: "<table id=\"statisticTable\" class=\"tables\" style='border:1px solid #bdd5dd;'>" + "<thead><tr>" + "<th style=\"width:9%;padding-left: 10px;\" class=\"statisticTableTD\">狀態</th>" + "<th style=\"width:9%;padding-left: 10px;\" class=\"statisticTableTD\">數量</th>" + "<th style=\"width:9%;padding-left: 10px;\" class=\"statisticTableTD\">自主調研</th>" + "<th style=\"width:9%;padding-left: 10px;\" class=\"statisticTableTD\">上級交辦</th>" + "</tr></thead>" + "</table>", align: 'left', sortable: false, formatter: function (value, row, index) { var table = "<table class='table-keyValue' style='border:1px solid #d0e3e9;'>"; $.each(row.stats, function (i, item) { table += "<tr><td style=\"width:9%;\" class='statisticTableTD '>" + (item.statusCn == null ? 0 : item.statusCn) + "</td>" + "<td style=\"width:9%;\" class='statisticTableTD'>" + (item.number == null ? 0 : item.number) + "</td>" + "<td style=\"width:9%;\" class='statisticTableTD'>" + (item.source1 == null ? 0 : item.source1) + "</td>" + "<td style=\"width:9%;\" class='statisticTableTD'>" + (item.source0 == null ? 0 : item.source0) + "</td>" + "</tr>"; }); table += "</table>"; return table; } }]
5.實現多層表頭
colspan 每格所佔的列數
rowspan 每格所佔的行數
columns: [ [{ title: '這是標題', field: '', align: 'center', valign: 'middle', colspan: 10 }], [{ title: '這是標題1', field: '', align: 'center', valign: 'middle', colspan: 1, rowspan: 2 }, { title: '這是標題2', field: '', align: 'center', valign: 'middle', colspan: 4, rowsapn: 1 }, { title: '這是標題3', field: '', align: 'center', valign: 'middle', colspan: 5, rowsapn: 1 }], [{ field: 'title1', //列ID同時也是指定要顯示的數據的ID title: '標題', width: 100, align: 'center', valign: 'middle', sortable: true }, ...... ] ]
下面是遇到的問題:
問題1.在設置爲服務器端分頁時,獲取頁碼的params.pageNumber會返回undefined
這是由於queryParamsType的默認參數是limit,在官方說明中這樣解釋:
"若是 queryParamsType = 'limit' ,返回參數必須包含limit, offset, search, sort, order 不然, 須要包含: pageSize, pageNumber, searchText, sortName, sortOrder. 返回false將會終止請求"
有兩種解決方法:
1.爲queryParamsType傳空參數,即queryParamsType : "",這時沒有params.limit,但可用params.pageSize來代替
2.修改源碼
首先在bootstrap-table.min.js中搜索 "limit"===this.options.queryParamsType&& (徹底複製過去搜索,固然由於版本的緣由,一些版本代碼細微處可能不太同樣,可是確定跟limit有關)找到下面的代碼片斷:
"limit"===this.options.queryParamsType&&(i={search:i.searchText,sort:i.sortName,order:i.sortOrder},this.options.pagination&&(i.offset=this.options.pageSize===this.options.formatAllRows()?0:this.options.pageSize*(this.options.pageNumber-1),i.limit=this.options.pageSize===this.options.formatAllRows()?this.options.totalRows:this.options.pageSize))
能夠看到在this.options.pagination&&後面的括號中有i.offset=...和i.limit=...的代碼,
在i.limit=this.options.pageSize===this.options.formatAllRows()?this.options.totalRows:this.options.pageSize後面加上,i.pageNumber=this.options.pageNumber(記得必定要英文逗號分隔)
最終修改後結果以下:
"limit"===this.options.queryParamsType&&(i={search:i.searchText,sort:i.sortName,order:i.sortOrder},this.options.pagination&&(i.offset=this.options.pageSize===this.options.formatAllRows()?0:this.options.pageSize*(this.options.pageNumber-1),i.limit=this.options.pageSize===this.options.formatAllRows()?this.options.totalRows:this.options.pageSize, i.pageNumber=this.options.pageNumber))
這樣就能夠經過params.pageNumber取到頁碼
問題2:在向表格內寫入自定義元素時在列中使用formatter方法,但在元素中不可直接添加事件,不然無效,只可以使用js獲取元素後添加事件.
問題3:在向表格內寫入自定義元素時在列中使用formatter方法,但在元素中添加行數據row時,必須先將json數據轉爲字符串纔可以使用,如:
var rows = JSON.stringify(row);
且在添加元素內時必須使用單引號('')包含,如:
"<span class='classDataTable transRelateName' table-data='" + JSON.stringify(row) + "'>" + row.relateName + "</span>"
問題4:當表格中有點擊事件的自定義元素時,換頁會致使沒法點擊?
方法一(推薦,若是在vue等框架內要保證類名和事件函數內調用的函數是惟一的):在寫點擊事件時須要按以下方法書寫:
$(document).on('click', '.researchName', function () {}
方法二:把事件單獨寫一個函數,在表格中添加換頁事件onPageChange,事件調用函數就行
問題5:設置列寬問題
首先要給table加個下面的樣式:
table-layout: fixed;
而後給列設置屬性:
width: 300