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 || [1] }; // 修改后的记录集合 modified = []; // 添加新记录 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); }; // 删除一条记录 op.del.button.onclick = function(e) { is = confirm("确认删除选择的记录吗?"); delurl = (op.del.url.constructor == Function ? op.del .url(op.del.button) : op.del.url); if (is) { BaseJs.Ajax.open({ url : delurl, success : function(data) { alert(data); if (op.del.callback) op.del.callback.call(this); }, failure : function(data) { alert(data); } }); } } // 保存修改 op.save.button.onclick = function(e) { is = confirm("是否确认保存当前修改?"); if (!is) { return; } modifiedData = BaseJs.encode(modified); saveurl = (op.save.url.constructor == Function ? op.save.url() : op.save.url); 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.callback) op.save.callback.call(this, modifiedData); }, failuer : function(data, xml, op, scope) { alert(data); } }, this); }; // 初始化表格 this.init.call(this, op); // 合并列 table = op.table; merge = op.mergeColumn; BaseJs.EditTable.prototype.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 == "date") { // 格式化日期 var format = column[s].format; format = (format ? format : "yyyy-MM-dd"); this.html = "<input type='text' name='editText' id=seq value=" + oldText + " οnclick=getDateString(this,oCalendarChs,'" + format + "')>"; this.isLoad = true; } else if (edittype == "select") { var me = this; // 加载远程数据 BaseJs.Ajax.open({ url : column[s].dataUrl.constructor == Function ? column[s].dataUrl(target) : column[s].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 + ">" + data[i].display; } 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 (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; // 保存修改的字段 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; } } // 删除编辑框 parent.removeChild(s); // 创建文本 var font = document.createElement("font"); color = (oldText == newText ? "" : "red"); BaseJs.element.resetCss(parent, { color : color }); var textNode = document.createTextNode(newText); font.appendChild(textNode); // 插入文本 parent.appendChild(font); }); })(); }; BaseJs.addEvent(td, op.active, tdEvent, this); })(); } } }; }(); 基本用法如下: var buttons = BaseJs.getByTagName("img"); for (var i=0;i<buttons.length;i++){ src = buttons[i].src; if(src.indexOf('add')> -1){ add = buttons[i]; }else if(src.indexOf('del')>-1){ del = buttons[i]; }else if(src.indexOf('save')>-1){ save = buttons[i]; } } new BaseJs.EditTable({ // 表对象 table : BaseJs.$("tabList"), // 从第几行第几列开始可编辑 start : [2, 2], // 到哪一行哪一列结束编辑 不写默认所有,写一个参数代表列,行不限 end : [], // 新增操作 addAction : { // (button)执行操作的按钮, button : add, // callback:执行操作后的回调函数,能够加入一些自定义操作 callback : function(tr) { tr.onclick = function() { var trs = BaseJs.getByTagName("tr",BaseJs.$("tagList")); for (var i = 0; i < trs.length; i++) { trs[i].style.background = '#FAFCFE'; } tr.style.background = '#B8CCF0'; } } }, // 保存新增或更新操作 saveOrUpdateAction : { button : save, // 提交更新url,后台取参数data,为json字符串 url : 'WaterQualityAction?method=saveOrUpdate', callback : function() { document.location.reload(); } }, // 删除操作 delAction : { button : del, // 删除url 可用函数返回动态url url : function() { return 'WaterQualityAction?method=del&mid=' + document.getElementById("mid").value; }, callback : function() { document.location.reload(); } }, // id名(记录的id值需要保存在tr.id上) primaryKey : 'id', // 要全并的列数集合 [0]代表第一列要执行合并操作,[0,1]代表1,2列有合并操作 mergeColumn : [0,1], // 列描述对象 ,包含一个数组,数组中每一个对象说明一个列编辑对象和相关处理 column : [ { // 列名 name : 'areaName', // 编辑类型 当前支持三种编辑方式text(文本框)date(日期型)select(选择框) editorType : 'select', //数据来源 dataUrl : 'WaterQualityAction?method=AjaxSelect¶=AREANAME&dataSource=db' }, { name : 'sectionName', editorType : 'select', // 支持动态url,传入参数为当前操作的td对象 dataUrl : function(me){ pre = me; while(pre.tagName.toLowerCase() != "td"){ pre = pre.parentNode; } pre = BaseJs.element.prev(pre); parentText = BaseJs.text(pre); if(parentText == "请修改数据"){ alert("请先修改水功能区名!"); return false; } return 'WaterQualityAction?method=AjaxSelect¶=sectionNAME&dataSource=db&parentText='+parentText; } }, { name : 'date_month', // 日期型 editorType : 'date', // 格式化日期样式,默认yyyy-MM format : 'yyyy年MM月份', //自定义默认值 defaultValue : BaseJs.Utils.format .date(new Date(), 'yyyy年MM月份') }, { name : 'quality_level', // 选择型 editorType : 'select', // 加载select数据url,返回json数据,格式应为:[{display:'',value:''},{display:'',value:''}] dataUrl : 'WaterQualityAction?method=AjaxSelect¶=LEVEL', validate : function(value) { return true; }, // 新增默认值,不写使用默认 defaultValue : '请选择', // 检验输入数据正确性,返回true通过验证 validate : function(v, obj) { //alert("现在检验输入数据合法性!"); return true; } }, { name : 'quality_state', editorType : 'select', dataUrl : 'WaterQualityAction?method=AjaxSelect¶=SELECT', defaultValue : '请选择' }, { name : 'overproof', editorType : 'text', defaultValue : '----' }, { name : 'quality_target', editorType : 'select', dataUrl : 'WaterQualityAction?method=AjaxSelect¶=LEVEL', defaultValue : '请选择' }, { name : 'area_qualityTarget', editorType : 'text', defaultValue : '请输入' }] });