博主初次入行,遇到一个好玩的客户需求,自己用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>


得到一张这样的表(为了方便,我就只贴了一列的表):




java JTable如何调整列宽_java JTable如何调整列宽



然后大概效果(瞎做的gif图,意思意思):



java JTable如何调整列宽_jquery_02



然后就是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层中都配置了事务管理,但是其实不同的需求会有不同的分析,正如这样的客户需求,我们确实就应该在业务层进行事务管理


对于事务这一块我也不咋会,不过经过百度;我找到一个很好的办法事务管理:


我先贴一下原博主的贴:


@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";
	}