最近一个项目,提到了可以用行内样式编辑最好,要求是,一个html table,一行的最后有个编辑按钮,然后点击编辑以后,能对这行进行修改。如果确认修改点击确认,可以对整行进行修改。如果,不想修改了则直接点击取消。返回非编辑状态。
对于这个我觉得还是挺有意思的,而且也是可以实现的,先是在网上找现成的代码,代码都是boostrapTable+xeditable的整合形式。但是我们这个项目,一开始没有选择使用boostrapTable的结构,如果因为一个行内编辑改的话,第一要学的有点多,第二要根据boostrapTable的模式改前端table和后台传值,实在是不想有太多改动,毕竟我只是需要一个行内样式。看了一圈下来,自己也试了试。发现其实完成我的需求只需要引入xeditable就行了,压根不用boostrapTable。新开了个项目,写了一天的js 最终完成了这个功能。结果如下:
1.模拟基础显示表格
2.点击编辑(启用编辑模式)
3.修改样式(text textarea 多选,单选框都要可以支持,还有可以先前端验证下数据格式)
4.点击确认要你那个接收到修改的值,方便统一ajax处理
5.点击取消回复原来的值
样式写的比较简陋,两条数据是js 拼接的,主要是一切从简,只保留了最关键的代码,其余的东西完全可以,按照自己的需求去美化,加样式。
大致说一下思路,源码会在最下面放地址
最小的代码侵占性。最小的代码修改。可以主要代码公用,具体代码各个页面各写各的。是我所想的。也就是说,首先我不用管你表格是怎么生成的,ajax分页请求回来拼接的也好,get同步返回的表单也好,都可以。只要在后面tr td 后面加个td为编辑的按钮,在你要修改的字段value外面,包一层<a>标签就好了,然后把公共代码(编辑器有关,编辑,确认,取消按钮有关)放在外面,具体的各个页面的ajax修改方法放在各个页面内部。
一步一步看看怎么写的:
1.模拟数据封装,初始化编辑器
$(function () {
//模拟数据拼接开始
var appendData='<tr><td>序号</td><td>姓名</td><td>性别</td><td>备注</td><td>操作</td></tr>'+
'<tr><td>1</td><td><a class=editUsername>张xy</a></td><td><a class=editSex>男</a></td><td><a class=editMemo>哈哈</a></td><td><input type=button onClick=editClickChange(this) class=btn btn-primary value=编辑 /></td></tr>'+
'<tr><td>2</td><td><a class=editUsername>李BB</a></td><td><a class=editSex>女</a></td><td><a class=editMemo>what?</a></td><td><input type=button onClick=editClickChange(this) class=btn btn-primary value=编辑 /></td></tr>';
$('#dataFlag').html(appendData);
initEditModel();
//模拟数据拼接结束
});
拼接数据,将要修改的字段外面包上一层a标签,然后最后加上一个编辑按钮
//负责有关初始编辑模型
function initEditModel(){
$('.editUsername').editable({
title: "修改", //编辑框的标题
type: "text", //编辑框的类型。支持text|textarea|select|date|checklist等
disabled: true, //是否禁用编辑
mode: "inline", //编辑框的模式:支持popup和inline两种模式,默认是popup
emptytext: "空文本", //空值的默认文本
validate: function (value) { //字段验证
if (isEmpty(value)) {
return '不能为空';
}
}
});
$('.editMemo').editable({
title: "修改", //编辑框的标题
type: "text", //编辑框的类型。支持text|textarea|select|date|checklist等
mode: "inline", //编辑框的模式:支持popup和inline两种模式,默认是popup
disabled: true, //是否禁用编辑
emptytext: "空文本", //空值的默认文本
validate: function (value) { //字段验证
if (isEmpty(value)) {
return '不能为空';
}
}
});
$('.editSex').editable({
title: "性别", //编辑框的标题
type: "select", //编辑框的类型。支持text|textarea|select|date|checklist等
mode: "inline", //编辑框的模式:支持popup和inline两种模式,默认是popup
source: [{ value: 1, text: "男" }, { value: 2, text: "女" }],
disabled: true, //是否禁用编辑
emptytext: "空文本", //空值的默认文本
validate: function (value) { //字段验证
if (isEmpty(value)) {
return '不能为空';
}
}
});
}
这段代码负责按class 锁定要修改的字段,然后初始化编辑器,并将编辑器设置为关闭的状态,Type可以设置编辑器的编辑框类型。validate里面可以写对于编辑字段的规则验证。至此,可修改的编辑字段已经初始化,但是现在是关闭状态
2.公用编辑按钮点击事件
//还原tr,点击取消的时候,还原未修改的tr
var saveCopyTr='';
//开启/关闭编辑操作
function changeEditType(){
$("#editTr .editable").editable('toggleDisabled');
}
//编辑按钮
function editClickChange(org){
if($("#handleFlag").length!=0){
alert("同时只允许一个编辑操作");
return;
}
//获取编辑按钮的td
var parentTd= $(org).parent();
//获取编辑当前行的tr
var parentTr=$(parentTd).parent();
//备份当前tr
saveCopyTr=$(parentTr).html();
$(parentTr).attr("id","editTr");
//启动编辑模式
changeEditType();
//新增操作按钮,隐藏编辑按钮
var htmlButton='<div id=handleFlag><button onClick=editHandle(this) class=btn btn-default>确认</button><button onClick=cancelChange(this) class=btn btn-default>取消</button></div>';
org.style.cssText = "display:none;";
$(parentTd).append(htmlButton);
}
给正在编辑的tr加上标识,防止多列编辑,然后保存未修改的tr备份(取消后,就用这个装回去),接着开启设置tr标识的这一列的编辑模式。jq 先隐藏编辑按钮,然后动态添加两个按钮,一个确认,一个取消。
3.取消按钮
//取消按钮
function cancelChange(org){
var editButton=$(org).parent().prev();
$("#editTr").html(saveCopyTr);
changeEditType();
saveCopyTr="";
$("#editTr").removeAttr("id");
$(editButton).removeAttr("style");
$("#handleFlag").remove();
}
获取按钮,将修改后的tr改成保存的未修改的,然后关闭编辑模式,清空保存str,移除修改tr标识,显示编辑按钮,将确认,取消的代码块移除。
4.确认按钮(获取修改参数,后台交互处理按钮)
//修改确认(接受修改参数+ajax修改请求)
function editHandle(){
alert("editHandle:您修改的字段为:");
var changeUsername=$(".editUsername.editable-unsaved").text();
var changeSex=$(".editSex.editable-unsaved").text();
var changeMemo=$(".editMemo.editable-unsaved").text();
var sex = '';
if(changeUsername!= ''){
alert("您修改 姓名 为:"+changeUsername);
}
if(changeSex!= ''){
sex = $(".editSex.editable-unsaved").editable('getValue', true);
alert("您修改 性别 为:"+changeSex);
alert("性别代码 为:"+sex);
}
if(changeMemo!= ''){
alert("您修改 备注 为:"+changeMemo);
}
//ajax
//to do......
}
function isEmpty(s){
return s == null || $.trim(s) == '';
}
如果已经修改的字段,内部css会新增一个叫editable-unsave的样式。而,这个样式只会出现在开启编辑器的那个tr 后面所以,很容易锁定修改的内容和修改的字段信息。想如select选框中,那种虽然显示的男女,但实际上是1,2这样的值,可以通过.ediable("getValue",true) 来获取。
接下来,获取到所有修改的值后,就可以完成各自所需要ajax修改请求了。
代码看下来,也挺简单的,按照我的逻辑,
其实就initEditModel方法和editHandle需要在具体修改页面重写,其他的都是可以放在公共js文件中的。这样的话,其实使用起来很简单。第一个方法自定义编辑字段和需求,第二个方法负责接收修改值,并且ajax处理修改请求。
作为一个后台工程师,其实偶尔写写js还是挺有意思的。
有关引用的所有js和css,以及springBoot的修改demo,和html直接访问的修改demo地址如下:
boostrp js,css整合包:http://download.csdn.net/download/zxysshgood/10245811
SpringBoot+jsp/html demo:http://download.csdn.net/download/zxysshgood/10245838