六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 30|回复: 0

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

[复制链接]

升级  36%

2

主题

2

主题

2

主题

童生

Rank: 1

积分
18
 楼主| 发表于 2013-1-29 11:42:51 | 显示全部楼层 |阅读模式
项目中需要一个可编辑表格控件,不能用一些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.defaultValue) {de = op.column.defaultValue;newdefault[op.column.name] = de;font = getfont(td, de);td.appendChild(font);} else {font = getfont(td, "请修改数据");newdefault[op.column.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.cells.length; c++) {if (BaseJs.isContain(c, merge)) {for (j = i + 1; j < table.rows.length; j++) {var cell1 = table.rows.cells[c].innerHTML;var cell2 = table.rows[j].cells[c].innerHTML;if (cell1 == cell2) {table.rows[j].cells[c].style.display = 'none';table.rows.cells[c].rowSpan++;} elsebreak;}}}}},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;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.editorType;// 得到原来的内容var oldText = BaseJs.text(target);// 清空原内容BaseJs.empty(target);// 设置默认类型为textedittype = 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.cols ? columns.cols : 30;rows = columns.rows ? columns.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.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.dataUrl.constructor == Function? column.dataUrl(target): column.dataUrl;if(column.data){data = BaseJs.decode(column.data);me.html = "<select name='editText'>";for (var i = 0; i < data.length; i++) {me.html += "<option value="+ data.value + " display="+data.display+">"+ data.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.value + " display="+data.display+">"+ data.display+"</option>";}me.html += "</select>";},failure : function(data, res) {alert(data);me.isLoad = false;},isATM : false}, this);               }}if (!this.isLoad) {alert("加载数据有错,有稍后再试!");return;}// 注入htmlvar 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;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;// // 保存关键idmod(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;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>
交互编辑表格简单示例...
<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;  trs.onclick = function(){   if (tr.selected){     tr.style.background = "#FAFCFE";     tr.selected = false;      for(i=0;i<selectedRow.length;i++){      if(selectedRow == 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.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 可用函数返回动态urlurl : 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-MMformat : 'yyyy年MM月份',//自定义默认值defaultValue : BaseJs.Utils.format.date(new Date(), 'yyyy年MM月份')}]}); </script></body></html>

源代码在下载的文件里,有什么不合理或错误的地方请大家指出,一起学习!!
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表