需要解决的问题:使用bootstrap-table实现行内编辑功能。
中途探索的路径:使用bootstrap-table-edit实现。
探索遇到的问题:bootstrap-table-edit和bootstrap-edittable无法正常行内编辑功能,实践中在浏览器调试界面提示new变量未定义啥的,原因大概率是bootstrap 与bootstrap-table与X-editable的版本不兼容的原因。
思想转换后的解决路径。使用bootstrap-table中的一个事件参数ondblclickcell来实现相关功能。具体代码和遇到的坑见下方的代码。下图是ondblclickcell的一个方法,内容很简单,就是检测到表格有双击的时候触发双击事件,事件的执行就是判断是否允许双击事件的列,允许则给表格元素设置contenteditable为true,也就是允许编辑,然后在离开触发事件的表格时,执行获取行数和修改后的内容,同时对修改后的内容进行对比确认,如果内容与原内容不一致,则执行保存数据的函数。
onDblClickCell: function(field, value, row, $element) {
console.log(field,value,$element,row);
var arr = [0,'id','zfid','zfxm'];//设置数组,内容为列名
var a = eval('{% if current_user.is_admin or current_user.is_company %}true{%else%}false{%endif%}');
if(a){
if(arr.indexOf(field) == -1){//判断点击的那一列的列名是否属于之前设置的列,也就是不允许修改的列
$element.attr('contenteditable', true);
$element.blur(function() {
var index = $element.parent().data('index');
var tdValue = $element.html();
if(tdValue!=value){//如果对内容进行了修改,则启动保存功能
saveData(index, field, tdValue,row);
}
}
)}}
}
第二个就是保存函数,这段代码其实很简单,但是,足足花费了我1天多的时间调试和处理,以及寻找问题。首先,通过updateCell来执行更新表格数据,也就是把新修改的数据保存显示到表格中,但是,这个时候的数据仅仅修改显示在前端界面,后端数据库是没有变化的,具体后端数据库如果提交修改,请继续看后面的代码。我是使用ajax通过异步提交的方式将修改后的数据实时提交到flask程序后端进行处理,这里遇到最大的坑是在csrf-token的问题上,最开始没有添加这个csrf-token的提交,所以每次提交数据都提示内部服务器错误,然后我打开这个请求后发现,具体的错误内容是csrf-token报错,也就是没有正常的提交csrf令牌导致服务器报错,因为我的flask是增加了csrf的校验,所以,所有的Post提交必须要增加csrf校验,否则是无法通过的。然后baidu上查询如何提交,最开始看的是把csrf放到data中提交,增加一个名为csrf-token,值为{{ csrf_token() }}的数据,后来发现还是报错,没有解决,又经过了一系列的查询,最后发现应该在请求头中增加校验,而且名称应该是X-CSRFToken,之前就搞错了,至于为什么前面加一个X-,我也不知道为什么,因为之前使用flask提交Post数据我也没有注意这个头部的问题。然后我就加进去了,再然后,成功提交了数据。
第三个问题就是传递数据的类型,必须加JSON.stringify,转换数据格式后传递给后端,不然后端的处理比较麻烦。这个坑也解决了半个小时。
function saveData(index, field, value,row) {//保存函数,参数为主函数传递的修改的内容
$('#bstable').bootstrapTable('updateCell', {//updateCell可以直接修改表格中的内容
index: index, //行索引
field: field, //列名
value: value //cell值
});
console.log({"index":row.id, "field":field,"value": value
, "csrf_token":'{{ csrf_token() }}'});
$.ajax({
headers:{'Content-type':"application/json;charset=UTF-8",
"X-CSRFToken": '{{ csrf_token() }}'},//特别注意这里,flask开通csrf校验必须在头部增加这个字段,否则后端无法正常接收,会报错内部服务器错误500
type: "post",
url: "/ccxpx_edit",//这里也可以用'{{ mian.ccxpx_edit }}'视图函数名称
data: JSON.stringify({//特别注意,flask后端要比较好处理,这里要转json再传递
"index":row.id,
"field":field,
"value":value
}),
dataType: "json",
success: function(data){
console.log(data);
if(data.data == "success"){
alert('数据保存成功');
}},
error:function(error){
console.log(error);//输出错误
alert('数据保存失败');
}
})
}
后端的数据看下面的图,在接收数据的时候也花费了很久的时间测试,当然,这里,接收数据还算比较好处理的问题,因为是字符串接收,所以用eval转换下,然后再通过名称获取相关的值,判断是否post提交,查询修改数据的id,然后提交修改的id,这里有个超级大的坑,目前我都还没有完全理解的一个坑,那就是无法正常提交的问题,因为提交数据的时候需要给查询的结果,也就是查询对象的相关列赋值,因为传递的是一个变量,所以最初我用的eval来执行一个赋值语句,但是总是报错,具体语言是这样的eval('q.'+ field + '=' + value),但是这个语句报错,无法执行,也就无法赋值,后来百度查询到通过q.__dict__[field] = value可以进行赋值,在flask shell中赋值后可以查询到相关的值确实改变了,但是通过db.session.commit()提交后,并没有真正的修改数据库中的值,所以我就蒙了,然后就是一天半的时间专门解决这个问题,完全不知道原因所在。
后来发现,有一个setattr(q,field,value)语句专门批量给查询值的列传递值的,我在flask shell中测试了很久,跟q.__dict__[field] 赋值时一样的问题,也就是赋值后当时发现成功,但是commit()提交总是把数据写不进去,这个时候我快崩溃了,一万个不理解错误的原因到底在哪里,所以一天半的时间就是不断的测试测试中浪费的,后来,我想要不在系统中写进去试试,于是,下面代码中展现了现在的新的代码,再重新打开网页,居然修改成功了,所以虽然解决了问题,但是我依旧不知道原因在哪儿,奔溃。所以写下了这片文章,给有需要的人提醒一下。同时我也发现了,在flask-sqlalchemy的使用中,真的有很多很多的诀窍,比如setattr,getattr和hasattr是非常使用的几个函数,后期我会考虑把所有的提交都交给这几个函数来执行,非常非常的简单,实用,避免了写赋值代码,这也算是浪费的三四天中一个不大不小的收获吧,如果有高手知道为什么shell中提交不成功请告诉我,谢谢。
然后具体网页修改的界面看最下面的图。
@main_bp.route('/ccxpx_edit', methods=['GET', 'POST'])
@login_required
def ccxpx_edit():
result = {"code": "", "data": ""}
data = eval(request.data)
id = data.get('index')
field = data.get('field')
value = data.get('value')
print('服务器接受参数', id, field, value)
if request.method == "POST":
if not field:
result['data'] = '服务器未接受到参数'
result["code"] = 400
else:
q = CcxpyExc.query.filter_by(id=int(id)).first()
if q:
#q.__dict__[field] = value
setattr(q,field,value)
print(q.fyccxzx)
try:
db.session.commit()
result["code"] = 200
result['data'] = 'success'
except:
db.session.rollback()
result["code"] = 300
result['data'] = '提交保存失败'
else:
result['data'] = 'id错误,未查询到数据'
result["code"] = 444
else:
result["code"]=400
result["data"]="请求方法错误"
return jsonify(result)


本文介绍如何使用Bootstrap Table插件实现表格的行内编辑功能,包括利用ondblclickcell事件触发编辑状态,通过AJAX提交更改并解决CSRF验证问题。

被折叠的 条评论
为什么被折叠?



