BootstrapTable (前后端分页,表格 ajax 返回数据回调处理) 配置参数全说明
bootstrap table使用总结
前端分页使用实例:
var App = {
renderSummaryData: (res) => {
var hitchDOM = ""
var onlineIssueDOM = ""
hitchDOM += `<div class="col-lg-2 col-xs-6"><div class="small-box bg-blue-active"><div class="inner"><h3>${res.hitchData.total}</h3>故障总数</div></div></div>`
hitchDOM += `<div class="col-lg-2 col-xs-6"><div class="small-box bg-red-gradient"><div class="inner"><h3>${res.hitchData.p1}</h3>P1总数</div></div></div>`
hitchDOM += `<div class="col-lg-2 col-xs-6"><div class="small-box bg-orange-active"><div class="inner"><h3>${res.hitchData.p2}</h3>P2总数</div></div></div>`
hitchDOM += `<div class="col-lg-2 col-xs-6"><div class="small-box bg-teal-active"><div class="inner"><h3>${res.hitchData.p3}</h3>P3总数</div></div></div>`
hitchDOM += `<div class="col-lg-2 col-xs-6"><div class="small-box bg-lime-active"><div class="inner"><h3>${res.hitchData.p4}</h3>P4总数</div></div></div>`
onlineIssueDOM += `<div class="col-lg-2 col-xs-6"><div class="small-box bg-blue-active"><div class="inner"><h3>${res.onlineIssueData.onlineIssueList.length}</h3>线上缺陷数</div></div></div>`
onlineIssueDOM += `<div class="col-lg-2 col-xs-6"><div class="small-box bg-teal-active"><div class="inner"><h3>${Math.round(res.onlineIssueData.avgFixTime * 1, 2)}</h3>平均修复时长(天)</div></div></div>`
onlineIssueDOM += `<div class="col-lg-2 col-xs-6"><div class="small-box bg-lime-active"><div class="inner"><h3>${Math.round(res.onlineIssueData.fixedRate, 2) * 100}%</h3>修复率</div></div></div>`
$('#hitchDOM').html(hitchDOM)
$('#onlineIssueDOM').html(onlineIssueDOM)
events: () => {
$("#searchBtn").unbind().bind("click", () => {
$('#App').bootstrapTable('refresh');
$("#clsBtn").unbind().bind("click", () => {
$("#deptNo").select2().val("");
$('#startDate').val("");
$('#endDate').val("");
$("[name=deptNo]").html(App.departmentHtml).select2({
placeholder: "请选择",
placeholderOption: "first",
allowClear: true
$('#startDate').datepicker({
language: 'zh_CN',
format: 'yyyy-mm-dd',
clearBtn: true,
autoclose: true,
todayBtn: "linked",
todayHighlight: true,
}).on('changeDate', function (e) {
$('#endDate').datepicker('setStartDate', e.date);
$('#endDate').datepicker({
language: 'zh_CN',
format: 'yyyy-mm-dd',
clearBtn: true,
autoclose: true,
todayBtn: "linked",
todayHighlight: true,
}).on('changeDate', function (e) {
$('#startDate').datepicker('setEndDate', e.date);
initData: () => {
$.ajax({
url: "integratedFindAll",
data: {},
dataType: "json",
type: "POST",
async: false,
success: function (data) {
var departmentList = data.departmentList;
var departmentHtml = "";
$(departmentList).each(function (key, value) {
departmentHtml += '<option value="' + value.deptNo + '">' + value.deptName + '</option>'
App.departmentHtml = '<option></option>' + departmentHtml;
initBootstrapTable: () => {
$('#App').bootstrapTable({
detailView: false,//父子表
//分页方式:client 客户端分页,server服务端分页(*)
sidePagination: "client",
pageNumber: 1,
pageSize: 10,
pageList: [10, 25, 50, 100],
paginationHAlign: 'right', //right, left
paginationVAlign: 'bottom', //bottom, top, both
paginationDetailHAlign: 'left', //right, left
paginationPreText: '‹',
paginationNextText: '›',
searchOnEnterKey: false,
strictSearch: false,
searchAlign: 'right',
selectItemName: 'btSelectItem',
//是否显示搜索
search: true,
url: 'getQualityDataOfDepartmentDto',
method: 'GET',
striped: true, //是否显示行间隔色
cache: false, //是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*)
pagination: true, //是否显示分页(*)
paginationLoop: false,
silent: true,
//是否启用排序
sortable: true,
//排序方式
sortOrder: "asc",
contentType: 'application/json',
dataType: 'json',
// dataField: 'departmentIssueQualityDataList', //server 后端 : json 对应的表格数据 key
responseHandler: function (res) {
console.log(res)
App.renderSummaryData(res);
$('#App').bootstrapTable('getOptions').data = res.departmentIssueQualityDataList;
return res;
columns: [
// name: "deptName",
// title: "部门",
valign: "middle",
align: "center",
colspan: 1,
rowspan: 1
title: "整体",
valign: "middle",
align: "center",
colspan: 9,
rowspan: 1
title: "前端",
valign: "middle",
align: "center",
colspan: 5,
rowspan: 1
title: "后端",
valign: "middle",
align: "center",
colspan: 6,
rowspan: 1
title: '部门',
field: 'deptName',
align: 'left',
valign: 'middle',
cellStyle: function (value, row, index) {
return {
css: {
"min-width": "200px",
"word-wrap": "break-word",
"word-break": "normal"
formatter: (value, row, index) => {
return value;
title: '有效缺陷数',
field: 'totalValidIssue',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
return value;
title: '开发人员数',
field: 'totalNumDevs',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
return value;
title: '人均缺陷',
field: 'totalAvgIssueOfPerson',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
if(value){
value = value.toFixed(2)
return value;
title: '代码变更行',
field: 'totalLineChange',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
return value;
title: '人均代码变更',
field: 'totalAvgLineChangeOfPerson',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
if(value){
value = value.toFixed(2)
return value;
title: 'reopen 率',
field: 'totalReopenRate',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
if(value){
value = value.toFixed(2)
return `${value*100}%`;
title: '初级缺陷率',
field: 'totalEasyfindRate',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
if(value){
value = value.toFixed(2)
return `${value*100}%`;
title: '平均修复时长',
field: 'totalAvgFixTime',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
if(value){
value = value.toFixed(2)
return value;
title: '缺陷修复率',
field: 'totalFixRate',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
if(value){
value = value.toFixed(2)
return `${value*100}%`;
title: '有效缺陷数',
field: 'frontValidIssue',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
return value;
title: 'reopen 率',
field: 'frontReopenRate',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
if(value){
value = value.toFixed(2)
return `${value*100}%`;
title: '初级缺陷率',
field: 'frontEasyfindRate',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
if(value){
value = value.toFixed(2)
return `${value*100}%`;
title: '平均修复时长',
field: 'frontAvgFixTime',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
if(value){
value = value.toFixed(2)
return value;
title: '缺陷修复率',
field: 'frontFixRate',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
if(value){
value = value.toFixed(2)
return `${value*100}%`;
title: '有效缺陷数',
field: 'backValidIssue',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
return value;
title: 'reopen 率',
field: 'backReopenRate',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
if(value){
value = value.toFixed(2)
return `${value*100}%`;
title: '初级缺陷率',
field: 'backEasyfindRate',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
if(value){
value = value.toFixed(2)
return `${value*100}%`;
title: '平均修复时长',
field: 'backAvgFixTime',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
if(value){
value = value.toFixed(2)
return value;
title: '缺陷修复率',
field: 'backFixRate',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
if(value){
value = value.toFixed(2)
return `${value*100}%`;
title: '缺陷密度',
field: 'backIssueDensity',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
if(value){
value = value.toFixed(2)
return value;
queryParams: function (params) {
params.deptNo = $("#deptNo").val()
if ($("#startDate").val()) {
params.startDate = new Date($("#startDate").val()).Format("yyyy-MM-dd");
if ($("#endDate").val()) {
params.endDate = new Date($("#endDate").val()).Format("yyyy-MM-dd");
return params
//注册加载子表的事件。注意下这里的三个参数!
onExpandRow: function (index, row, $detail) {
// 当表格加载完毕才可以绑定的事件
onPostBody: (rows) => {
init: () => {
App.initData();
App.events();
App.initBootstrapTable();
$(() => {
App.init();
var options = $('#App').bootstrapTable('getOptions');
console.log(options);
})
后端分页使用实例:
function doAjax(data) {
$.get({
url: 'updateAppBaseValue',
data: data,
success: (result) => {
debugger;
if (result.success == true) {
new PNotify({
title: '设置基线值',
styling: 'bootstrap3',
text: '更新成功!',
type: 'success',
delay: 3000
} else {
new PNotify({
title: '设置基线值',
styling: 'bootstrap3',
text: '服务器出错,请联系管理员!',
type: 'error',
delay: 3000
error: (a, b, c) => {
debugger;
var appList = {
getAppendTextUp: (x, y) => {
var color = x >= y ? 'green' : 'red';
var text = Math.round((x - y) * 1.0, 2);
var flgHtml = "";
return x + '<div style="display:flex;justify-content: center;">' +
'<span style="width:25px;text-align:center;vertical-align:middle;color:' + color + '">(' + text + ')</span></div>';
getAppendTextUpWithPercentage: (x, y) => {
var color = x >= y ? 'green' : 'red';
var text = Math.round((x - y) * 100.0, 2);
var flgHtml = "";
return Math.round(x * 100.0, 2) + '<div style="display:flex;justify-content: center;">' +
'<span style="width:25px;text-align:center;vertical-align:middle;color:' + color + '">(' + text + ')</span></div>';
getAppendTextDown: (x, y) => {
var color = x <= y ? 'green' : 'red';
var text = Math.round((x - y) * 1.0, 2);
var flgHtml = "";
return Math.round(x * 1.0, 2) + '<div style="display:flex;justify-content: center;">' +
'<span style="width:25px;text-align:center;vertical-align:middle;color:' + color + '">(' + text + ')</span></div>';
getAppendTextDownWithPercentage: (x, y) => {
var color = x <= y ? 'green' : 'red';
var text = Math.round(1.0 * (x - y), 2);
var flgHtml = "";
return Math.round(x * 100.0, 2) + '<div style="display:flex;justify-content: center;">' +
'<span style="width:25px;text-align:center;vertical-align:middle;color:' + color + '">(' + text + ')</span></div>';
events: () => {
$("#searchBtn").unbind().bind("click", () => {
$('#appTable').bootstrapTable('refresh');
$("#clsBtn").unbind().bind("click", () => {
$("#deptNo").select2().val("");
$("#aoneProductId").select2().val("");
$("[name=aoneProductId]").html(appList.productHtml).select2({
placeholder: "请选择",
placeholderOption: "first",
allowClear: true
$("[name=deptNo]").html(appList.departmentHtml).select2({
placeholder: "请选择",
placeholderOption: "first",
allowClear: true
initData: () => {
$.ajax({
url: "integratedFindAll",
data: {},
dataType: "json",
type: "POST",
async: false,
success: function (data) {
var products = data.products;
var departmentList = data.departmentList;
var productHtml = "";
var departmentHtml = "";
$(products).each(function (key, value) {
productHtml += '<option value="' + value.aoneProductId + '">' + value.aoneProductName + '</option>'
$(departmentList).each(function (key, value) {
departmentHtml += '<option value="' + value.deptNo + '">' + value.deptName + '</option>'
appList.productHtml = '<option></option>' + productHtml;
appList.departmentHtml = '<option></option>' + departmentHtml;
initBootstrapTable: () => {
$('#appTable').bootstrapTable({
detailView: false,//父子表
url: 'findQualityDataOfAppDtoByDeptNoAndAoneProductId',
sidePagination: "server",
queryParamsType: 'pageSize,pageNum',
contentType: "application/x-www-form-urlencoded",
method: 'GET',
striped: true, //是否显示行间隔色
cache: false, //是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*)
pagination: true, //是否显示分页(*)
paginationLoop: false,
sortable: true, //是否启用排序
sortOrder: "desc", //排序方式
sortName: "lineCount",
pageNumber: 1, //初始化加载第一页,默认第一页
pageSize: 10, //每页的记录行数(*)
pageList: [5, 10, 20, 50, 100],// 可选的每页数据
silent: true,
totalField: 'total',
dataField: 'list', //后端 json 对应的表格数据 key
columns: [
title: '产品线',
field: 'aoneProductName',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
return value;
title: '应用',
field: 'appName',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
return value;
title: '偏离度',
field: 'deviation',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
var deviation = value;
var baseValue = row.appScoreBaseValue;
var appScore = row.appScore;
try {
var x = (baseValue - appScore) / parseFloat(baseValue);
deviation = x.toFixed(2);
} catch (e) {
deviation = 1;
var html = Math.round(deviation * 100, 2) + "%";
var level = '优';
var background = '#eee';
if (deviation < 0.2) {
level = '优';
background = '#36CC22';
} else if (deviation >= 0.2 && deviation < 0.4) {
level = '良';
background = '#6e6eff';
} else if (deviation >= 0.4 && deviation < 0.6) {
level = '差';
background = '#f39c12';
} else if (deviation >= 0.6 && deviation <= 1.0) {
level = '很差';
background = '#ff4b52';
} else {
level = '未知';
background = '#B8B8B8';
html += '<div style="display:flex;justify-content: center;width: 10rem;">' +
'<div style="border:1px solid #e8e8e8;padding-left:5px;padding-right:5px;min-width:70px">' +
'<a href="#" name="noteEditable" id="' + row.appId + '" data-type="text">' + baseValue + '</a>' +
'基线值</div>' +
'<span style="background:' + background + ';width:2.5rem;min-width: 2.5rem;text-align:center;color:white;border-radius: 0.2rem;margin-right: 0.5rem;vertical-align:middle;">' + level + '</span></div>';
return html;
field: 'appScore',
title: '应用代码评分',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
var html = value;
var rate = 0.0;
var appScoreRelative = row.appScoreRelative
if (value != 0) {
rate = Math.round((value - appScoreRelative) / value * 100, 2);
if (rate >= 0) {
html += '<div style="display:flex;justify-content: center;">环比<span style="width:25px;text-align:center;vertical-align:middle;color:green">' + rate + '%<i class="fa fa-long-arrow-up"></i></span></div>';
} else {
html += '<div style="display:flex;justify-content: center;">环比<span style="width:25px;text-align:center;vertical-align:middle;color:red">' + rate + '%<i class="fa fa-long-arrow-down"></i></span></div>';
return html
field: 'lineCount',
title: '代码行数',
align: 'center',
valign: 'middle'
field: 'complexity',
title: '复杂度',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
return appList.getAppendTextDown(value, row.complexityRelative);
field: 'duplication',
title: '重复率%',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
return appList.getAppendTextDown(value, row.duplicationRelative);
field: 'commentRate',
title: '注释率%',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
var html = appList.getAppendTextUp(value, row.commentRateRelative);
return html
field: 'uiRate',
title: 'UI通过率%',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
var html = appList.getAppendTextUpWithPercentage(value, row.uiRateRelative);
return html
field: 'itRate',
title: 'API通过率%',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
var html = appList.getAppendTextUpWithPercentage(value, row.itRateRelative);
return html
field: 'utRate',
title: 'UT通过率%',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
var html = appList.getAppendTextUpWithPercentage(value, row.utRateRelative);
return html
field: 'utCoverageLine',
title: '行覆盖率%',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
var html = appList.getAppendTextUpWithPercentage(value, row.utCoverageLineRelative);
return html
field: 'utCoverageBranch',
title: '分支覆盖率%',
align: 'center',
valign: 'middle',
formatter: (value, row, index) => {
var html = appList.getAppendTextUpWithPercentage(value, row.utCoverageBranchRelative);
return html
field: 'staticCodeCheckValue4',
title: '静态扫描',
align: 'center',
valign: 'middle'
field: 'staticCodeCheckValue2',
title: '集团规约',
align: 'center',
valign: 'middle'
field: 'staticCodeCheckValue3',
title: 'CR 规则',
align: 'center',
valign: 'middle'
queryParams: function (params) {
return {
pageSize: params.pageSize,
pageNum: params.pageNumber,
sortName: params.sortName,
sortOrder: params.sortOrder,
searchText: params.searchText,
deptNo: $("#deptNo").val(),
aoneProductId: $("#aoneProductId").val()
//注册加载子表的事件。注意下这里的三个参数!
onExpandRow: function (index, row, $detail) {
// 当表格加载完毕才可以绑定的事件
onPostBody: (rows) => {
let rowsList = rows;
$('[name=noteEditable]').each(function (index, item) {
$(this).editable({
title: '请输入基线值',
placeholder: '必填,请输入基线值...',
$(this).on('hidden', function (e, reason) {
if (reason === 'save') {
debugger;
//doAjax
let ajaxData = {
appId: $(e.currentTarget).attr("id"),
baseValue: e.currentTarget.text
doAjax(ajaxData)
init: () => {
appList.initData();
appList.events();
appList.initBootstrapTable();
$(() => {
appList.init();
})
BootstrapTable.DEFAULTS = {
classes: 'table table-hover',
sortClass: undefined,
locale: undefined,
height: undefined,
undefinedText: '-',
sortName: undefined,
sortOrder: 'asc',
sortStable: false,
striped: false,
columns: [[]],
data: [],
totalField: 'total',
dataField: 'rows',
method: 'get',
url: undefined,
ajax: undefined,
cache: true,
contentType: 'application/json',
dataType: 'json',
ajaxOptions: {},
queryParams: function (params) {
return params;
queryParamsType: 'limit', // undefined
responseHandler: function (res) {
return res;
pagination: false,
onlyInfoPagination: false,
paginationLoop: true,
sidePagination: 'client', // client or server
totalRows: 0, // server side need to set
pageNumber: 1,
pageSize: 10,
pageList: [10, 25, 50, 100],
paginationHAlign: 'right', //right, left
paginationVAlign: 'bottom', //bottom, top, both
paginationDetailHAlign: 'left', //right, left
paginationPreText: '‹',
paginationNextText: '›',
search: false,
searchOnEnterKey: false,
strictSearch: false,
searchAlign: 'right',
selectItemName: 'btSelectItem',
showHeader: true,
showFooter: false,
showColumns: false,
showPaginationSwitch: false,
showRefresh: false,
showToggle: false,
buttonsAlign: 'right',
smartDisplay: true,
escape: false,
minimumCountColumns: 1,
idField: undefined,
uniqueId: undefined,
cardView: false,
detailView: false,
detailFormatter: function (index, row) {
return '';
trimOnSearch: true,
clickToSelect: false,
singleSelect: false,
toolbar: undefined,
toolbarAlign: 'left',
checkboxHeader: true,
sortable: true,
silentSort: true,
maintainSelected: false,
searchTimeOut: 500,
searchText: '',
iconSize: undefined,
buttonsClass: 'default',
iconsPrefix: 'glyphicon', // glyphicon of fa (font awesome)
icons: {
paginationSwitchDown: 'glyphicon-collapse-down icon-chevron-down',
paginationSwitchUp: 'glyphicon-collapse-up icon-chevron-up',
refresh: 'glyphicon-refresh icon-refresh',
toggle: 'glyphicon-list-alt icon-list-alt',
columns: 'glyphicon-th icon-th',
detailOpen: 'glyphicon-plus icon-plus',
detailClose: 'glyphicon-minus icon-minus'
customSearch: $.noop,
customSort: $.noop,
rowStyle: function (row, index) {
return {};
rowAttributes: function (row, index) {
return {};
footerStyle: function (row, index) {
return {};
onAll: function (name, args) {
return false;
onClickCell: function (field, value, row, $element) {
return false;
onDblClickCell: function (field, value, row, $element) {
return false;
onClickRow: function (item, $element) {
return false;
onDblClickRow: function (item, $element) {
return false;
onSort: function (name, order) {
return false;
onCheck: function (row) {
return false;
onUncheck: function (row) {
return false;
onCheckAll: function (rows) {
return false;
onUncheckAll: function (rows) {
return false;
onCheckSome: function (rows) {
return false;
onUncheckSome: function (rows) {
return false;
onLoadSuccess: function (data) {
return false;
onLoadError: function (status) {
return false;
onColumnSwitch: function (field, checked) {
return false;
onPageChange: function (number, size) {
return false;
onSearch: function (text) {
return false;
onToggle: function (cardView) {
return false;
onPreBody: function (data) {
return false;
onPostBody: function () {
return false;
onPostHeader: function () {
return false;
onExpandRow: function (index, row, $detail) {
return false;
onCollapseRow: function (index, row) {
return false;
onRefreshOptions: function (options) {
return false;
onRefresh: function (params) {