先上效果:


表格内编辑插件 · X-editable 使用实例教程_ajax

image.png 表格内编辑插件 · X-editable 使用实例教程_bootstrap_02

image.png

添加 js,css 依赖

<link href="plugins/x-editable-develop/dist/bootstrap-editable/css/bootstrap-editable.css" rel="stylesheet" />
<link href="plugins/x-editable-develop/src/inputs/select2/lib/select2-bootstrap.css" rel="stylesheet" />

<script src="plugins/x-editable-develop/dist/bootstrap3-editable/js/bootstrap-editable.min.js"></script>

JS代码:

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({allowClear: true});
$("[name=deptNo]").html(appList.departmentHtml).select2({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 html = Math.round(value * 100, 2) + "%";
var level = '优';
var background = '#10b510ba';

if (deviation < 0.2) {
level = '优';
background = '#10b510ba';
} else if (deviation >= 0.2 && deviation < 0.4) {
level = '良';
background = '#6e6eff';
} else if (deviation >= 0.4 && deviation < 0.6) {
level = '差';
background = '#f39c12';
} else {
level = '很差';
background = '#ff000099';
}

var baseValue = row.appScoreBaseValue;
html += '<div style="display:flex;justify-content: center;">' +
'<div style="border:1px solid #e8e8e8;padding-left:5px;padding-right:5px;">' +
'<a href="#" name="noteEditable" id="' + row.appId + '" data-type="text">' + baseValue + '</a>' +
'基线值</div>' +
'<span style="background:' + background + ';width:2rem;text-align:center;vertical-align:middle;color:white;border-radius: 1rem;">' + 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: '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();
})

后端 Ajax HTTP 接口的代码

package com.alibaba.swork.info.web.controller.qualitydata;

import com.alibaba.swork.info.common.mapper.QualityDataAppBaseValueMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.math.BigDecimal;

@Controller
public class QualityDataAppBaseValueController {
@Autowired
QualityDataAppBaseValueMapper qualityDataAppBaseValueMapper;

@RequestMapping(value = "updateAppBaseValue", method = RequestMethod.GET)
@ResponseBody
public Result<String> updateAppBaseValue(@RequestParam("appId") Long appId,
@RequestParam("baseValue") String baseValue){
Result<String> result = new Result<>();
BigDecimal baseV = BigDecimal.valueOf(Double.valueOf(baseValue));

try {
qualityDataAppBaseValueMapper.updateBaseValueByAppId(appId, baseV);
result.setSuccess(true);
result.setResult("更新成功");
} catch (Exception e){
result.setSuccess(true);
result.setResult("更新失败" + e.getMessage());
}
return result;
}

}

class Result<T>{
T result;
Boolean success = false;

public T getResult() {
return result;
}

public void setResult(T result) {
this.result = result;
}

public Boolean getSuccess() {
return success;
}

public void setSuccess(Boolean success) {
this.success = success;
}
}

文档参考:

X-editable

​http://vitalets.github.io/x-editable/docs.html#date​