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

可以和后台进行互动,通过第一列的值进行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;  
    } 
文章导航