EasyUI效果--DataGrid的编辑效果

    DataGrid的编辑效果是我目前使用的easyUI的第三个效果,相对于前两个,这个算是比较复杂点了。
    运行起来的效果,大概就是这样,任意点击某行,然后该行变为可以编辑的,失去焦点之后,该行恢复.点击上面的按钮Append,Remove,Accept,Reject,getChanges可以添加一行,删除一行,保存修改,撤销修改,获取改变的数据.

    之前拿到官网的源码之后,进行测试.开始没细看代码,删了几列数据,包括Product列,就发现只有第一次点击数据会有编辑效果,并且之后不论怎么做都不会恢复到只读的样子.
EasyUI效果--DataGrid的编辑效果_第1张图片
    后来,看代码发现,点击行时,会判断endEditing方法的返回值是否为true.
    分析代码,最开始editIndex编辑索引为undefined,假设我点击了第二行,那么editIndex为1.执行onClickRow()的方法,由于index为1 != undefined,所以执行判断endEditing(结束编辑)的方法是否为true,若结束,则将该选中行(第二行)执行beginEdit方法,并且将editIndex更新为1.若没有结束,则还是选中之前那行.
    而结束编辑方法,先判断editIndex是否为undefined,若是,则直接返回true,表示结束;若不是,假设我之前点击了第二行,然后再点击第三行,则目前是index为2,而editIndex为1.则判断第二行是否为有效行,不是就直接返回false,表示没有结束.否则,需要将该有效行的修改获取到值,其他还好说,但是下拉框需要获取到valueField和textFiled,所以根据valueField值字段,获取到第二行的productid的指定的编辑器ed ,并且获取该下拉框中的值textFiled,将该值赋到productname字段上,最后endEit结束编辑,并设置editIndex为undefined,并且返回true.
    简而言之,该方法的作用就是:结束之前的编辑,只是无效的结束不掉,有效的要先保存下再结束,而第一次选中行,那不管如何都是结束了.
    而删掉Product列之后,由于没有productid,所以ed为null,获取不到该字段的编辑器,然后$(ed.target)就抛异常TypeError: ed is null,执行else,返回false,endEditing不结束,所以就只能有一次编辑效果了.
<script type="text/javascript">
	var editIndex = undefined;
	function endEditing(){
		if (editIndex == undefined){return true}
		if ($('#dg').datagrid('validateRow', editIndex)){
			var ed = $('#dg').datagrid('getEditor', {index:editIndex,field:'productid'});
			var productname = $(ed.target).combobox('getText');
			$('#dg').datagrid('getRows')[editIndex]['productname'] = productname;
			$('#dg').datagrid('endEdit', editIndex);
			editIndex = undefined;
			return true;
		} else {
			return false;
		}
	}
	function onClickRow(index){
		if (editIndex != index){
			if (endEditing()){
				$('#dg').datagrid('selectRow', index)
						.datagrid('beginEdit', index);
				editIndex = index;
			} else {
				$('#dg').datagrid('selectRow', editIndex);
			}
		}
	}
    然后是我的代码,先是html代码,效果是上图一样,只是字段和名字不同.
<!--查询主页面*******start************************************************************************ -->
<div title="查询规则" class="easyui-panel"
	style="padding: 20px; width: 100%">
	<input id="searchtxt" class="easyui-searchbox" style="width: 350px"
		searcher="doSearch" /> <a href="javascript:void(0)"
		class="easyui-linkbutton" data-options="iconCls:'icon-search'"
		onclick="doSearchButton()" style="width: 80px">查询</a>
</div>
<table id="dg" title="规则列表" class="easyui-datagrid"
	url="${pageContext.request.contextPath}/queryPageRule"
	style="width: 100%; height: 450px" toolbar="#toolbar"
	pagination="true" rownumbers="true" fitColumns="true" sortName="sort"
	sortOrder="asc" remoteSort=false singleSelect="true"
	data-options="iconCls: 'icon-edit',onClickRow: onClickRow">
	<thead>
		<tr>
		           <th data-options="field:'id',width:30,hidden:'hidden'">规则id</th>
			<th
				data-options="field:'rule',width:30,
					formatter:function(value,row){
						return row.rule;
					},
					editor:{
						type:'combobox',
						options:{
							valueField:'rule',
							textField:'rule',
							url:'rule1.json', 
							method:'get',
						    required:true
						}
					}">规则</th>
			<th
				data-options="field:'type',width:30,
 						formatter:function(value,row){  
  							return row.type;  
 						}, 
  						editor:{  
						type:'combobox',
						options:{
							valueField:'type',
							textField:'type',
							method:'get',
							url:'ruleType.json',
							required:true
							
						}
					}">类型</th>


			<th data-options="field:'sort',align:'right',width:30">优先级</th>
			<th
				data-options="field:'startIndex',width:30,align:'right',editor:{type:'numberbox'}">起始位置</th>
			<th
				data-options="field:'length',width:30,align:'right',editor:{type:'numberbox'}">长度</th>
			<th
				data-options="field:'realLength',width:30,align:'right',editor:{type:'numberbox'}">原长度</th>
			<th data-options="field:'result',width:30,editor:'text'">效果</th>
			<th
				data-options="field:'isValid',formatter:formatValid,width:20,align:'center',editor:{type:'checkbox',options:{on:'启用',off:'停用'}}">是否启用</th>


		</tr>
	</thead>
</table>
<div id="toolbar" width="50">
	<a href="javascript:void(0)" class="easyui-linkbutton"
		data-options="iconCls:'icon-add',plain:true" onclick="append()">添加</a>
	<a href="javascript:void(0)" class="easyui-linkbutton"
		data-options="iconCls:'icon-remove',plain:true" onclick="removeit()">删除</a>
	<a href="javascript:void(0)" class="easyui-linkbutton"
		data-options="iconCls:'icon-edit',plain:true" onclick="MoveUp()">上移</a>
	<a href="javascript:void(0)" class="easyui-linkbutton"
		data-options="iconCls:'icon-edit',plain:true" onclick="MoveDown()">下移</a>
	<a href="javascript:void(0)" class="easyui-linkbutton"
		data-options="iconCls:'icon-save',plain:true" onclick="accept()">保存</a>
	<a href="javascript:void(0)" class="easyui-linkbutton"
		data-options="iconCls:'icon-undo',plain:true" onclick="reject()">撤销</a>
	<a href="javascript:void(0)" class="easyui-linkbutton"
		data-options="iconCls:'icon-undo',plain:true" onclick="saveUpDow()">保存优先级</a>


</div>
<!--查询主页面*******end************************************************************************ -->
    主要是这样的,首先规则和类型列都是下拉框列,优先级列不议不可编辑;起始位置,长度和原长度的编辑器都是可编辑的数字框,效果是文本框,而是否启用显示的是中文"启用","停用".而按钮,除了正常的添加,删除,保存和撤销,还有上移和下移,以及保存优先级,这三个按钮是用来处理优先级的.
    其中,添加方法,就是在结束之前的编辑之后,添加一行,其中isValid行设置默认为"启用",而sort优先级和该表的数据行数一样.而editIndex编辑索引,假设现在有8行,再加一行为9行,则sort为9.appendRow执行完之后,datagrid就是9条数据了,而编辑索引应该为8.
function append() {
	if (endEditing()) {
		$('#dg').datagrid('appendRow', {
			isValid : '启用',
			sort:$('#dg').datagrid('getRows').length + 1,
		});
		editIndex = $('#dg').datagrid('getRows').length - 1;
		$('#dg').datagrid('selectRow', editIndex).datagrid('beginEdit',
				editIndex);
	}
}
    移除一行,先选中一行,然后取消对该行的编辑,然后删了该行,并将编辑索引清了.
function removeit() {
	if (editIndex == undefined) {
		return
	}
	$('#dg').datagrid('cancelEdit', editIndex).datagrid('deleteRow',
			editIndex);
	editIndex = undefined;
}
    撤销修改,则将所有没有保存的数据,进行还原.
function reject() {
	$('#dg').datagrid('rejectChanges'); 
	editIndex = undefined;
}
    而提交数据,将之前修改的结果进行持久化保存.还是先结束之前的编辑,然后获取到所有修改,添加,删除和修改的.将所有修改中的isValid的启用改为true,因为后台该字段为boolean类型.并将所有的添加,删除和修改的结果都用JSON.stringify处理,将数据通过Contoller处理,最后用acceptChanges提交所有修改.
function accept() {
	if (endEditing()) { 
                //利用easyui控件本身的getChange获取新添加,删除,和修改的内容  
                if ($("#dg").datagrid('getChanges').length) {  
                    var inserted = $("#dg").datagrid('getChanges', "inserted");  
                    var deleted = $("#dg").datagrid('getChanges', "deleted");  
                    var updated = $("#dg").datagrid('getChanges', "updated");
                
                    var effectRow = new Object();  
                    if (inserted.length) { 
                    	inserted.forEach(function(e){  
                    		if(e.isValid == "启用") {
                        		e.isValid = true;
                        	}else {
                        		e.isValid = false;
                        	} 
                    	})  
                        effectRow["inserted"] = JSON.stringify(inserted);  
                    }  
                    if (deleted.length) {  
                    	deleted.forEach(function(e){  
                    		if(e.isValid == "启用") {
                        		e.isValid = true;
                        	}else {
                        		e.isValid = false;
                        	} 
                    	})  
                        effectRow["deleted"] = JSON.stringify(deleted);  
                    }  
                    if (updated.length) {  
                    	updated.forEach(function(e){  
                    		if(e.isValid == "启用") {
                        		e.isValid = true;
                        	}else {
                        		e.isValid = false;
                        	} 
                    	})  
                    	
                        effectRow["updated"] = JSON.stringify(updated);  
                    } 
                    $.post("${pageContext.request.contextPath}/add", effectRow, function(rsp) {
                        if(rsp.status){
                            $.messager.alert("提示", "提交成功!");
                            $dg.datagrid('acceptChanges');
                        }
                    }, "JSON").error(function() {
                        $.messager.alert("提示", "提交错误!");
                    });
              
                 }else {
                	 var updown = $("#dg").datagrid('getData');
                	 if (updown.length) {  
                		 updown.forEach(function(e){  
                     		if(e.isValid == "启用") {
                         		e.isValid = true;
                         	}else {
                         		e.isValid = false;
                         	} 
                     	})  
                	 $.post("${pageContext.request.contextPath}/add", function(rsp) {
                         if(rsp.status){
                             $.messager.alert("提示", "提交成功!");
                             $dg.datagrid('acceptChanges');
                         }
                     }, "JSON").error(function() {
                         $.messager.alert("提示", "提交错误!");
                     });
                 }
			}
		}
	}
    而对于优先级的修改,是这样处理的.上移和下移按钮分别执行MoveUp和MoveDown方法,获取到当前选中行,以及该行的索引,执行mysort方法,传入当前行的索引,以及'up'指令,以及对应的datagrid名.同理moveDown一样,只是指令为'down'.
//上移
function MoveUp() {
	var row = $("#dg").datagrid('getSelected'); 
	var index = $("#dg").datagrid('getRowIndex', row);
	mysort(index, 'up', 'dg'); 
	editIndex = undefined;
}
//下移
function MoveDown() {
	var row = $("#dg").datagrid('getSelected');
	var index = $("#dg").datagrid('getRowIndex', row);
	mysort(index, 'down', 'dg');	
	editIndex = undefined;
}
    而mysort方法,是这样处理的,若为up,则根据传入的index和datagrid的名字获取到本行以及上一行的数据,将本行和上一行的数据进行交换,并且刷新,然后还是选中之前的行.而优先级的值,是和行号保持一致的.down同理.
function mysort(index, type, gridname) {
	if ("up" == type) {
		if (index != 0) {
			//本行
			var toup = $('#' + gridname).datagrid('getData').rows[index];
			//上一行
			var todown = $('#' + gridname).datagrid('getData').rows[index - 1];
			//本行的sort-1,本行的上一行的sort+1 (如8(index为7),上移为7;则原来的7,变为8)
			toup.sort = index;
			todown.sort = index+1;
			$('#' + gridname).datagrid('getData').rows[index] = todown;
			$('#' + gridname).datagrid('getData').rows[index - 1] = toup;
			$('#' + gridname).datagrid('refreshRow', index);
			$('#' + gridname).datagrid('refreshRow', index - 1);
			$('#' + gridname).datagrid('selectRow', index - 1);
		}
	} else if ("down" == type) {
		var rows = $('#' + gridname).datagrid('getRows').length;
		if (index != rows - 1) {
			//本行
			var todown = $('#' + gridname).datagrid('getData').rows[index];
			//下一行
			var toup = $('#' + gridname).datagrid('getData').rows[index + 1];
			//本行的sort+1,本行的上一行的sort-1 (如8(index为7),下移为9;则原来的9,变为8)
			toup.sort = index + 1;
			todown.sort = index + 2;
			$('#' + gridname).datagrid('getData').rows[index + 1] = todown;
			$('#' + gridname).datagrid('getData').rows[index] = toup;
			$('#' + gridname).datagrid('refreshRow', index);
			$('#' + gridname).datagrid('refreshRow', index + 1);
			$('#' + gridname).datagrid('selectRow', index + 1);
		}
	}


}<span style="font-family: KaiTi_GB2312; background-color: rgb(255, 255, 255);">		</span>
   而保存就是将所有的数据都获取到,进行保存.
   后台contoller中如何处理数据?将数据传到后台后,从request获取到值,用JsonUntils的fromJson方法将数据从json转为实体list.然后更新实体list.
/**
 * 添加规则
 *
 * @param rule
 * @param response
 */
@RequestMapping("/add")
public void addRule(Rule rule, Object effectRow, HttpServletRequest request, HttpServletResponse response) {
	logger.info("Controller开始执行添加规则的方法");
	// 获取编辑数据 这里获取到的是json字符串
		  String updown = request.getParameter("updown");
				  boolean flagUpdown = false;

	if (updown != null) {
		listUpdown = (List<Rule>) JsonUtils.fromJson(updown, new TypeToken<List<Rule>>() {
		}.getType());
		flagUpdated = ruleBean.updateEntitys(listUpdown);
	}


	try {
		try {
			jacksonJsonUntil.BeanToJson(response, flagUpdown);
		} catch (Exception e) {
			e.printStackTrace();
		}
	} catch (Exception e) {
		logger.error("Controller的添加规则失败", e);
		throw e;
	}


	logger.info("Controller执行完成添加规则的方法");
}
    以上就是我做的DataGrid编辑效果,主要了解原理,以及做了一个优先级的修改.到目前为止,我使用的easyUI效果就介绍完了.

你可能感兴趣的:(EasyUI效果--DataGrid的编辑效果)