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;
}
~~~