1. 可以和后台进行互动,通过第一列的值进行ajax请求。然后给后面的单元格进行赋值操作。支持键盘添加一行、删除一行表格、支持上下左右,快捷移到获得焦点操作。以及键盘事件对数字进行验证等。
    2. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    3. <html>
    4. <head>
    5. <title>table editor</title>
    6. <meta http-equiv="pragma" content="no-cache">
    7. <meta http-equiv="cache-control" content="no-cache">
    8. <meta http-equiv="expires" content="0">
    9. <script type="text/javascript" src="jquery.js"></script>
    10. <style type="text/css">
    11. .tableRow1 {
    12. background-color: #E6F3FC;
    13. }
    14. .tableRow2 {
    15. background-color: #ffffff;
    16. }
    17. .tableRow3 {
    18. background-color: #FFFFC9;
    19. color: #D40F16;
    20. }
    21. .tableHead {
    22. font-size: 12px;
    23. color: #FFFFFF;
    24. font-weight: bold;
    25. white-space: nowrap;
    26. word-break : keep-all ;
    27. background-color: #2897E6;
    28. }
    29. </style>
    30. <script type="text/javascript">
    31. var htmlTemplate = '<tr align="center"><td><input type="text" name="report_num" size="20"/>';
    32. htmlTemplate += '<input type="hidden" name="consign_id"/><br/>';
    33. htmlTemplate += '<span name="msg" style="color: red;"></span></td>';
    34. htmlTemplate += '<td><input type="text" name="contract_num" size="15"/></td>';
    35. htmlTemplate += '<td><input type="text" name="wt_num" size="15"/></td>';
    36. htmlTemplate += '<td><input type="text" name="wt_company" size="20"/></td>'
    37. htmlTemplate += '<td><input type="text" name="project_name" size="20"/></td>'
    38. htmlTemplate += '<td><input type="text" name="project_address" size="20"/></td>';
    39. htmlTemplate += '<td><input type="hidden" name="item_id"/><input type="text" name="item_name" size="15"/></td>';
    40. htmlTemplate += '<td><input type="text" name="report_count" size="3"/></td>';
    41. htmlTemplate += '<td><input type="text" name="price" size="5"/></td>';
    42. htmlTemplate += '<td><input type="text" name="amount" size="5"/></td>';
    43. htmlTemplate += '<td><input type="text" name="ought_fare" size="5"/></td></tr>';
    44. //添加一行表格记录
    45. function addRowEl(textInput, currentEL) {
    46. //textInput = $(this),jQuery会自动传入触发当前事件的一个对象,即textInput,也就是这里的$(this)
    47. var el = currentEL == undefined ? $(this) : currentEL;
    48. if (el.attr("name") == "report_num") {
    49. getReportInfo(el);
    50. } else {
    51. var trEl = el.parent().parent();
    52. if (isAdd(trEl)) {
    53. //var tabEl = $(this).parentsUntil("table");
    54. //trEl.clone(true).appendTo(trEl.parent());
    55. var template = $(htmlTemplate);
    56. template.appendTo(trEl.parent());
    57. template.find(":text").focusin(onReportNum).focusout(onLoadReportInfo).keyup(onInputKeyUp);
    58. template.find(":text[name='report_num']").focus().focusin();
    59. addClass();
    60. }
    61. }
    62. }
    63. //失去焦点时,添加一条tr行记录
    64. function onReportNum() {
    65. var el = $(this);
    66. var trEl = el.parent().parent();
    67. if (el.attr("name") == "report_num") {
    68. if (el.val() == "") {
    69. var userName = "H";
    70. if (userName.length > 0) {
    71. el.val(userName.substring(0, 1) + new Date().getYear());
    72. }
    73. }
    74. if (isAdd(trEl)) {
    75. var template = $(htmlTemplate);
    76. template.appendTo(trEl.parent());
    77. template.find(":text").focusin(onReportNum).focusout(onLoadReportInfo).keyup(onInputKeyUp);
    78. template.find(":text[name='report_num']").focusin(onReportNum).focus().focusin();
    79. addClass();
    80. }
    81. } else if (el.attr("name") == "ought_fare") {
    82. var price = trEl.find(":text[name='price']").val();
    83. var count = trEl.find(":text[name='amount']").val();
    84. if (price != "" && count != "") {
    85. el.val(parseFloat(price)*parseInt(count));
    86. }
    87. }
    88. }
    89. //验证字段值是否为空,不为空则可以添加一行
    90. function isAdd(trEl) {
    91. var allInput = trEl.parent().find(":text");
    92. for (var i = 0; i < allInput.length; i++) {
    93. var temp = $(allInput[i]);
    94. var index = $.inArray(temp.attr("name"), ["report_num", "contract_num", "wt_num", "wt_company", "project_name", "item_name"]);
    95. if (index != -1) {
    96. if (temp.attr("name") == "report_num") {
    97. if (temp.val() == "E2010" || temp.val() == "") {
    98. return false;
    99. }
    100. } else {
    101. if(temp.val() == "") {
    102. return false;
    103. }
    104. }
    105. }
    106. }
    107. return true;
    108. }
    109. function flaotInputOnly() {
    110. if (event.keyCode > 57 || event.keyCode < 46 || event.keyCode == 47)
    111. event.keyCode = 0;
    112. }
    113. String.prototype.replaceAll = function(s1, s2) {
    114. return this.replace(new RegExp(s1, "gm"), s2); //g全局
    115. }
    116. //获得当前光标的索引
    117. function getFocusIndex(aryTr, currentEL) {
    118. var i = 0;
    119. var j = -1;
    120. $(aryTr).each(function () {//得到当前元素索引
    121. if (currentEL.attr("name") == $(this).attr("name")) {
    122. j = i;
    123. }
    124. i++;
    125. });
    126. return j;
    127. }
    128. function onInputKeyUp(e) {
    129. var event = e || window.event;
    130. var currKeyCode = event.keyCode || event.which || event.charCode;
    131. var currentEL = $(this);
    132. if (currentEL.attr("name") == "report_count" || currentEL.attr("name") == "amount") {
    133. currentEL.val(currentEL.val().replace(//D/g,''));//验证整数
    134. } else if (currentEL.attr("name") == "price" || currentEL.attr("name") == "ought_fare") {
    135. var val = currentEL.val();//验证小数
    136. if (parseFloat(val) != val) {
    137. var ar = val.split('');
    138. for(var i = 0; i < ar.length; i++) {
    139. var charCode = ar[i].charCodeAt(0);
    140. if (charCode > 57 || charCode < 46 || charCode == 47) {
    141. currentEL.val(val.replaceAll(ar[i], ''));
    142. }
    143. }
    144. }
    145. }
    146. var currentTd = currentEL.parent();
    147. var currentTr = currentTd.parent();
    148. var aryTr = currentTr.find(":text").toArray();
    149. var nextTd = currentTd.next("td");
    150. var prevTd = currentTd.prev("td");
    151. //alert(e.keyCode + ":" + currKeyCode);
    152. if (currKeyCode == 13) {//回车,enter键
    153. nextTd.find(":text").focus().focusin();//获得下一文本域让其获得焦点
    154. addRowEl(undefined, currentEL);//添加一行
    155. } else if (currKeyCode == 45) { //insert键,添加一行
    156. addRowEl(undefined, currentEL);
    157. } else if (currKeyCode == 46) { //delete键,删除一行
    158. var tab = currentTr.parent();
    159. var j = getFocusIndex(aryTr, currentEL);
    160. var prevTr = currentTr.prev("tr");
    161. var prevInput = prevTr.find(":text:eq(" + j + ")");
    162. if (prevInput.attr("name") != undefined) {
    163. prevInput.focus().focusin();
    164. }
    165. if (tab.get(0).rows.length != 2) {
    166. currentTr.remove();
    167. }
    168. } else if (currKeyCode == 39) { //right键,后一个、右
    169. //如果是报告编号文本域就调用ajax方法并设置委托的信息
    170. onLoadReportInfo(undefined, currentEL);
    171. nextTd.find(":text").focus().focusin();
    172. } else if (currKeyCode == 38) {//up键,上
    173. onLoadReportInfo(undefined, currentEL);
    174. //得到当前元素索引
    175. var j = getFocusIndex(aryTr, currentEL);
    176. var prevTr = currentTr.prev("tr");
    177. var prevInput = prevTr.find(":text:eq(" + j + ")");
    178. if (prevInput.attr("name") != undefined) {
    179. prevInput.focus().focusin();
    180. }
    181. } else if (currKeyCode == 40) {//down键,下一个
    182. onLoadReportInfo(undefined, currentEL);
    183. var j = getFocusIndex(aryTr, currentEL);
    184. var nextTr = currentTr.next("tr");
    185. var nextInput = nextTr.find(":text:eq(" + j + ")");
    186. if (nextInput.attr("name") != undefined) {
    187. nextInput.focus().focusin();
    188. }
    189. } else if (currKeyCode == 37) {//left键,左、前
    190. onLoadReportInfo(undefined, currentEL);
    191. prevTd.find(":text").focus().focusin();
    192. }
    193. }
    194. //根据报告编号加载委托信息
    195. function onLoadReportInfo(textInput, currentEL) {
    196. var el = currentEL == undefined ? $(this) : currentEL;
    197. if (el.attr("name") == "report_num") {
    198. getReportInfo(el);
    199. }
    200. }
    201. //ajax请求,通过报告编号获得委托信息
    202. function getReportInfo(el) {
    203. var reportNum = $(el);
    204. var trEl = reportNum.parent().parent();
    205. var idEL = reportNum.next(":hidden[name='id']");
    206. var reportVal = reportNum.val();
    207. var aryNum = $("#sealTab :text[name='report_num']").toArray();
    208. var aryResult = $.grep(aryNum, function (o) {
    209. return $(o).val() == reportVal;
    210. });
    211. if (aryResult.length > 1) {
    212. reportNum.parent().find("span[name='msg']").text("该编号已申请,确定重复申请!");
    213. reportNum.attr("flag", "exist");
    214. //return;
    215. }
    216. if (reportVal != "") {
    217. $.post("transaction/reportSeal.do?method=getInfo", {id: idEL.val(), REPORT_NUM: reportVal}, function (data) {
    218. var rs = eval(data);
    219. if (rs.length > 0) {
    220. if (!rs[0].valid){
    221. reportNum.parent().find("span[name='msg']").text("没有查询到该编号的信息!");
    222. reportNum.attr("flag", "invalid");
    223. return;
    224. } else {
    225. if (rs.length > 2) {
    226. $.each(rs[2], function (field, value) {
    227. if (value != "") {
    228. trEl.find("input[name='" + field + "']").val(value);
    229. }
    230. });
    231. }
    232. }
    233. if (!rs[1].exists) {
    234. reportNum.parent().find("span[name='msg']").empty();
    235. reportNum.attr("flag", "valid");
    236. } else {
    237. reportNum.parent().find("span[name='msg']").text("该编号已申请,确定重复申请!");
    238. reportNum.attr("flag", "exist");
    239. }
    240. }
    241. });
    242. }
    243. }
    244. $(function () {
    245. addClass();
    246. //为sealTab中所有的文本域添加获得焦点、事情焦点事件
    247. $("#sealTab :text").focusin(onReportNum).keyup(onInputKeyUp).focusout(onLoadReportInfo);
    248. });
    249. function addClass() {
    250. $("#sealTr").nextAll().each(function (i) {
    251. return i % 2 == 0 ? $(this).addClass("tableRow1").removeClass("tableRow2") : $(this).addClass("tableRow2").removeClass("tableRow1");
    252. });
    253. }
    254. </script>
    255. </head>
    256. <body bgcolor="#ffffff">
    257. <font color="red" style="font-size: 12px;">注意:*标记的列表格为必填的;insert插入一行(*号标记数据填写完整时)、delete键删除当前行(一行记录时不能删除)</font>
    258. <table id="sealTab" width="100%" border="0" cellpadding="3" cellspacing="1" bgcolor="#C7CED4">
    259. <tr id="sealTr" class="tableHead" valign="middle">
    260. <td align="center">
    261. <span style="color:#ffffff">报告编号</span>
    262. <font color="red">*</font>
    263. </td>
    264. <td align="center">
    265. <span style="color:#ffffff">合同编号</span>
    266. </td>
    267. <td align="center">
    268. <span style="color:#ffffff">委托编号</span>
    269. </td>
    270. <td align="center">
    271. <span style="color:#ffffff">委托单位</span>
    272. </td>
    273. <td align="center">
    274. <span style="color:#ffffff">工程名称</span>
    275. </td>
    276. <td align="center">
    277. <span style="color:#ffffff">工程地点</span>
    278. </td>
    279. <td align="center">
    280. <span style="color:#ffffff">检测项目</span>
    281. </td>
    282. <td align="center">
    283. <span style="color:#ffffff">份数</span>
    284. </td>
    285. <td align="center">
    286. <span style="color:#ffffff">单价</span>
    287. </td>
    288. <td align="center">
    289. <span style="color:#ffffff">数量</span>
    290. </td>
    291. <td align="center">
    292. <span style="color:#ffffff">总价</span>
    293. </td>
    294. </tr>
    295. <tr align="center">
    296. <td>
    297. <input type="text" name="report_num" size="20"/>
    298. <input type="hidden" name="id"/>
    299. <input type="hidden" name="consign_id"/>
    300. <span name="msg" style="color: red;"></span>
    301. </td>
    302. <td>
    303. <input type="text" name="contract_num" size="15"/>
    304. </td>
    305. <td>
    306. <input type="text" name="wt_num" size="15"/>
    307. </td>
    308. <td>
    309. <input type="text" name="wt_company" size="20"/>
    310. </td>
    311. <td>
    312. <input type="text" name="project_name" size="20"/>
    313. </td>
    314. <td>
    315. <input type="text" name="project_address" size="20"/>
    316. </td>
    317. <td>
    318. <input type="hidden" name="item_id"/>
    319. <input type="text" name="item_name" size="15"/>
    320. </td>
    321. <td>
    322. <input type="text" name="report_count" size="3"/>
    323. </td>
    324. <td>
    325. <input type="text" name="price" size="5"/>
    326. </td>
    327. <td>
    328. <input type="text" name="amount" size="5"/>
    329. </td>
    330. <td>
    331. <input type="text" name="ought_fare" size="5"/>
    332. </td>
    333. </tr>
    334. </table>
    335. </body>
    336. </html>
    1. //ajax请求相关java code:
    2. public String getConsigJSON(String reportNum, String id) throws Exception {
    3. String sql = "select top 1 m.id as consign_id, contract_num,wt_num,wt_company,project_name,project_prov+project_city+project_area project_address,m.report_count,item_id,ought_fare,s.name item_name from MM_Consign m, SS_subject s where item_id = s.id and report_num = '" + reportNum + "'";
    4. StringBuffer json = new StringBuffer("[");
    5. try {
    6. stmt = conn.createStatement();
    7. rs = stmt.executeQuery(sql);
    8. ResultSetMetaData rsmd = rs.getMetaData();
    9. RowSetDynaClass rsdc = new RowSetDynaClass(rs);
    10. List list = rsdc.getRows();
    11. /*if ("".equals(id)) {
    12. String validValue = isValid(reportNum);
    13. json.append("{valid:").append(validValue).append("},");
    14. String existsValue = this.isExists(reportNum);
    15. json.append("{exists:").append(existsValue).append("}");
    16. } else {*/
    17. String num = getReportNum(id);
    18. if (num.equals(reportNum)) {
    19. json.append("{valid:true},");
    20. json.append("{exists:false}");
    21. } else {
    22. String validValue = isValid(reportNum);
    23. json.append("{valid:").append(validValue).append("},");
    24. String existsValue = this.isExists(reportNum);
    25. json.append("{exists:").append(existsValue).append("}");
    26. }
    27. //}
    28. for (int j = 0, len = list.size(); j < len; j++) {
    29. json.append(",{");
    30. DynaBean dyna = (DynaBean) list.get(j);
    31. for (int i = 1; i <= rsmd.getColumnCount(); i++) {
    32. if (i == rsmd.getColumnCount()) {
    33. json.append(rsmd.getColumnName(i)).append(":/"")
    34. .append(FunctionStatic.getNullString(BeanUtils.getSimpleProperty(dyna, rsmd.getColumnName(i).toLowerCase())))
    35. .append("/"");
    36. } else {
    37. json.append(rsmd.getColumnName(i)).append(":/"")
    38. .append(FunctionStatic.getNullString(BeanUtils.getSimpleProperty(dyna, rsmd.getColumnName(i).toLowerCase())))
    39. .append("/",");
    40. }
    41. }
    42. json.append("}");
    43. /*if (j < len - 1) {
    44. json.append(",");
    45. }*/
    46. }
    47. json.append("]");
    48. } catch (Exception e) {
    49. e.printStackTrace();
    50. throw e;
    51. }
    52. return json.toString();
    53. }
    54. public String isValid(String reportNum) throws Exception {
    55. String bool = "";
    56. try {
    57. prepar = conn.prepareStatement("select count(*) from MM_Consign where report_num = '" + reportNum + "'");
    58. rs = prepar.executeQuery();
    59. int count = rs.next() ? rs.getInt(1) : 0;
    60. bool = count > 0 ? "true" : "false";
    61. } catch (Exception e) {
    62. e.printStackTrace();
    63. throw e;
    64. }
    65. return bool;
    66. }
    67. public String isExists(String reportNum) throws Exception {
    68. String bool = "";
    69. try {
    70. prepar = conn.prepareStatement("select count(*) from MM_ReportTransfer where report_num = '" + reportNum + "'");
    71. rs = prepar.executeQuery();
    72. int count = rs.next() ? rs.getInt(1) : 0;
    73. bool = count > 0 ? "true" : "false";
    74. } catch (Exception e) {
    75. e.printStackTrace();
    76. throw e;
    77. }
    78. return bool;
    79. }