jQuery 可编辑表格文本域,支持键盘快捷操作

最后更新于:2022-04-01 10:05:03

~~~ 可以和后台进行互动,通过第一列的值进行ajax请求。然后给后面的单元格进行赋值操作。支持键盘添加一行、删除一行表格、支持上下左右,快捷移到获得焦点操作。以及键盘事件对数字进行验证等。 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>table editor</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <script type="text/javascript" src="jquery.js"></script> <style type="text/css"> .tableRow1 { background-color: #E6F3FC; } .tableRow2 { background-color: #ffffff; } .tableRow3 { background-color: #FFFFC9; color: #D40F16; } .tableHead { font-size: 12px; color: #FFFFFF; font-weight: bold; white-space: nowrap; word-break : keep-all ; background-color: #2897E6; } </style> <script type="text/javascript"> var htmlTemplate = '<tr align="center"><td><input type="text" name="report_num" size="20"/>'; htmlTemplate += '<input type="hidden" name="consign_id"/><br/>'; htmlTemplate += '<span name="msg" style="color: red;"></span></td>'; htmlTemplate += '<td><input type="text" name="contract_num" size="15"/></td>'; htmlTemplate += '<td><input type="text" name="wt_num" size="15"/></td>'; htmlTemplate += '<td><input type="text" name="wt_company" size="20"/></td>' htmlTemplate += '<td><input type="text" name="project_name" size="20"/></td>' htmlTemplate += '<td><input type="text" name="project_address" size="20"/></td>'; htmlTemplate += '<td><input type="hidden" name="item_id"/><input type="text" name="item_name" size="15"/></td>'; htmlTemplate += '<td><input type="text" name="report_count" size="3"/></td>'; htmlTemplate += '<td><input type="text" name="price" size="5"/></td>'; htmlTemplate += '<td><input type="text" name="amount" size="5"/></td>'; htmlTemplate += '<td><input type="text" name="ought_fare" size="5"/></td></tr>'; //添加一行表格记录 function addRowEl(textInput, currentEL) { //textInput = $(this),jQuery会自动传入触发当前事件的一个对象,即textInput,也就是这里的$(this) var el = currentEL == undefined ? $(this) : currentEL; if (el.attr("name") == "report_num") { getReportInfo(el); } else { var trEl = el.parent().parent(); if (isAdd(trEl)) { //var tabEl = $(this).parentsUntil("table"); //trEl.clone(true).appendTo(trEl.parent()); var template = $(htmlTemplate); template.appendTo(trEl.parent()); template.find(":text").focusin(onReportNum).focusout(onLoadReportInfo).keyup(onInputKeyUp); template.find(":text[name='report_num']").focus().focusin(); addClass(); } } } //失去焦点时,添加一条tr行记录 function onReportNum() { var el = $(this); var trEl = el.parent().parent(); if (el.attr("name") == "report_num") { if (el.val() == "") { var userName = "H"; if (userName.length > 0) { el.val(userName.substring(0, 1) + new Date().getYear()); } } if (isAdd(trEl)) { var template = $(htmlTemplate); template.appendTo(trEl.parent()); template.find(":text").focusin(onReportNum).focusout(onLoadReportInfo).keyup(onInputKeyUp); template.find(":text[name='report_num']").focusin(onReportNum).focus().focusin(); addClass(); } } else if (el.attr("name") == "ought_fare") { var price = trEl.find(":text[name='price']").val(); var count = trEl.find(":text[name='amount']").val(); if (price != "" && count != "") { el.val(parseFloat(price)*parseInt(count)); } } } //验证字段值是否为空,不为空则可以添加一行 function isAdd(trEl) { var allInput = trEl.parent().find(":text"); for (var i = 0; i < allInput.length; i++) { var temp = $(allInput[i]); var index = $.inArray(temp.attr("name"), ["report_num", "contract_num", "wt_num", "wt_company", "project_name", "item_name"]); if (index != -1) { if (temp.attr("name") == "report_num") { if (temp.val() == "E2010" || temp.val() == "") { return false; } } else { if(temp.val() == "") { return false; } } } } return true; } function flaotInputOnly() { if (event.keyCode > 57 || event.keyCode < 46 || event.keyCode == 47) event.keyCode = 0; } String.prototype.replaceAll = function(s1, s2) { return this.replace(new RegExp(s1, "gm"), s2); //g全局 } //获得当前光标的索引 function getFocusIndex(aryTr, currentEL) { var i = 0; var j = -1; $(aryTr).each(function () {//得到当前元素索引 if (currentEL.attr("name") == $(this).attr("name")) { j = i; } i++; }); return j; } function onInputKeyUp(e) { var event = e || window.event; var currKeyCode = event.keyCode || event.which || event.charCode; var currentEL = $(this); if (currentEL.attr("name") == "report_count" || currentEL.attr("name") == "amount") { currentEL.val(currentEL.val().replace(//D/g,''));//验证整数 } else if (currentEL.attr("name") == "price" || currentEL.attr("name") == "ought_fare") { var val = currentEL.val();//验证小数 if (parseFloat(val) != val) { var ar = val.split(''); for(var i = 0; i < ar.length; i++) { var charCode = ar[i].charCodeAt(0); if (charCode > 57 || charCode < 46 || charCode == 47) { currentEL.val(val.replaceAll(ar[i], '')); } } } } var currentTd = currentEL.parent(); var currentTr = currentTd.parent(); var aryTr = currentTr.find(":text").toArray(); var nextTd = currentTd.next("td"); var prevTd = currentTd.prev("td"); //alert(e.keyCode + ":" + currKeyCode); if (currKeyCode == 13) {//回车,enter键 nextTd.find(":text").focus().focusin();//获得下一文本域让其获得焦点 addRowEl(undefined, currentEL);//添加一行 } else if (currKeyCode == 45) { //insert键,添加一行 addRowEl(undefined, currentEL); } else if (currKeyCode == 46) { //delete键,删除一行 var tab = currentTr.parent(); var j = getFocusIndex(aryTr, currentEL); var prevTr = currentTr.prev("tr"); var prevInput = prevTr.find(":text:eq(" + j + ")"); if (prevInput.attr("name") != undefined) { prevInput.focus().focusin(); } if (tab.get(0).rows.length != 2) { currentTr.remove(); } } else if (currKeyCode == 39) { //right键,后一个、右 //如果是报告编号文本域就调用ajax方法并设置委托的信息 onLoadReportInfo(undefined, currentEL); nextTd.find(":text").focus().focusin(); } else if (currKeyCode == 38) {//up键,上 onLoadReportInfo(undefined, currentEL); //得到当前元素索引 var j = getFocusIndex(aryTr, currentEL); var prevTr = currentTr.prev("tr"); var prevInput = prevTr.find(":text:eq(" + j + ")"); if (prevInput.attr("name") != undefined) { prevInput.focus().focusin(); } } else if (currKeyCode == 40) {//down键,下一个 onLoadReportInfo(undefined, currentEL); var j = getFocusIndex(aryTr, currentEL); var nextTr = currentTr.next("tr"); var nextInput = nextTr.find(":text:eq(" + j + ")"); if (nextInput.attr("name") != undefined) { nextInput.focus().focusin(); } } else if (currKeyCode == 37) {//left键,左、前 onLoadReportInfo(undefined, currentEL); prevTd.find(":text").focus().focusin(); } } //根据报告编号加载委托信息 function onLoadReportInfo(textInput, currentEL) { var el = currentEL == undefined ? $(this) : currentEL; if (el.attr("name") == "report_num") { getReportInfo(el); } } //ajax请求,通过报告编号获得委托信息 function getReportInfo(el) { var reportNum = $(el); var trEl = reportNum.parent().parent(); var idEL = reportNum.next(":hidden[name='id']"); var reportVal = reportNum.val(); var aryNum = $("#sealTab :text[name='report_num']").toArray(); var aryResult = $.grep(aryNum, function (o) { return $(o).val() == reportVal; }); if (aryResult.length > 1) { reportNum.parent().find("span[name='msg']").text("该编号已申请,确定重复申请!"); reportNum.attr("flag", "exist"); //return; } if (reportVal != "") { $.post("transaction/reportSeal.do?method=getInfo", {id: idEL.val(), REPORT_NUM: reportVal}, function (data) { var rs = eval(data); if (rs.length > 0) { if (!rs[0].valid){ reportNum.parent().find("span[name='msg']").text("没有查询到该编号的信息!"); reportNum.attr("flag", "invalid"); return; } else { if (rs.length > 2) { $.each(rs[2], function (field, value) { if (value != "") { trEl.find("input[name='" + field + "']").val(value); } }); } } if (!rs[1].exists) { reportNum.parent().find("span[name='msg']").empty(); reportNum.attr("flag", "valid"); } else { reportNum.parent().find("span[name='msg']").text("该编号已申请,确定重复申请!"); reportNum.attr("flag", "exist"); } } }); } } $(function () { addClass(); //为sealTab中所有的文本域添加获得焦点、事情焦点事件 $("#sealTab :text").focusin(onReportNum).keyup(onInputKeyUp).focusout(onLoadReportInfo); }); function addClass() { $("#sealTr").nextAll().each(function (i) { return i % 2 == 0 ? $(this).addClass("tableRow1").removeClass("tableRow2") : $(this).addClass("tableRow2").removeClass("tableRow1"); }); } </script> </head> <body bgcolor="#ffffff"> <font color="red" style="font-size: 12px;">注意:*标记的列表格为必填的;insert插入一行(*号标记数据填写完整时)、delete键删除当前行(一行记录时不能删除)</font> <table id="sealTab" width="100%" border="0" cellpadding="3" cellspacing="1" bgcolor="#C7CED4"> <tr id="sealTr" class="tableHead" valign="middle"> <td align="center"> <span style="color:#ffffff">报告编号</span> <font color="red">*</font> </td> <td align="center"> <span style="color:#ffffff">合同编号</span> </td> <td align="center"> <span style="color:#ffffff">委托编号</span> </td> <td align="center"> <span style="color:#ffffff">委托单位</span> </td> <td align="center"> <span style="color:#ffffff">工程名称</span> </td> <td align="center"> <span style="color:#ffffff">工程地点</span> </td> <td align="center"> <span style="color:#ffffff">检测项目</span> </td> <td align="center"> <span style="color:#ffffff">份数</span> </td> <td align="center"> <span style="color:#ffffff">单价</span> </td> <td align="center"> <span style="color:#ffffff">数量</span> </td> <td align="center"> <span style="color:#ffffff">总价</span> </td> </tr> <tr align="center"> <td> <input type="text" name="report_num" size="20"/> <input type="hidden" name="id"/> <input type="hidden" name="consign_id"/> <span name="msg" style="color: red;"></span> </td> <td> <input type="text" name="contract_num" size="15"/> </td> <td> <input type="text" name="wt_num" size="15"/> </td> <td> <input type="text" name="wt_company" size="20"/> </td> <td> <input type="text" name="project_name" size="20"/> </td> <td> <input type="text" name="project_address" size="20"/> </td> <td> <input type="hidden" name="item_id"/> <input type="text" name="item_name" size="15"/> </td> <td> <input type="text" name="report_count" size="3"/> </td> <td> <input type="text" name="price" size="5"/> </td> <td> <input type="text" name="amount" size="5"/> </td> <td> <input type="text" name="ought_fare" size="5"/> </td> </tr> </table> </body> </html> ~~~ ~~~ //ajax请求相关java code: public String getConsigJSON(String reportNum, String id) throws Exception { 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 + "'"; StringBuffer json = new StringBuffer("["); try { stmt = conn.createStatement(); rs = stmt.executeQuery(sql); ResultSetMetaData rsmd = rs.getMetaData(); RowSetDynaClass rsdc = new RowSetDynaClass(rs); List list = rsdc.getRows(); /*if ("".equals(id)) { String validValue = isValid(reportNum); json.append("{valid:").append(validValue).append("},"); String existsValue = this.isExists(reportNum); json.append("{exists:").append(existsValue).append("}"); } else {*/ String num = getReportNum(id); if (num.equals(reportNum)) { json.append("{valid:true},"); json.append("{exists:false}"); } else { String validValue = isValid(reportNum); json.append("{valid:").append(validValue).append("},"); String existsValue = this.isExists(reportNum); json.append("{exists:").append(existsValue).append("}"); } //} for (int j = 0, len = list.size(); j < len; j++) { json.append(",{"); DynaBean dyna = (DynaBean) list.get(j); for (int i = 1; i <= rsmd.getColumnCount(); i++) { if (i == rsmd.getColumnCount()) { json.append(rsmd.getColumnName(i)).append(":/"") .append(FunctionStatic.getNullString(BeanUtils.getSimpleProperty(dyna, rsmd.getColumnName(i).toLowerCase()))) .append("/""); } else { json.append(rsmd.getColumnName(i)).append(":/"") .append(FunctionStatic.getNullString(BeanUtils.getSimpleProperty(dyna, rsmd.getColumnName(i).toLowerCase()))) .append("/","); } } json.append("}"); /*if (j < len - 1) { json.append(","); }*/ } json.append("]"); } catch (Exception e) { e.printStackTrace(); throw e; } return json.toString(); } public String isValid(String reportNum) throws Exception { String bool = ""; try { prepar = conn.prepareStatement("select count(*) from MM_Consign where report_num = '" + reportNum + "'"); rs = prepar.executeQuery(); int count = rs.next() ? rs.getInt(1) : 0; bool = count > 0 ? "true" : "false"; } catch (Exception e) { e.printStackTrace(); throw e; } return bool; } public String isExists(String reportNum) throws Exception { String bool = ""; try { prepar = conn.prepareStatement("select count(*) from MM_ReportTransfer where report_num = '" + reportNum + "'"); rs = prepar.executeQuery(); int count = rs.next() ? rs.getInt(1) : 0; bool = count > 0 ? "true" : "false"; } catch (Exception e) { e.printStackTrace(); throw e; } return bool; } ~~~
';