博主初次入行,遇到一个好玩的客户需求,自己用jquery调试了好久总算调出来了,这里给大家分享一下我的经验,新手!新手!新手!重要的事多说一遍:新手!这个好玩的需求在于对html table中数据操作问题,大多数情况下点新增,编辑按钮时都是弹出壹个新网页,在网页中进行操作,这如果在一次需要对数据库表做很多的修改就显得很鸡肋;所以客户更希望直接在table表中修改数据,然后再一次性将数据发送到后台处理。
因为是自己一步一步的调出来的,所以可能看着有些菜,毕竟博主还是新手,有不对不好的地方还请帮帮忙赐教赐教
第一步:需求分析
把table表变成可编辑状态,无非就是放一个input到相应的td中;
首先第一需要知道的要编辑的是哪一行:可以对每一个行讲一个onclick事件
其次就是要保证一次正在编辑的只有一行,所以点击一行时需要清除前一行的input格式以及判断为空时就不能点击
最后就是记录是新增的行,还是修改的行,以及删除的行
第二步:网页
就是一张普通的jsp页面,用foreach遍历出所有的数据到table表中:
<c:forEach items="${result.data}" var="item" varStatus="s">
<tr class="tr_change" οnclick="_edit(this)">
<input type="hidden" value="${item.id}"/>
<td name="name"> ${item.name}</td>
</tr>
</c:forEach>
得到一张这样的表(为了方便,我就只贴了一列的表):
然后大概效果(瞎做的gif图,意思意思):
然后就是js代码了:
首先加一个temp变量判断是否对table编辑过:
var temp = true;
//tr点击编辑事件
function _edit(obj){
var has = $(".table input[type=text]");
var could = $(obj).find(":input[type=text]");
//判断当前tr是否正在编辑
if(could.length!=0){
return;
}
//判断table中在编辑的tr是否为空
if($(has).val()==""){
return;
}
_clear(has);
$(obj).children("td").html("<input οnchange='_change(this,"+'"'+$(obj).children("td").html()+'"'+")' type='text' value='"+$(obj).children("td").html().trim()+"'>");
}
//清除input格式
function _clear(obj){
var parent = $(obj).parent();
var val = $(obj).val();
if(val != ""){
$(parent).html(val);}
else
return;
}
现在可以对已有的数据进行修改;然后要解决的是新增和删除:
//新增
function toAdd(){
var could = $(".table input[type=text]");
if($(could).val()!=""){
_clear(could);
$("table.table").append("<tr class='tr_change addRow' οnclick='_edit(this)'><input type='hidden' value='0'/><td><input type='text' οnchange='_change(this,"+''+")' value=''/></td></tr>");
}else{
return;
}
}
//删除
function _delete(){
var has = $(".table input[type=text]");
if(has.length != 0){
var deleteid = $(has).parent().parent().find("input[type=hidden]").val();
if(deleteid!="0"){
deletejson += "," + deleteid;
temp = false;
}
$(has).parent().remove();
}
}
当然刷新按钮依旧:
//刷新
function _refresh(){
window.location.reload();
}
然后再对onchange事件进行编辑,这里我们可以小小的添加一次使table数据都是唯一的判断:
//记录修改与否
function _change(obj,preval){
var val = $(obj).val();
$("table").find("td").each(function(){
if(val.trim()==$(this).html().trim()){
alertF("不能有重复的值,修改失败");
$(obj).val(preval);
}else{
var updateid = $(obj).parent().parent().find("input[type=hidden]").val();
if(updateid != "0"){
$(obj).parent().parent().addClass("updateRow");
}
temp = false;
}
});
}
这里对于新增的行我们加一个class为addRow,对修改的行加一个class为updateRow;用去区分json;
第三步:对table表中的数据封装json传入后台中
就是对保存按钮的点击事件:
var deletejson = "";
var addjson = "[";
var updatejson = "[";
//保存
function _save(){
if(temp == true){
alertF("没有任何修改过的数据,无需保存");
return;
}
if($(".table input[type=text]").val()==""){
return;
}
_clear($(".table input[type=text]"));
//拼接新增的行的json对象
var addtab = $("table").find("tr.addRow");
if(addtab.length>0){
for(var i=0;i<addtab.length;i++){
addjson +=
'{"typename":"' +addtab.eq(i).find("td").html().trim()+ '"},';
}
addjson = addjson.substr(0,addjson.length-1);
addjson += "]";
addjson = eval("("+addjson+")");
}
//拼接修改的行的json对象
var updatetab = $("table").find("tr.updateRow");
if(updatetab.length>0){
for(var i=0;i<updatetab.length;i++){
updatejson += '{"topictype":"'+updatetab.eq(i).find("input[type=hidden]").val()
+ '","typename":"' +updatetab.eq(i).find("td").html().trim()+ '"},';
}
updatejson = updatejson.substr(0,updatejson.length-1);
updatejson += "]";
updatejson = eval("("+updatejson+")");
}
if(deletejson.indexOf(",")==0){
deletejson = deletejson.substr(1,deletejson.length-1);
}
/* $.ajax({
url:url,
type:"post",
dataType:"json",
data:{updateJson:JSON.stringify(eval("("+updatejson+")")),
addJson:JSON.stringify(eval("("+addjson+")")),
deleteJson:deletejson
},
success:function(data){
if(data.responseText == "ok"){
window.location.reload();
}
}
}) */
$.post(url,{updateJson:JSON.stringify(updatejson),
addJson:JSON.stringify(addjson),
deleteJson:deletejson},function(data){
if(data == "ok"){
window.location.reload();
}
});
}
这里因为删除其实where语句可以直接用where id in();所以我们直接在删除就封装好json字符串,不用穿对象过去了;
最后:对数据进行数据库回写
其实也没啥好说的,主要就是事务管理这一块,我们都知道,只要进行了两条以上的数据库修改都应该加上事务,统一commit或者rollback
大部分我们都在service层中都配置了事务管理,但是其实不同的需求会有不同的分析,正如这样的客户需求,我们确实就应该在业务层进行事务管理
对于事务这一块我也不咋会,不过经过百度;我找到一个很好的办法事务管理:
我先贴一下原博主的贴:http://blog.csdn.net/quwenzhe/article/details/60308999
@Resource
private PlatformTransactionManager transactionManager;
/**
* 保存
* @param model
* @param req
* @return
* @throws Exception
*/
@RequestMapping(value="doSave" )
@ResponseBody
public String doSave(Model model,HttpServletRequest req) throws Exception{
DefaultTransactionDefinition defaultTransactionDefinition = new DefaultTransactionDefinition();
defaultTransactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = transactionManager.getTransaction(defaultTransactionDefinition);
try{
String deletejson = req.getParameter("deleteJson");
Object addjson = req.getParameter("addJson");
Object updatejson = req.getParameter("updateJson");
//删除
if(deletejson!=null && deletejson.length()>0){
param = getHashMap();
param.put("ids", deletejson);
commonService.delete("deleteTopicType", param);
}
//修改
if(updatejson!=null && updatejson.toString().startsWith("[")){
List<TopicTypeInfo> list = JSONArray.parseArray(updatejson.toString(), TopicTypeInfo.class);
for(TopicTypeInfo info : list){
topicTypeService.updateTopicType(info);
}
}
//增加
if(addjson!=null && addjson.toString().startsWith("[")){
List<TopicTypeInfo> list = JSONArray.parseArray(addjson.toString(), TopicTypeInfo.class);
for(TopicTypeInfo info : list){
topicTypeService.addTopicType(info);
}
}
transactionManager.commit(status);
}catch(Exception e){
transactionManager.rollback(status);
e.printStackTrace();
}
return "ok";
}