<html> <adept> <style type = "text/css"> .grid {border: 1px solid #808080; spasi perbatasan: 0; Lebar: 500px; Border-Collapse: runtuh} .grid th, .grid td {border: 0; text-align: center;} .grid tr {height: 25px; line-height: 25px;} .grid tr.odd {latar belakang:#d0d0d0} .grid .btn {lebar: 80px; Text-Align: center} </tyle> <script type = "text/javascript"> (function () {// var util = {next: function next (eLe) {if (ele) {var n = eLe.nextSibling; if (n && n.nodetype === 1) {return n;} return next (n && n.nodetype === 1) {return n;} return next; Json! = "Tidak terdefinisi") {return json.parse (str); Array.prototype.slice.call (obj, 0); "Tidak ditentukan") {Hasil. Target); Offset: function offset (ELE) {var result = {top: 0, kiri: 0}; (ELE.STYLE.TOP || "0"). Ganti (/[^/d]+$/, "")); result.left = angka (ELE.OffsetLeft || (ELE.STYLE.LEFT || "0"). Ganti (/[^/D]+$/, "")); if (ele.parentnode) {var r = offset (ele.parentnode); result.top += r.top; result.left += r.left; } hasil pengembalian; }}; // 事件处理 var event = {on: function (eventType, fn) {var elemen = this; if (this.addeventListener) {this.addeventListener (eventType, fn, false); } lain jika (this.attachevent) {// 将事件缓冲到该标签上, 已解决 window 指向 ini (现 fn 内 ini 指向 elemen) 和移除匿名事件问题 var _eventref = '_'+eventType+'eventRef'; if (! element [_eventref]) {elemen [_eventRef] = []; } var _eventrefs = elemen [_eventref]; indeks var; untuk (indeks dalam _eventrefs) {if (_eventrefs [index] ['realfn'] == fn) {return; }} var nestfn = function () {fn.Apply (elemen, argumen); }; elemen [_eventref] .push ({'realfn': fn, 'nestfn': nestfn}); element.attachevent ('on'+eventType, nestfn); }}, hapus: function (eventType, fn) {var elemen = this; if (this.removeEventListener) {this.removeEventListener (eventType, fn, false); } else if (this.detachevent) {var _eventref = '_'+eventType+'eventRef'; if (! element [_eventref]) {elemen [_eventRef] = []; } var _eventrefs = elemen [_eventref] indeks var; var nestfn; untuk (indeks dalam _eventrefs) {if (_eventrefs [index] ['realfn'] == fn) {nestfn = _eventrefs [index] ['nestfn']; if (index == _ eventRefs.length-1) {elemen [_eventRef] = _ eventRefs.slice (0, index); } else {element [_eventRef] = _ eventRefs.slice (0, index) .concat (_eventrefs.slice (index+1, _eventrefs.length-1)); } merusak; }} if (nestfn) {element.detachevent ('on'+eventType, nestfn); }}}}; // Extens (function () {// 删除数组中指定下标出的元素 array.prototype.remove = function (index) {var o = this [index]; if (typeof o! == "tidak terdefinisi") {if (index == 0) {this.shift ();} lain jika (index === this ARR2 = ini i = 0; i <this.length; i ++) {if (typeof ini [i]! == "tidak terdefinisi") {fn.call (ini [i], i); this.__data[this.length++] = obj; }, get:function(index){ return this.__data[index]; }, remove:function(index){ var obj = this.__data[index]; if(typeof obj !== "undefined"){ this.length--; } delete this.__data[index]; }, clear:function(){ this.__data = {}; this.length = 0;}, masing -masing: fungsi (fn) {var index = 0; untuk (var k dalam data .__ ini) {if (k && typeof data ini [k]! == "tidak terdefinisi") {fn.call (data ini .__ [k], index ++); }}}, toArray: function () {var arr = []; this.each (function () {arr.push (this);}); return arr; }}; }) (); // var grid = this.grid = function (tabel, opsi) {grid.prototype._init.call (this, tabel, opsi); } grid.prototype = {_init: function (tabel, opsi) {if (typeof tabel === "tidak terdefinisi" ||! Table) {throw "Tabel tidak terdefinisi atau nol"; } if (TABLE.NODETYPE! == 1 ||!/^TABLE $/I.TEST (TABLE.TAGNAME)) {Throw "Tabel harus menjadi elemen 'Tabel'."; } table.guid = ++ grid.guid; ini .__ cache = {}; var self = ini; var header = ini .__ cache ["header"] = loadheader (); // header ini .__ root = header.parentnode; var templaterow = ini .__ cache ["template"] = loadTemplate (); // 模板行 ini .__ cache ["DataFormat"] = loadDataFormat (); // 数据模板 ini .__ cache ["DataRows"] = new (); // 数据行 ini .__ cache ["customCache"] = 当前编辑行 当前编辑行 ed ed ed ed ed 数据模板 ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed new new load 数据模板 CACHE. this .__ saveContainer = createSaveButton (); // 保存按钮 ini .__ cache ["commandHandles"] = {// perintah handels removerow: function () {var rowIndex = this.getAttribute ("index"); self.removerow.apply (self, [rowindex]); }, newline: function () {self.newline (); }}; this .__ regCommand = function (commandName, row) {// 注册 perintah if (row) {var arg = row.getAttribute ("index"); this.setAttribute ("index", arg || false); } this.CommandName = commandName; Event.remove.call (ini, "klik", exec); Event.on.call (ini, "klik", exec); } this .__ removerowCallback = function () {// 改变行的背景样式 var rows = ini .__ cache ["datarows"]; var CustomCache = ini .__ cache ["CustomCache"]; var arr = baris.toArray (), dataArr = []; Var Rowindex, Row, Data; baris.clear (); arr.each (function (i) {rowIndex = this.getAttribute ("index"); data = customcache.get (rowIndex); dataArr.push (data); this.setAttribute ("index", i.toString ()); rows.add (ini); if (i % 2 == 1) {// 基数行 基数行 基数行if (! // sodd/s | /sodd$/g.test (this.className)) {this.className = (this.className || ") +" ganjil "; this.classname.replace (// sodd/s |/sodd $/g, ""); customcache.clear (); dataArr.each (function () {customcache.add (this);}); } // 事件处理 opsi = opsi || {}; this.ondatabinding = options.ondatabinding || this.ondatabinding; this.onrowbinding = options.onrowbinding || this.onrowbinding; this.onrowbinded = options.onrowbinded || ini .onrowbinded; function loadHeader () {var tr = Table.FirstChild; if (tr && tr.nodetype! = 1) {tr = util.next (tr); } if (!/tr/i.test (tr.tagname)) {// 如果第一个元素不是 tr , 则浏览器支持 tbody tr = tr.FirstChild; if (tr.nodetype! = 1) {tr = util.next (tr); }} return tr; } function loadTemplate () {tr = util.next (header); // 获取模板行 return tr; } function loadDataFormat () {var node = templaterow.childnodes, ele, data, result = {}, attr; node = util.pararray (node); nodes.each (function (i) {ele = this; if (ele && ele.nodetype == 1) {attr = ele.data || ele.getattribute ("data"); if (attr) {data = util.parsejson (attr); eLe.field = data.field; hasil [eLe. hasil pengembalian; } function createSaveButton () {var div = document.createelement ("div"); div.style.position = "absolute"; div.style.display = "none"; div.style.width = "auto"; var btn = document.createElement ("tombol"); btn.innerHtml = btn.innertext = btn.textContent = btn.value = "save"; coba {btn.type = "tombol"; } catch (e) {btn.setAttribute ("type", "button"); } div.AppendChild (btn); var btncancel = document.createelement ("tombol"); btncancel.innerHtml = btncancel.innertext = btncancel.textcontent = btncancel.value = "batal"; coba {btncancel.type = "tombol"; } catch (e) {btncancel.setAttribute ("type", "Tombol"); } div.AppendChild (btncancel); Document.Body.AppendChild (Div); Event.on.call (btn, "klik", function () {self.save ();}); Event.on.call (btncancel, "klik", function () {div.style.display = "none"; if (self .__ editrow) {self .__ editrow.parentnode.removechild (self .__ editrow); self .__ editrow = null;}}); Return Div; } function exec () {if (self .__ editrow) {// 如果当前处于编辑模式 , 则禁用所有 perintah kembali; } var commandName = this.CommandName; var handler = self .__ cache ["commandhandles"] [commandName]; if (handler) {handler.call (ini); }} // 去除模板行 templaterow.parentnode.removechild (templaterow); // 处理表格中的 Perintah 事件 elemen var = header.getElementsbyTagname ("*"); elemen = util.pararray (elemen); elemen.each (function () {if (this.nodetype === 1) {var commandName = this.Command || this.getAttribute ("command"); if (commandName) {self .__ regcommand.call (this, commandName, header);}}}); }, // Bind: function (data) {this.clear (); if (data && data.length> 0) {var self = this; data.each (function () {self.append (this);}); }}, // 清理表 , 删除所以除 header 以外的数据行 CLEAR: function () {var rows = ini .__ cache ["DATAROWS"], ROW; rows.each (function () {row = this; if (row) {row.parentnode.removechild (row);}}); baris.clear (); // 清理 baris}, // 删除指定的行 removerow: function (rowIndex) {var rows = ini .__ cache ["datalows"]; var row = rows.get (rowIndex); if (row) {var data = ini .__ cache ["customcache"] [rowIndex]; row.parentnode.removechild (baris); Baris.Remove (Rowindex); // 通知用户数据行被移除 if (util.isfunction (this.onrowremoved)) {this.onrowremoved (data, baris); }} ini .__ removerowCallback (); }, // 添加 行 append: function (data) {if (! Data) {return; } var template = ini .__ cache ["template"]; var baris = ini .__ cache ["datarows"]; var rowindex = rows.length; var tr = template.clonenode (); var CustomCache = ini .__ cache ["CustomCache"]; customcache.add (data); // 将数据行添加到 Tabel ini .__ root.AppendChild (TR); var self = ini; var td, // 数据单元格 dataformat, // 数据格式化器 nilai; // 单元格中的给定的数据 tr.setAttribute ("index", rowIndex.tostring ()); // 更改样式 if (rowIndex % 2 == 1) {tr.classname = (tr.classname || "") + "ganjil"; } // 通知 行数据绑定开始 if (util.isfunction (this.onrowbinding)) {this.onrowBinding (rowindex, tr); } var templateTd = template.firstchild; while (templateTd) {td = templateTd.clonenode (true); Tr.AppendChild (TD); if (td.nodetype == 1 && templateTd.field) {dataFormat = ini .__ cache ["DataFormat"] [templateTd.field]; td.removeattribute ("data"); td.field = templatetd.field; value = data [DataFormat.Field]; // 通知单元格数据绑定事件 value = this.ondatabinding (dataformat.field, value, td, data); if (value! == false) {// 如果返回 false , 则不用做赋值操作 switch (dataFormat.render) {case "innerHtml": td.innerHtml = typeOf value == "tidak terdefinisi" || nilai == NULL? "" : nilai; merusak; case "Innertext": default: td.innerText = td.textContent = typeOf value == "tidak terdefinisi" || nilai == NULL? "" : nilai; merusak; }}} templateTd = templateTd.nextsibling; } Rows.add (tr); // 处理 perintah var elemen = tr.geteLementsbyTagname ("*"), ele, attr; elemen = util.pararray (elemen); elemen.each (function () {ele = this; if (eLe.nodetype == 1 && (ele.Command || ele.getattribute ("command"))) {attr = ele.command || ele.getattribute ("command"); self .__ regcommand.call (eLe, attr, tr); // 通知 行数据绑定完成 if (util.isfunction (this.onrowbinded)) {this.onrowbinded (rowindex, tr); }}, // 手动产生新的输入行 newline: function () {if (this .__ editrow) {// 如果当前有存在编辑行 , 则直接返回 , 每次最多限制编辑一行数据 return; } var template = ini .__ cache ["template"]; var row = this .__ editrow = template.clonenode (false); var templateTd = template.firstchild; var textarealist = []; while (templateTd) {td = templateTd.clonenode (true); Row.AppendChild (TD); if (td.nodetype == 1) {if (templateTd.field) {td.field = templateTd.field; td.innerhtml = ""; var dataFormat = ini .__ cache ["DataFormat"] [TemplatetD.Field]; var textarea = null; if (dataformat.render == "innerHtml") {texTarea = document.createElement ("textArea"); } else {TextAreA = document.createElement ("input"); textarea.type = "text"; } textarea.style.display = "none"; TD.AppendChild (TexTarea); textarealist.push (TextArea); }} templateTd = templateTd.nextsibling; } // 将数据行添加到 Tabel ini .__ root.AppendChild (baris); var height = row.offsetHeight, width = row.offsetWidth, offset = util.offset (baris); textarealist.each (function () {this.style.height = (0,8 * tinggi) + "px"; this.style.width = (0,8 * this.parentnode.offsetWidth) + "px"; this.style.display = "";}); var left = offset. Left + lebar + 5; var top = offset.top; this.__savecontainer.style.top = top + "px"; ini .__ savecontainer.style.left = kiri + "px"; ini .__ savecontainer.style.height = ini .__ savecontainer.style.lineheight = tinggi + "px"; ini .__ savecontainer.style.display = "block"; }, // 保存手动产生的数据行数据 save: function () {if (! This .__ editrow) {return; } var row = ini .__ EditRow; var td = row.firstchild; var data = {}; while (td) {if (td.nodetype === 1 && td.field) {var dataFormat = ini .__ cache ["dataFormat"] [td.field]; var textarea = null; if (dataformat.render == "innerHtml") {texTarea = td.getElementsByTagname ("TextAreA") [0]; } else {texTarea = td.getElementsByTagname ("input") [0]; } value = TextArea.Value; switch (dataFormat.DataType) {case "number": value = util.trim (value); value = number (value.length == 0? 0: value); merusak; default: break; } data [td.field] = nilai; } td = td.nextsibling; } ini .__ editrow.parentnode.removechild (ini .__ editrow); ini .__ editrow = null; ini .__ savecontainer.style.display = "none"; // 通知用户正在保存数据 if (util.isfunction (this.onsaving)) {this.onsaving (data); } this.append (data); }, getRowData: function (rowIndex) {return ini .__ cache ["customcache"]. get (rowIndex); }, // 数据绑定到指定 sel 时的事件 ontDatabinding: function (bidang, nilai, sel, data) {nilai pengembalian; }, // 当数据行绑定开始时的事件 OnrowBinding: function (rowIndex, row) {}, // 当数据行绑定完成时的事件 //@param row {dom elemen tr} onrowbinded: function (rowIndex, row) {}, // 当编辑的数据被保存时的事件 onsaving: function (data) {}, // 当数据行被移除时的通知事件 onrowremoved: function, row) {{} {} {}; grid.guid = 0; }) (); </script> </head> <body> <Table id = "Table_Demo"> <tr> <th> id </t> <t th> nama </th> <t th> descpription </t th> <t th> <typute type = "command" command = "newline"> Baris baru </tutton> </th> </tr> <TR> <td Data = '{"bidang": "id", "DataType": "Number", "Render": "Innertext"}'> 1 </td> <td data = '{"bidang": "name", "DataType": "string", "render": "Innertext"}> workingservice </td> <td td Data = '{"bidang": "Deskripsi", "DataType": "String", "Render": "InnerHtml"}'> WorkingService </td> <td> <tombol type = "command" command = "Removerow"> Teks/TEKPT/TOMPLEK "> </td> </tr> </Table> <script typeing =" TEXT/TEXT/JAV/JAV/JAV/JAV = JAV/JAV/JAV/JAV/JAV/TEXTREK/TEXT/JAV/TEXTCHCK = document.geteLementById ("Table_Demo"); var g = grid baru (tabel, {ontDatabinding: function (bidang, nilai) {value return;}, onrowbinded: function (rowIndex, row) {}}); g.bind ([{{id: 0, name: "kilin"}, {id: 1, name: "kilin1"}, {id: 2, nama: "kilin2"}, {id: 3, nama: "kilin3"}]); </script> </body> </html>