`
tianzizhi
  • 浏览: 15077 次
  • 性别: Icon_minigender_1
  • 来自: 南京
文章分类
社区版块
存档分类
最新评论

原创-javascript服务器交互型可编辑表格

阅读更多
   项目中需要一个可编辑表格控件,不能用一些js库,在网上搜索了一下,没有符合要求的,不是太简单就是没有和服务器通信的,自己花了一些时间写了符合条件的可编辑表格,在ie里测试正确,并把它放到我的常用js库中,特此分享一下,希望对一些朋友有帮助,有可以改进的地方大家一起提出和修改!!


BaseJs.EditTable = function(op) {
	op = {
		// 激活方法
		active : op.active || "ondblclick",
		table : op.table || {},
		// 从第几行第几列开始可编辑
		start : op.start || [2, 1],
		// 到哪一行哪一列结束编辑
		end : op.end || [],
		// 表头对象
		column : op.column || [],// 
		// 新增按钮
		add : op.addAction || {},
		// 保存按钮
		save : op.saveOrUpdateAction || {},
		// 删除按钮
		del : op.delAction || {},
		// id名
		primaryKey : op.primaryKey,
		// 合并的列数
		mergeColumn : op.mergeColumn || []

	};

	// 修改后的记录集合
	modified = [];
	// 添加新记录
	if (op.add.button)
		op.add.button.onclick = function(e) {

			var tr = op.table.insertRow(1);

			function getfont(td, v) {
				var font = document.createElement("font");
				BaseJs.element.resetCss(td, {
							color : 'red'
						});
				var textNode = document.createTextNode(v);
				font.appendChild(textNode);
				return font;
			};
			newdefault = {};
			newdefault["newKey"] = BaseJs.random(1, 1, 9999999)[0];

			for (var i = 0; i < op.column.length; i++) {
				td = tr.insertCell(i);

				tr.newid = newdefault["newKey"];
				BaseJs.attr(td, "align", "center");
				if (op.column[i].defaultValue) {
					de = op.column[i].defaultValue;
					newdefault[op.column[i].name] = de;
					font = getfont(td, de);
					td.appendChild(font);
				} else {
					font = getfont(td, "请修改数据");
					newdefault[op.column[i].name] = "请修改数据";
					td.appendChild(font);
				}

			}
			op.start = [2, 1];
			op.end = [2, op.column.length];
			modified.push(newdefault);

			BaseJs.EditTable.prototype.init(op);
			if (op.add.callback)
				op.add.callback.call(this, tr);

		};

	// 删除一条记录
	if (op.del.button)
		op.del.button.onclick = function(e) {
			is = confirm("确认删除选择的记录吗?");
			if(op.del.beforeCallback){
				  if(!op.del.beforeCallback.call(this)){
				  	 return;
				  	};
				}
			delurl = (op.del.url.constructor == Function ? op.del
					.url(op.del.button) : op.del.url);
			if (!delurl) {
				return;
			}
			if (is) {
				BaseJs.Ajax.open({
							url : delurl,
							success : function(data) {
								alert(data);
								if (op.del.afterCallback)
									op.del.afterCallback.call(this);
							},
							failure : function(data) {
								alert(data);
							}
						});
			}

		}

	// 保存修改
	if (op.save.button)
		op.save.button.onclick = function(e) {
			is = confirm("是否确认保存当前修改?");
			if(op.save.beforeCallback){
				  if(!op.save.beforeCallback.call(this,modified)){
				  	 return;
				  	};
				}
			if (!is) {
				return;
			}
			modifiedData = BaseJs.encode(modified);
			saveurl = (op.save.url.constructor == Function
					? op.save.url()
					: op.save.url);
			if (!saveurl)
				return;
			BaseJs.Ajax.open({
				url : saveurl,
				params : {
					data : modifiedData
				},
				success : function(data, xml, opu, scope) {
					// alert("data:" + xml.responseText);
					BaseJs.foreach(modified, function(d) {
								// 查找行去掉标记颜色
								key = op.primaryKey;
								id = BaseJs.isEmpty(d[key])
										? d["newKey"]
										: d[key];
								BaseJs.foreach(op.table.rows, function(row) {
											index = (BaseJs.isEmpty(row.id)
													? row.newid
													: row.id);
											if (id == index) {
												BaseJs.foreach(row.cells,
														function(cell) {
															BaseJs.element
																	.resetCss(
																			cell,
																			{
																				color : 'black'
																			})
														}, this);

											}

										}, this)
							}, scope);

					alert(data);
			(function() {
						modified = [];
					}).call(scope);

					if (op.save.afterCallback)
						op.save.afterCallback.call(this, modifiedData);

				},
				failuer : function(data, xml, op, scope) {
					alert(data);
				}
			}, this);

		};
	// 初始化表格
	this.init.call(this, op);

	// 合并列
	table = op.table;
	merge = op.mergeColumn;
	if (merge.length != 0)
		this.merge(table, merge);

	// 其它操作
}

BaseJs.EditTable.prototype = function() {

	return {
		// 计算开始结束序列号
		getStartEnd : function(op, length, tds) {
			var start = length * (op.start[0] - 1);
			if (op.end.length == 0) {
				nop = [0, length];
				end = tds.length;
			} else if (op.end.length == 1) {
				nop = [0, op.end[0]]
				end = tds.length
			} else if (op.end.length == 2) {
				nop = [op.end[0], op.end[1]];
				end = length * (op.end[0]);
			}
			return [start, end, nop];
		},
		// 合并表格 merge=要合并的列数数组,如[0,1]第一列和第二列执行合并操作
		merge : function(table, merge) {
			for (i = 0; i < table.rows.length; i++) {
				for (c = 0; c < table.rows[i].cells.length; c++) {
					if (BaseJs.isContain(c, merge)) {
						for (j = i + 1; j < table.rows.length; j++) {
							var cell1 = table.rows[i].cells[c].innerHTML;
							var cell2 = table.rows[j].cells[c].innerHTML;
							if (cell1 == cell2) {
								table.rows[j].cells[c].style.display = 'none';
								table.rows[i].cells[c].rowSpan++;
							} else
								break;
						}
					}
				}
			}
		},
		init : function(op) {

			var tds = BaseJs.getByTagName("td", op.table);

			var length = op.column.length;

			var se = this.getStartEnd(op, length, tds);

			for (var i = se[0]; i < se[1]; i++) {

				var cols = (i % length) + 1;

				if (op.start[1] && se[2][1]
						&& (cols < op.start[1] || cols > se[2][1])) {

					continue;
				}

				(function() {
					var td = tds[i];
					var seq = i;
					// 设置当前td序列号
					var column = op.column;

					tdEvent = function(e) {
						// 得到目标对象
						var target = (BaseJs.isIE ? e.srcElement : e.target);
						// 计算当前td所处editorType值
						var s = (seq) % length;

						edittype = column[s].editorType;

						// 得到原来的内容
						var oldText = BaseJs.text(target);
						// 清空原内容
						BaseJs.empty(target);
						// 设置默认类型为text
						edittype = BaseJs.isEmpty(edittype) ? "text" : edittype;
						this.html = "";
						this.isLoad = true;
						if (edittype == "text") {

							this.html = "<input type='text' name='editText' id=seq value="
									+ oldText + ">";
							this.isLoad = true;
						} else if (edittype == "textarea") {
							cols = columns[s].cols ? columns[s].cols : 30;
							rows = columns[s].rows ? columns[s].rows : 3;
							this.html = "<textarea name='editText' id=seq value="
									+ oldText
									+ " cols="
									+ cols
									+ " rows="
									+ rows + "></textarea>";
							this.isLoad = true;
						} else if (edittype == "date") {
							// 格式化日期
							var format = column[s].format;
							format = (format ? format : "yyyy-MM-dd");
							this.html = "<input type='text' name='editText' id=seq value="
									+ oldText
									+ "  onclick=getDateString(this,oCalendarChs,'"
									+ format + "')>";
							this.isLoad = true;
						} else if (edittype == "select") {
							var me = this;
							dataUrl = column[s].dataUrl.constructor == Function
									? column[s].dataUrl(target)
									: column[s].dataUrl;
						
							if(column[s].data){
								data = BaseJs.decode(column[s].data);
											me.html = "<select name='editText'>";
											for (var i = 0; i < data.length; i++) {
												me.html += "<option value="
														+ data[i].value + " display="+data[i].display+">"
														+ data[i].display+"</option>";
											}
											me.html += "</select>";
								}else{	
							// 加载远程数据
							BaseJs.Ajax.open({
										url : dataUrl,
										success : function(data, res, op, me) {
											data = BaseJs.decode(data);
											me.html = "<select name='editText'>";
											for (var i = 0; i < data.length; i++) {
												me.html += "<option value="
														+ data[i].value + " display="+data[i].display+">"
														+ data[i].display+"</option>";
											}
											me.html += "</select>";
										},
										failure : function(data, res) {
											alert(data);
											me.isLoad = false;

										},
										isATM : false

									}, this);
               }
						}
						if (!this.isLoad) {
							alert("加载数据有错,有稍后再试!");
							return;
						}

						// 注入html
						var newObj = BaseJs.element.htmlUtil.append(target,
								this.html);

						newObj = newObj.length ? newObj[0] : newObj;

						BaseJs.element.resetCss(newObj, {
									color : 'green'
								});

						newObj.focus();
						newObj.click();

						var action = (edittype == "date"
								? "onchange"
								: "onblur");

						(function() {
							curcolumn = column[s];
							BaseJs.addEvent(newObj, action, function(e) {
								var target = (BaseJs.isIE
										? e.srcElement
										: e.target);
								// 得到对象
								var s = target;
								// 得到新值
								var newText = s.value;
								if(s.tagName.toLowerCase() == "select"){
									BaseJs.foreach(s.options,function(op){
										 if (op.selected){
										 	 newText = {display:op.display,value:op.value};
										 	}
										})
									}
									
								// 检验所输入
								if (curcolumn.validate) {
									var is = curcolumn.validate(newText, s);
									if (!is) {
										s.focus();
										return;
									};
								};

								var parent = s.parentNode;
								parents = parent;
								do {
									parents = parents.parentNode;
									if (parents.tagName) {
										tag = parents.tagName;
									} else {
										tag = "";
									}
								} while (tag.toLowerCase() != "tr");

								// 保存修改

								var name = curcolumn.name; // 得到当前字段名
								var obj = {};

								if (parents.newid) {
									obj['newKey'] = parents.newid;
									mod('newKey');
								} else if (parents.id) {
									obj[op.primaryKey] = parents.id;// // 保存关键id
									mod(op.primaryKey);
								}

								function mod(key) {
									obj[name] = newText.value?newText.value:newText; // 保存修改的字段
									iscon = false; // 是否已保存该记录
									index = 0;// 如何已修改的集合里有当前记录,保存其在modified中的索引号
									for (var i = 0; i < modified.length; i++) {
										mod = modified[i];
										if (mod[key] == obj[key]) {
											iscon = true;
											index = i
										};
									}
									if (!iscon) {
										modified.push(obj);
									} else {
										modified[index][name] = newText.value?newText.value:newText;
									}
								}

								// 删除编辑框
								parent.removeChild(s);
								// 创建文本
								var font = document.createElement("font");

								color = (oldText == newText ? "" : "red");

								BaseJs.element.resetCss(parent, {
											color : color
										});
								var textNode = document.createTextNode(newText.value?newText.display:newText);

								font.appendChild(textNode);
								// 插入文本
								parent.appendChild(font);
									// 待解决问题
									// 9 表格修饰
							});

						})();
					};

					BaseJs.addEvent(td, op.active, tdEvent, this);

				})();

			}
		}

	};

}();

基本用法如下:
   <html>
<head>
		<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
		<title>内页面</title>
	 <script src="BaseJs.js" type="text/javascript"></script>
	<script src="Calendar0.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
		 [align=center]交互编辑表格简单示例...[/align]
		<form>
				<input type="button" value="新增" id="add"/>
					<input type="button" value="删除" id="delete"/>
						<input type="button" value="保存修改" id="save"/>
				      <input type="hidden" id="mid"/>
		<table width="80%" border="1" id="tab">
        <tr align="center">
        	     
                <td>年</th>
                <td>com域名的数量</th>
                <td>cn域名的数量</th>
                <td>日期</th>
        </tr>
        <tr id="1" align="center">
        	     
                <td>2003年</td>
                <td>1000</td>
                <td>2000</td>
                <td>2003年12月份</td>
        </tr>
        <tr id="2" align="center">
        	
                <td>2004年</td>
                <td>4000</td>
                <td>5000</td>
                <td>2004年12月份</td>
        </tr>
        <tr id="3" align="center">
        	
                <td>2005年</td>
                <td>7000</td>
                <td>8000</td>
                <td>2005年12月份</td>
        </tr>
</table>
</form>
<script type="text/javascript">
	
	         selectedRow = [];
	         //设置行选中状态
						var trs = BaseJs.getByTagName("tr",BaseJs.$("tab"));
						for (var i = 0; i < trs.length; i++) {
							 (function(){
							 	var tr = trs[i];
							 	 trs[i].onclick = function(){
							 	 	 if (tr.selected){
							 	 	 	  tr.style.background = "#FAFCFE";
							 	 	 	  tr.selected = false;
							 	 	 	   for(i=0;i<selectedRow.length;i++){
							 	 	 	   	if(selectedRow[i] == tr.id){
							 	 	 	   		 selectedRow.splice(i,1);
							 	 	 	   		}
							 	 	 	   };
							 	 	 		 BaseJs.$("mid").value = selectedRow.join(",");
							 	 	 	}else{
							 	 	 		 tr.style.background = '#B8CCF0';
							 	 	 		 tr.selected = true;
							 	 	 		 selectedRow.push(tr.id);
							 	 	 		 BaseJs.$("mid").value = selectedRow.join(",");
							 	 	 		}
							 	 	}
							 	})();
						}
						
	
	table = new BaseJs.EditTable({
			// 表对象
			table : BaseJs.$("tab"),
			// 从第几行第几列开始可编辑
			start : [2, 1],
			// 到哪一行哪一列结束编辑 不写默认所有,写一个参数代表列,行不限
			end : [],
			// 新增操作
			addAction : {
				// (button)执行操作的按钮,
				button : BaseJs.$('add'),
				// callback:执行操作后的回调函数,能够加入一些自定义操作
				callback : function(tr) {
					tr.onclick = function() {
						var trs = BaseJs.getByTagName("tr",BaseJs.$("tab"));
						for (var i = 0; i < trs.length; i++) {
							trs[i].style.background = '#FAFCFE';
						}
						tr.style.background = '#B8CCF0';
					}
				}
			},
			// 保存新增或更新操作
			saveOrUpdateAction : {
				button : BaseJs.$('save'),
				// 提交更新url,后台取参数data,为json字符串
				url : 'saveOrUpdateActionUrl',
				//返回true执行保存操作
				beforeCallback:function(data){
					 alert("提交给后台url:saveOrUpdateActionUrl?data="+BaseJs.encode(data));
					 return false;
					},
				afterCallback : function(mo) {
					alert("提交修改后的数据:"+mo);
					//document.location.reload();
				}
			},
			// 删除操作
			delAction : {
				button : BaseJs.$('delete'),
				// 删除url 可用函数返回动态url
				url : function() {
					return 'delActionUrl&mid='
							+ document.getElementById("mid").value;
				},
				//返回true执行删除操作
					beforeCallback:function(){
					 alert("提交给后台url:delActionUrl?sids="+document.getElementById("mid").value);
					 return false;
					},
				afterCallback : function() {
					document.location.reload();
				}
			},
			// id名(记录的id值需要保存在tr.id上)
			primaryKey : 'id',
			// 要全并的列数集合 [0]代表第一列要执行合并操作,[0,1]代表1,2列有合并操作
			mergeColumn : [],
			// 列描述对象 ,包含一个数组,数组中每一个对象说明一个列编辑对象和相关处理
			column : [
			 {
				name : 'year',
				// 选择型
				editorType : 'select',
				// 加载select数据url,返回json数据,格式应为:[{display:'',value:''},{display:'',value:''}]
				dataUrl : 'WaterQualityAction?method=AjaxSelect&para=LEVEL',
				//可以动态返回
				//dataUrl : function(me){
				//  return  'WaterQualityAction?method=AjaxSelect&para=LEVEL';
				//},
				//本地数据 有此选项时dataUrl无效
				data:"[{display:'2005年',value:'2005'},{display:'2004年',value:'2004'},{display:'2003年',value:'2003'},{display:'2002年',value:'2002'},{display:'2001年',value:'2001'}]",		
				// 新增默认值,不写使用默认
				defaultValue : '2008年',
				// 检验输入数据正确性,返回true通过验证
				validate : function(v, obj) {
					alert("现在检验输入数据合法性!");
					return true;
				}
			},
					 {
				name : 'com',
				editorType : 'text',
				defaultValue : '请输入',
				validate : function(v, obj) {
					if (!/^[0-9]+$/.test(v)){alert("必须是数字");return false};
					return true;
				}
			},
			{
				name : 'cn',
				editorType : 'text',
				defaultValue : '请输入',
				validate : function(v, obj) {
				if (!/^[0-9]+$/.test(v)){alert("必须是数字");return false};
					return true;
				}
			}, {
				name : 'date_month',
				// 日期型
				editorType : 'date',
				// 格式化日期样式,默认yyyy-MM
				format : 'yyyy年MM月份',
				//自定义默认值
				defaultValue : BaseJs.Utils.format
						.date(new Date(), 'yyyy年MM月份')
			}]
		});
 
	</script>
		</body>
	</html>


源代码在下载的文件里,有什么不合理或错误的地方请大家指出,一起学习!!
分享到:
评论

相关推荐

    原创-javascript服务器交互型可编辑表格和我的js常用库

    自己常用的js库和写的一个交互型可编辑表格: BaseJs库的一点源码: /** * 自定义javascript常用基础库 author zhang_jhai 创建时间 2010/04/10 最后修改时间 2010/05/03 * version 2.0 */ // Base库基础类 BaseJs ...

    javascript服务器交互型可编辑表格和js常用库

    自己常用的js库和写的一个交互型可编辑表格: new BaseJs.EditTable({ // 表对象 table : BaseJs.$("tab"), // 从第几行第几列开始可编辑 start : [2, 1], // 到哪一行哪一列结束编辑 不写默认所有,写一个...

    javascript可编辑的表格

    总的来说,JavaScript可编辑表格是Web开发中的一个核心技能,涉及前端多个方面,包括DOM操作、事件处理、数据交互和用户体验。理解并掌握这些知识点,对于构建高效、易用的数据管理界面至关重要。

    JQuery实现可编辑的表格

    这些特性为我们提供了构建可编辑表格的基础。 1. **选择器**:在jQuery中,我们可以使用CSS选择器快速定位到表格元素,如`$('table tr td')`会选取表格中的所有单元格。通过选择器,我们可以针对特定行、列或单元格...

    JavaScript实现在线编辑表格

    JavaScript是一种广泛应用于...5. 可选地,使用AJAX与服务器交互,或者利用JavaScript库提升功能和性能。 以上就是使用JavaScript实现在线编辑表格的基本原理和实践方法,希望对你在Web开发中实现类似功能有所帮助。

    jquery easy ui edatagrid 动态编辑表格 例子

    在本文中,我们将深入探讨jQuery Easy UI中的`edatagrid`组件,以及如何实现动态编辑表格,特别是下拉框的联动功能。`edatagrid`是jQuery Easy UI库中的一个强大工具,它扩展了基本的`datagrid`功能,提供了更丰富的...

    backbone学习例子-可编辑的表格

    在可编辑表格的场景下,集合可能是整个表格的数据源,它可以管理模型的添加、删除和排序,并且可以监听模型的变化。 3. **视图(View)**:视图负责渲染模型的数据到DOM,并响应用户的交互。在这个例子中,每个视图...

    Jquery 可编辑的表格

    为了提升用户体验,可编辑表格的样式和交互设计也非常重要。使用CSS可以定制表格的样式,如边框、颜色、字体等。同时,可以通过jQuery响应式设计确保表格在不同设备上的显示效果。 综上所述,构建一个jQuery可编辑...

    EditTable可编辑表格

    "EditTable可编辑表格"是一种专门用于数据展示和编辑的前端组件,常见于网页应用中。这个组件允许用户直接在表格内对数据进行增删改查操作,极大地提高了数据处理的效率和用户体验。下面我们将详细探讨EditTable的...

    vuedatagrid利用Vuejs实现复杂可交互表格的一个例子

    在本文中,我们将深入探讨如何使用Vue.js框架创建一个复杂的、具有交互性的表格——vue-data-grid。Vue.js是一个流行的轻量级JavaScript库,它提供了一种声明式、组件化的方式来构建用户界面。Vue-data-grid是基于...

    SlickGrid一个闪电快速JavaScript网格电子表格

    在JavaScript开发中,表格和网格组件通常是必不可少的,因为它们能够有效地组织和展示数据。SlickGrid的独特之处在于它的性能优化。由于JavaScript在浏览器环境中运行,内存和计算资源有限,所以处理成千上万条记录...

    jquery grid插件 -- 编辑表格

    本文将深入探讨`jQuery Grid`的使用方法及其在编辑表格中的应用。 首先,`jQuery Grid`基于`jQuery`库,所以使用前需确保页面已引入`jQuery`。然后,我们需要引入`jQuery Grid`的核心库,通常是`jquery.jqGrid.min....

    表格内编辑插件 x-editable 下载

    - **性能优化**:如果页面中可编辑的元素很多,可以考虑延迟加载 x-editable,或者只在需要时动态启用编辑功能。 总之,x-editable 是一个强大的前端工具,它使得在网页中进行表格内编辑变得简单而直观。无论是小型...

    PHP+Ajax+Mysql+jeditable无刷新编辑表格

    本文将深入探讨如何使用PHP、Ajax、MySQL和jEditable技术实现一个无刷新编辑表格的功能,从而提高用户体验并减少服务器负载。 首先,让我们了解一下这四个技术的核心概念: 1. **PHP (Hypertext Preprocessor)**: ...

    jQuery网页版excel表格代码.zip

    通过JavaScript,这些数据可以从服务器获取或者本地读取,然后加载到表格中,形成可编辑的单元格。 **表格编辑操作**:jQuery网页版Excel表格代码提供了对表格的编辑功能,用户可以添加、删除或修改单元格的内容,...

    ActiveWidgets 比较好用的javascript 表格

    ActiveWidgets 是一个强大的JavaScript库,专门用于创建高性能、交互式的用户界面,特别是在处理表格和数据展示方面表现出色。这个库以其高效、灵活和易于使用的特性,深受开发者的喜爱。在本文中,我们将深入探讨...

    纯javascript文本编辑器

    6. **可扩展性**:可以通过插件系统或自定义函数扩展编辑器功能,例如添加代码高亮、表格工具、公式编辑等。 在给定的压缩包文件中,我们可以看到以下几个关键文件和目录: - **readme.html**:通常包含项目说明、...

    可编辑的列表视图

    这种交互模式在许多应用中都非常实用,例如在线表格、任务管理器或者联系人管理应用。下面将详细讨论可编辑的列表视图及其在项目开发中的应用。 首先,我们需要理解列表视图(ListView)的基本概念。列表视图是一种...

    WEB表格控件 DateTables

    3. **扩展功能**:包括行选择(单选或多选)、行编辑、服务器端处理(数据的获取和处理不在客户端而是在服务器端进行)、AJAX数据加载、响应式布局(适应不同设备屏幕尺寸)。 4. **插件与API**:DataTables拥有...

Global site tag (gtag.js) - Google Analytics