梦见你的名字 发表于 2024-6-23 18:42:19

C#结合JS实现HtmlTable动态添加行并生存到数据库

   
目次
需求
结果视频演示
范例运行环境
预备数据源
数据表计划
UI及表结构Json配置
Json数据包提交配置
计划实现
前端UI
Javascript 脚本
Jquery引用
C# 服务端操作 
小结


需求

在 Web 应用项目中,实现一对多录入的数据管理功能是一项常见的应用。因此可以实现一个相对轻量化的计划实现表格的录入,为保证功能的可用性、界面友爱性,总体的需求如下:
1、数据网格可以动态的添加行,行可以提供输入框、选择框的控件举行录入。
2、数据网格可以删除选中的行。
3、数据网格可以上下移动选中的行重新举行排序。
4、可以实现数据的有用性验证功能(如必填写、位数限定、类型限定等)。
5、需要对输入的笔墨过滤和屏蔽HTML标记等危险内容。
6、添加新行前判断已有行的有用性,对于未校验通过的暂不允许添加新行。
7、对于修改中的、生存时的、生存后的状态有肯定的相关提示信息。
8、数据生存实现动态无刷新。
结果视频演示

为实现需求会利用到用C# 编写服务端Web 静态方法,Jquery 实现 Ajax 无刷新技术并调用服务器方法,Json 存储数据表格需要的配置,客户端大部分计划利用 Javascript 实现。实现的结果演示视频如下:
   动态添加 HtmlTable 行并生存到数据库

范例运行环境

操作体系: Windows Server 2019 DataCenter
数据库:Microsoft SQL Server 2016
.net版本: .netFramework4.0 或以上
开发工具及相关技术:VS2019  C# 、Jquery 、Json、Javascript

预备数据源

数据表计划

我们在 MS SQL Server 创建 att_jypx(教育培训履历表),其结构如下表:
序号字段名类型说明1ciduniqueidentifier行唯一标识,唯一键2xmbhvarchar(20)外键父项,指项目编号3sfzhnvarchar(18)外键父项,指身份证号4nf1nvarchar(4)起始年份5yf1nvarchar(2)起始月份6nf2nvarchar(4)停止年份7yf2nvarchar(2)停止月份8xxmcnvarchar(100)学校名称9zynvarchar(50)所学专业10xlnvarchar(10)学历11byzlbnvarchar(50)结业证类别12xhint排序号 实行如下 创建表的 SQL 语句:
CREATE TABLE .(
        ROWGUIDCOLNOT NULL,
        (20) NOT NULL,
        (18) NOT NULL,
        (4) NULL,
        (2) NULL,
        (4) NULL,
        (2) NULL,
        (100) NULL,
        (50) NULL,
        (10) NULL,
        (50) NULL,
        NULL,
CONSTRAINT PRIMARY KEY CLUSTERED
(
        ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON
) ON
GO

ALTER TABLE . ADDCONSTRAINT DEFAULT (newid()) FOR
GO 数据表的别的说明如下:
1、CID字段为GUID类型,可用于标识 HtmlTable 的 Row 行对象的 ID 并用于存储。
2、xmbh 字段和 sfzh 字段是引用的外键,我们为了演示方便假设为 项目编号 为‘001’、身份证号为‘120102’
3、xh 为排序纪录序次所用。
以上的所述字段均不参与 HtmlTable 表格内容的呈现,以低落数据包的容量,只参与外键操作。
UI及表结构Json配置

对于 HtmlTable 表格内容的呈现、数据结构及数据验证的校验,我们将利用Json文件举行配置,配置说明如下:
序号项类型说明1maxRowCount字符允许添加的最大行数2mtable_style字符主体编辑HtmlTable的风格3ttable_style字符标题HtmlTable的风格4cols数组列数组定义变量,以下5到12均为 cols 所包含每一数组元素对象的属性5fname字符字段名6cname字符字段中文名或说明7 len数字字段长度8td_style字符HtmlTabelCell 单元格的风格9ctl_style字符单元格中输入或选择控件的风格10 input字符可输入 text 和 select,分别对应输入框和选择框11 list字符用于select选择框的选项设置,各选项间以 “|” 举行分隔12 check字符用于数据校验方案设置,假如设置请参考我的文章《C# 结合 JavaScript 对 Web 控件举行数据输入验证》
 完全的样例JSON如下:
 
{
"att_jypx":[
        {"maxRowCount":12,
          "mtable_style":"table-layout: fixed;word-break: break-all; word-wrap: break-word;font-size:10pt; width:700px; position:absolute;left:0px; border-color:rgb(235,235,235); border-width:1px 1px 1px 1px;border-collapse:collapse;",
          "ttable_style":"z-index:9999;position:fixed;left:0px;top:37px;table-layout: fixed;word-break: break-all; word-wrap: break-word;font-size:10pt; width:700px; background-color:rgb(235,235,235);border-color:rgb(235,235,235); border-width:1px 1px 1px 1px;border-collapse:collapse;",
          "cols": [
          {
              "fname": "nf1",
              "cname": "起始年份",
              "len":4,
              "td_style":"width:75px",
              "ctl_style":"width:70px;border-radius:2px;border-width:1px;",
              "input":"text",
              "list":"",
              "display":"",
              "check":"notnull|mustlen4|int"
          },
          {
             "fname": "yf1",
             "cname": "起始月份",
              "len":2,
              "td_style":"width:75px",
              "ctl_style":"width:70px;border-radius:2px;",
              "input":"select",
             "list":"01|02|03|04|05|06|07|08|09|10|11|12",
             "check":"notnull"
             },
          {
              "fname": "nf2",
              "cname": "截止年份",
              "len":4,
              "td_style":"width:75px",
              "ctl_style":"width:70px;border-radius:2px;border-width:1px;",
              "input":"text",
              "list":"",
              "display":"",
              "check":"notnull|mustlen4|int"
          },
          {
             "fname": "yf2",
             "cname": "截止月份",
              "len":2,
              "td_style":"width:75px",
              "ctl_style":"width:70px;border-radius:2px;",
              "input":"select",
             "list":"01|02|03|04|05|06|07|08|09|10|11|12",
             "check":"notnull"
             },
          {
             "fname": "xxmc",
             "cname": "所在院校",
              "len":100,
              "td_style":"width:200px;",
              "ctl_style":"width:195px;border-radius:2px;border-width:1px;",
              "input":"text",
             "list":"",
             "check":"notnull|maxlen100"
             },
           {
             "fname": "xl",
             "cname": "学历",
              "len":10,
              "td_style":"width:60px",
              "ctl_style":"width:55px;border-radius:2px;border-width:1px;",
              "input":"text",
             "list":"",
             "check":"notnull|maxlen10"
             },
          {
             "fname": "zy",
             "cname": "所学专业",
              "len":50,
              "td_style":"width:80px",
              "ctl_style":"width:75px;border-radius:2px;border-width:1px;",
              "input":"text",
             "list":"",
             "check":"notnull|maxlen50"
             },
          {
             "fname": "byzlb",
             "cname": "毕业证类别",
              "len":50,
              "td_style":"width:160px",
              "ctl_style":"width:155px;border-radius:2px;border-width:1px;",
              "input":"select",
             "list":"全日制普通高等教育毕业证|成人高等教育毕业证|高等教育自学考试毕业证|其他",
             "check":"notnull"
             }        ]
             }
       ]
} Json数据包提交配置

Json数据包根据Json配置信息通过服务端生成,紧张包括字段名的项,用于将来提交数据时利用,因为提交的数据方式仍然是Json数据对象,即Json数据包,生成的初始格式如下示例:
{"nf1":"",
"yf1":"",
"nf2":"",
"yf2":"",
"xxmc":"",
"zy":"",
"xmbh":"001",
"sfzh":"120102",
"xh":"",
"cid":"",
"com_name":"jypx"} 计划实现

前端UI

前端UI我们紧张放置一些中心变量控件,表格元素等,紧张元素说明见下表:
序号元素Id类型说明1curidTextBox用于纪录当前点行的ID2pjsonTextBox用于存储Json配置数据3djsonTextBox用于存储Json提交数据包4ttableHtmlTable标题列表格,用于固定显示表头5mtableHtmlTable主编辑表格对象6topnavsDiv一组固定于顶端的工具栏对象层,包括新增、删除、上移、下移、生存按钮 示例代码如下:
   <formrunat="server">
<asp:TextBox ID="cid" style="display:none" runat="server"></asp:TextBox>
<asp:TextBox ID="com_name" style="display:none" runat="server"></asp:TextBox>
<asp:TextBox ID="xmbh" style="display:none" runat="server"></asp:TextBox>
<asp:TextBox ID="sfzh" style="display:none" runat="server"></asp:TextBox>
<asp:TextBox ID="p_acode"Runat="server" Visible="true" style="display:none" ></asp:TextBox>
<asp:TextBox ID="curid"Runat="server" Visible="true" style="display:none" ></asp:TextBox>
<asp:TextBox ID="pjson" TextMode="MultiLine"Runat="server" Visible="true" style="display:none" ></asp:TextBox>
<asp:TextBox ID="djson" TextMode="MultiLine"Runat="server" Visible="true" style="display:none" ></asp:TextBox>
<div id="topnavs" runat="server" style=" z-index:9999; border-bottom: 1px solid silver; padding:3px;display:flex;justify-content:start; background-color:rgb(235,235,235); position:fixed;top:0px;left:0px;width:100%;height:30px; text-align:center; line-height:30px;">
<input id="closebutton" runat="server" type="button" value='' style=" border-width:0px; background-position:center; background-image:url(/images/att_add6.jpg);font-size:14pt;cursor:pointer;width:25px;height:25px;" onclick="addRow()" class="" />
<input id="Button1" runat="server" type="button" value='' style=" border-width:0px;background-position:center;background-image:url(/images/att_del.jpg); margin-left:5px; font-size:14pt;cursor:pointer;width:25px;height:25px;" onclick='delinfo()' class="" />
<input id="Button2" runat="server" type="button" value='' style="border-width:0px; background-position:center; background-image:url(/images/att_up2.jpg); margin-left:5px; font-size:14pt;cursor:pointer;width:25px;height:25px;" onclick="swarp(document.getElementById('curid').value,1);" class="" />
<input id="Button3" runat="server" type="button" value='' style="border-width:0px; background-position:center; background-image:url(/images/att_down3.jpg); margin-left:5px; font-size:14pt;cursor:pointer;width:25px;height:25px;" onclick="swarp(document.getElementById('curid').value,2);" class="" />
<input id="Button4" runat="server" type="button" value='' style="border-width:0px; background-position:center; background-image:url(/images/att_save.jpg); margin-left:5px; font-size:14pt;cursor:pointer;width:25px;height:25px;" onclick="if (validall('') == false) {document.getElementById('Button4').removeAttribute('disabled');return;}saveall();if(document.getElementById('mtable').rows.length>0){ this.setAttribute('disabled','true');}" class="" />
<div id="saved" style="margin-left:10px; font-weight:bold; font-size:11pt; color:Red; "></div>
</div>
<table align="left" id="ttable" runat="server" style="z-index:9999;position:fixed;left:0px;top:37px;table-layout: fixed;word-break: break-all; word-wrap: break-word;font-size:10pt; width:700px; background-color:rgb(235,235,235);border-color:rgb(235,235,235); border-width:1px 1px 1px 1px;border-collapse:collapse;"border="1" cellspacing="0" cellpadding="3">
</table>
<table align="left" id="mtable" runat="server" style="table-layout: fixed;word-break: break-all; word-wrap: break-word;font-size:10pt; width:700px; position:absolute;left:0px;top:67px; border-color:rgb(235,235,235); border-width:1px 1px 1px 1px;border-collapse:collapse;"border="1" cellspacing="0" cellpadding="3">
</table>
</form>

Javascript 脚本

Javascript 脚本实现表格编辑操作及通过Ajax与服务器方法通信,并生存数据的功能,紧张方法说明见下表:
序号方法名称参数说明1simplecheck chkobj:单元格对象
_chkvalue:单元格编辑的值
 allowAlert:是否允许弹出提示
etip:弹出提示的扩展前缀字串
本方法用于数据有用性的校验

2swarp mId:当前行的ID
stype:移动方向,1上移,2下移
用于对选中行的移动排序操作3chnRowSelColorrowobj:当前行对象用于高亮显示选中行的颜色,并同时将当前行设置为可编辑状态4tojsonstrstr:输入的值对输入的值举行安全检测,并移除HTML标记,对单引号双引号做特殊处理,以保证JSON字符串传递的字符合法性5saveall生存全部行纪录并提交数据库操作6delinfo删除当前选中的行并提交数据库操作7validallextip:附加的前缀性提示生存前对全部行举行数据有用性校验8validchangeobj:当前编辑的控件元素提示用户当前正修改哪个控件元素的值9validsaveextip:附加的前缀性提示用于检验是否正有生存的纪录10addRow添加一个新行并提交到数据库操作11gGuid用于增加新行时生成一个GUID字符串12ScrollToBottom用于增加新行时自动滚动到页面底部 完备示例代码如下:
   <script language="javascript">
    function simplecheck(chkobj, _chkvalue, allowAlert,etip) {
      check_result = true; check_errid = ''; check_errmsg = '';var _checkSchema = chkobj.getAttribute('checkSchema');var _cName = chkobj.getAttribute('cName');
      if (_checkSchema.indexOf('ctrim') != -1) { _chkvalue = ctrim(_chkvalue); } var _objlength = _chkvalue.length; if (_checkSchema.indexOf('abslen') != -1) { _objlength = PositionLen(_chkvalue); }
      var _schemaList = _checkSchema.split('|'); var _reqeustnotnull = false;
      for (var k = 0; k < _schemaList.length; k++) { if (_schemaList.toLowerCase() == 'notnull') { _reqeustnotnull = true; } }
      if ((!_reqeustnotnull) && (_chkvalue == '')) { return check_result; }
      for (var j = 0; j < _schemaList.length; j++) {
            var curSchema = _schemaList.toLowerCase(); check_errid = curSchema; var curErrmsg = ''; switch (true) { case curSchema == 'notnull': check_result = isNotNull(_chkvalue); curErrmsg = _cName + '需要填写内容!'; break; case curSchema == 'number': check_result = isNumber(_chkvalue); curErrmsg = _cName + ' 输入的数值不合理,请核对!'; break; case curSchema == 'bnumber': check_result = isBNumber(_chkvalue); curErrmsg = _cName + ' 输入的数值应为>=0的正数,请核对!'; break; case curSchema == 'snumber': check_result = isSNumber(_chkvalue); curErrmsg = _cName + ' 输入的数值应为<0的负数,请核对!'; break; case curSchema == 'date': check_result = isDate(_chkvalue, _cName); check_errid = 'date'; check_errmsg = (check_result ? '' : _cName + ' 输入的日期不合理,请核对!'); curErrmsg = ''; break; case curSchema.indexOf('minlen') != -1: var _slen = parseInt(curSchema.substr('minlen'.length, curSchema.length - 'minlen'.length), 10); if (isNaN(_slen)) { check_result = false; curErrmsg = _cName + ' 输入的最小位数参数不合理,请与软件供应商联系!'; } else { check_result = (_objlength < _slen ? false : true); curErrmsg = _cName + ' 的内容要求最小输入' + _slen + '位,请核对!'; } break; case curSchema.indexOf('maxlen') != -1: var _slen = parseInt(curSchema.substr('maxlen'.length, curSchema.length - 'maxlen'.length), 10); if (isNaN(_slen)) { check_result = false; curErrmsg = _cName + ' 输入的最大位数参数不合理,请与软件供应商联系!'; } else { check_result = (_objlength > _slen ? false : true); curErrmsg = _cName + ' 最大允许输入' + _slen + '位,请核对!'; } break; case curSchema.indexOf('mustlen') != -1: var _slen = parseInt(curSchema.substr('mustlen'.length, curSchema.length - 'mustlen'.length), 10); if (isNaN(_slen)) { check_result = false; curErrmsg = _cName + ' 输入的限制位数参数不合理,请与软件供应商联系!'; } else { check_result = (_objlength != _slen ? false : true); curErrmsg = _cName + ' 的内容输入长度只能是' + _slen + '位,请核对!'; } break; case curSchema == 'time': check_result = validRegs(_chkvalue, /^\d{1,2}:\d{1,2}:\d{1,2}$/); curErrmsg = _cName + ' 输入的时间不合理,请核对。'; break; case curSchema == 'alpha': check_result = isAlpha(_chkvalue); curErrmsg = _cName + ' 只能输入的数字、字母和下划线,请核对。'; break; case curSchema == 'mail': check_result = validRegs(_chkvalue, /^()+@()+(\.)+/); curErrmsg = _cName + ' 输入的邮件地址不合理,请核对。'; break; case curSchema == 'phone': check_result = validRegs(_chkvalue, /({8,})$/); curErrmsg = _cName + ' 输入的电话号码不合理,请核对。'; break; case curSchema == 'mobile': check_result = validRegs(_chkvalue, /^1(3|5|8)\d{8}$/); curErrmsg = _cName + ' 输入的手机号码不合理,请核对。'; break; case curSchema == 'money': check_result = validRegs(_chkvalue, /^\d+(\.\d+)?$/); curErrmsg = _cName + ' 输入的内容不符合货币类型的要求,请核对。'; break; case curSchema == 'zip': check_result = validRegs(_chkvalue, /^\d{5}$/); curErrmsg = _cName + ' 输入的邮政编码不合理,请核对。'; break; case curSchema == 'int': check_result = validRegs(_chkvalue, /^[-\+]?\d+$/); curErrmsg = _cName + ' 需要输入一个整数,请核对。'; break; case curSchema == 'en': check_result = validRegs(_chkvalue, /^+$/); curErrmsg = _cName + ' 只能输入英文大小写字母,请核对。'; break; case curSchema == 'cn': check_result = validRegs(_chkvalue, /^[\u0391-\uFFE5]+$/); curErrmsg = _cName + ' 只能输入中文,请核对。'; break; case curSchema == 'url': check_result = validRegs(_chkvalue, /([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/); curErrmsg = _cName + ' 输入的网址不合理,请核对。'; break; case curSchema == 'idcard18': rv_result = checkIdcard(_chkvalue); check_result = (rv_result == '' ? true : false); curErrmsg = _cName + rv_result; break; case curSchema == 'idcard15': rv_result = checkIdcard(_chkvalue); check_result = (rv_result == '' ? true : false); curErrmsg = _cName + rv_result; break; case curSchema == 'idcard': rv_result = checkIdcard(_chkvalue); check_result = (rv_result == '' ? true : false); curErrmsg = _cName + rv_result; break; } if (!check_result) {
                if (curErrmsg != '') { check_errmsg = etip + curErrmsg; } if ((curErrmsg != '') && (allowAlert)) { document.getElementById('saved').innerHTML = etip + curErrmsg; alert(etip + curErrmsg); return check_result; }
            }
      }
      return check_result;
    }
    function checkIdcard(idcard) {
      var _idcard = idcard;var Errors = new Array('', '身份证号码位数不对!', '身份证号码出生日期超出范围或含有非法字符!', '身份证号码校验错误!', '身份证地区非法!', '');
      if (_idcard == '') { return Errors; }
      var area = { 11: '北京', 12: '天津', 13: '河北', 14: '山西', 15: '内蒙古', 21: '辽宁', 22: '吉林', 23: '黑龙江', 31: '上海', 32: '江苏', 33: '浙江', 34: '安徽', 35: '福建', 36: '江西', 37: '山东', 41: '河南', 42: '湖北', 43: '湖南', 44: '广东', 45: '广西', 46: '海南', 50: '重庆', 51: '四川', 52: '贵州', 53: '云南', 54: '西藏', 61: '陕西', 62: '甘肃', 63: '青海', 64: '宁夏', 65: '新疆', 71: '台湾', 81: '香港', 82: '澳门', 91: '国外' }
      var _idcard, Y, JYM; var S, M; var idcard_array = new Array(); idcard_array = _idcard.split('');
      if (area == null) { return Errors; }
      switch (_idcard.length) {
            case 15: if ((parseInt(_idcard.substr(6, 2)) + 1900) % 4 == 0 || ((parseInt(_idcard.substr(6, 2)) + 1900) % 100 == 0 && (parseInt(_idcard.substr(6, 2)) + 1900) % 4 == 0)) {
                  ereg = /^{5}{2}((01|03|05|07|08|10|12)(0||3)|(04|06|09|11)(0||30)|02(0|)){3}$/;
                } else {
                  ereg = /^{5}{2}((01|03|05|07|08|10|12)(0||3)|(04|06|09|11)(0||30)|02(0|1|2)){3}$/;
                }
                if (ereg.test(_idcard)) {
                  var iS = 0; var iW = new Array; iW = 7; iW = 9; iW = 10; iW = 5; iW = 8; iW = 4; iW = 2; iW = 1; iW = 6; iW = 3; iW = 7; iW = 9; iW = 10; iW = 5; iW = 8; iW = 4; iW = 2;
                  var LastCode = '10X98765432'; var perIDNew; perIDNew = _idcard.substr(0, 6); perIDNew += '19'; perIDNew += _idcard.substr(6, 9);
                  for (var i = 0; i < 17; i++) { iS += parseInt(perIDNew.substr(i, 1)) * iW; }
                  var iY = iS % 11; perIDNew += LastCode.substr(iY, 1);
                  return Errors;
                } else {
                  return Errors;
                }
                break;
            case 18: if (parseInt(_idcard.substr(6, 4)) % 4 == 0 || (parseInt(_idcard.substr(6, 4)) % 100 == 0 && parseInt(_idcard.substr(6, 4)) % 4 == 0)) {
                  ereg = _idcard.substr(6, 2) == '19' ? /^{5}19{2}((01|03|05|07|08|10|12)(0||3)|(04|06|09|11)(0||30)|02(0|)){3}$/ : /^{5}20{2}((01|03|05|07|08|10|12)(0||3)|(04|06|09|11)(0||30)|02(0|)){3}$/;
                } else {
                  ereg = _idcard.substr(6, 2) == '19' ? /^{5}19{2}((01|03|05|07|08|10|12)(0||3)|(04|06|09|11)(0||30)|02(0|1|2)){3}$/ : /^{5}20{2}((01|03|05|07|08|10|12)(0||3)|(04|06|09|11)(0||30)|02(0|1|2)){3}$/;
                }
                if (ereg.test(_idcard)) {
                  S = (parseInt(idcard_array) + parseInt(idcard_array)) * 7 + (parseInt(idcard_array) + parseInt(idcard_array)) * 9 + (parseInt(idcard_array) + parseInt(idcard_array)) * 10 + (parseInt(idcard_array) + parseInt(idcard_array)) * 5 + (parseInt(idcard_array) + parseInt(idcard_array)) * 8 + (parseInt(idcard_array) + parseInt(idcard_array)) * 4 + (parseInt(idcard_array) + parseInt(idcard_array)) * 2 + parseInt(idcard_array) * 1 + parseInt(idcard_array) * 6 + parseInt(idcard_array) * 3;
                  Y = S % 11; M = 'F'; JYM = '10X98765432'; M = JYM.substr(Y, 1); if (M == idcard_array) return Errors; else { return Errors; }
                } else { return Errors; } break; default: return Errors; break;
      }
    }
    function getid(id) { alert(checkIdcard(id)) }
    function per18To15(perIDSrc) { rstr = ''; for (var i = 0; i < 17; i++) { if ((i == 6) || (i == 7)) { continue; } rstr += perIDSrc.charAt(i); } return rstr; }
    function per15To18(perIDSrc) {
      var iS = 0; var iW = new Array;
      iW = 7; iW = 9; iW = 10; iW = 5; iW = 8; iW = 4; iW = 2; iW = 1; iW = 6; iW = 3; iW = 7; iW = 9; iW = 10; iW = 5; iW = 8; iW = 4; iW = 2;
      var LastCode = '10X98765432'; var perIDNew; perIDNew = perIDSrc.substr(0, 6); perIDNew += '19'; perIDNew += perIDSrc.substr(6, 9);
      for (var i = 0; i < 17; i++) { iS += parseInt(perIDNew.substr(i, 1)) * iW; }
      var iY = iS % 11; perIDNew += LastCode.substr(iY, 1); return perIDNew;
    }
    var aCity = { 11: '北京', 12: '天津', 13: '河北', 14: '山西', 15: '内蒙古', 21: '辽宁', 22: '吉林', 23: '黑龙江', 31: '上海', 32: '江苏', 33: '浙江', 34: '安徽', 35: '福建', 36: '江西', 37: '山东', 41: '河南', 42: '湖北', 43: '湖南', 44: '广东', 45: '广西', 46: '海南', 50: '重庆', 51: '四川', 52: '贵州', 53: '云南', 54: '西藏', 61: '陕西', 62: '甘肃', 63: '青海', 64: '宁夏', 65: '新疆', 71: '台湾', 81: '香港', 82: '澳门', 91: '国外' }
    function cidInfo(sId) {
      var iSum = 0; var info = '';
      if (!/^\d{17}(\d|x)$/i.test(sId))
            return false; sId = sId.replace(/x$/i, 'a');
      if (aCity == null) return 'Error:非法地区'; sBirthday = sId.substr(6, 4) + '-' + Number(sId.substr(10, 2)) + '-' + Number(sId.substr(12, 2));
      var d = new Date(sBirthday.replace(/-/g, '/'))
      if (sBirthday != (d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate()))
            return 'Error:非法生日';
      for (var i = 17; i >= 0; i--) iSum += (Math.pow(2, i) % 11) * parseInt(sId.charAt(17 - i), 11)
      if (iSum % 11 != 1) return 'Error:非法证号';
      return aCity + ',' + sBirthday + ',' + (sId.substr(16, 1) % 2 ? '男' : '女')
    }
function PositionLen(s){var i,str1,str2,str3,nLen;        str1 =s;nLen = 0;for(i=1;i<=str1.length;i++){str2=str1.substring(i-1,i);str3=escape(str2);if(str3.length>3){        nLen = nLen + 2;}else{nLen = nLen + 1;}        }
return nLen;}
function isNotNull(str){return (str==''?false:true);}
function isNumber(str){if(str==''){return true;}return (isNaN(str)?false:true);}
function isNumber(str){if(str==''){return true;}return (isNaN(str)?false:true);}
function isBNumber(str){if(str==''){return true;}return (!isNaN(str)?parseInt(str,10)>=0?true:false:false);}
function isSNumber(str){if(str==''){return true;}return (!isNaN(str)?parseInt(str,10)<0?true:false:false);}
function isAlpha(_str){return (_str.replace(/\w/g,'').length == 0);}
function isAN(_str){var reg = /^((++)|(++))*$/i;return reg.test(_str);}
function validRegs(_value,_Regs){return _Regs.test(_value); }
function isVisibled(obj){   if( (obj.style.display=='none')||( (obj.offsetHeight==0)&&(obj.offsetWidth==0) ) )       return false; if(obj.currentStyle){if(obj.currentStyle['display']=='none') return false;}return true;}
function isFocused(obj){   if( (obj.disabled==false)&&(isVisibled(obj)) )       return true;   return false;}
function isDate(str,cname,notip){if(str==''){return true;}
str=str.replace(/\//g,'-');
dt=str.split(' ');if(dt.length>2){if(!notip) alert(cname+'日期输入不正确!可能包括非法的日期组成部分。');return false;        } dt1=dt.split('-');if(dt1.length!=3){if(!notip)         alert(cname+'日期输入不正确!日期部分应为YYYY-MM-DD。');return false;}dt1n=(dt1+dt1+dt1).split('');for(var i=0;i<dt1.length;i++){if((isNaN(dt1)||(ctrim(dt1)==''))){if(!notip)         alert(cname+'字符:'+dt1+',年月日部分必须输入数字!');        return false;}        }_year=parseInt(dt1,10);        _month=parseInt(dt1,10);        _day=parseInt(dt1,10);if((_year<1000)||(_year>9999)||(_month<1)||(_month>12)||(_day<1)||(_day>31)){if(!notip) alert(cname+'年月日部分输入的数字不合理,请核对!');return false;        }v_date31=new Array;v_date31=4;v_date31=6;v_date31=9;v_date31=11;if((getArrayIndex(v_date31,_month)!=-1)&&(_day>30)){if(!notip) alert(cname+'月份:'+_month+',天数输入范围不合理!');        return false;}if(_month==2){        if(((_year%4==0)&&(_year%100!=0))||(_year%400==0)){        if(_day>29){if(!notip) alert(cname+'月份:'+_month+',天数输入范围不合理!');return false;        }}else{        if(_day>28){if(!notip) alert(cname+'月份:'+_month+',天数输入范围不合理!');return false;        }}        }        return true;   }
function getArrayIndex(xArray,find){_rs=-1;for(var j=0;j<xArray.length;j++){if(xArray==find){_rs=j;        break;         }}        return _rs;        }
function ctrim(ename){ if(ename==undefined) return '';        return (ename.replace(/(^\s*)|(\s*$)/g, '')).replace(/^[\s \t]+|[\s \t]+$/, '');}


    var RowsCount = 0;
    var ErrorMessage = "";

    function swarp(mId, stype) {
      var mObj = document.getElementById(mId);
      if (mObj == undefined) {
            return false;
      }
      var premObj = mObj.previousElementSibling;
      if (stype == 2) {
            premObj = mObj.nextElementSibling;
      }
      if (premObj == null) return false;
      if (stype == 1) {
            mObj.parentNode.insertBefore(mObj, premObj);
      } else if (stype == 2) {
            mObj.parentNode.insertBefore(premObj, mObj);
      }
    }
    function setrow(rowobj) {
      document.getElementById('curid').value = rowobj.id;
      chnRowSelColor(rowobj);
    }
    function chnRowSelColor(rowobj) {
      var _com = "att_" + document.getElementById('com_name').value;
      var mt = document.getElementById('mtable');
      for (var i = 0; i < mt.rows.length; i++) {
            var mt_row = mt.rows;
            mt_row.style.backgroundColor = '';
            if (mt_row.id == rowobj.id) {continue;}
            for (var j = 0; j < mt_row.cells.length; j++) {
                var cell1 = mt_row.cells;
                if (cell1.getElementsByTagName('input').length > 0) {
                  cell1.innerHTML = cell1.getElementsByTagName('input').value.replace(/<[^>]*>/g, '');
                }else
                if (cell1.getElementsByTagName('select').length > 0) {
                        cell1.innerHTML = cell1.getElementsByTagName('select').value.replace(/<[^>]*>/g, '');
                }
            }
      }
      rowobj.style.backgroundColor = 'rgb(235,235,235)';
      var pj = JSON.parse(document.getElementById('pjson').value);
      var jtcy = pj.cols;
      var isadd = false;
      if (rowobj.cells.length == 0) {
            isadd = true;
      }
      for (var i = 0; i < jtcy.length; i++) {
            var cell1 = isadd==true?rowobj.insertCell(i):rowobj.cells;
            var ctype = jtcy.input;
            var innerhtml = "";
            var oldvalue = "";
            if(isadd==true){
                cell1.setAttribute("checkSchema",jtcy.check);
                cell1.setAttribute("cName",jtcy.cname);
            }
            if (ctype == "text") {
                oldvalue = cell1.innerText;
                innerhtml = "<input type='" + ctype + "' onchange='validchange(this)' placeholder='" + jtcy.cname + "'style='" + jtcy.ctl_style + "'/>";
            } else if (ctype == "select") {
                oldvalue = cell1.innerText;
                innerhtml = "<" + ctype + " onchange='validchange(this)' style='" + jtcy.ctl_style + "' />";
                innerhtml += "<option value=''>" + jtcy.cname + "</option>";
                var items = jtcy.list.split("|");
                for (var j = 0; j < items.length; j++) {
                  innerhtml += "<option>" + items + "</option>";
                }
                innerhtml += "</" + ctype + ">";
            }
            cell1.innerHTML = innerhtml;
            cell1.style = jtcy.td_style;
            cell1.addEventListener('click', function (event) {
                event.stopPropagation();
                if (cell1.parentNode.id != document.getElementById('curid').value) {
                  setrow(cell1.parentNode);
                }
            });
            if (cell1.getElementsByTagName('input').length > 0) {
                cell1.getElementsByTagName('input').value=oldvalue;
                cell1.getElementsByTagName('input').addEventListener('click', function (event) {
                  event.stopPropagation();
                });
            } else if (cell1.getElementsByTagName('select').length > 0) {
                cell1.getElementsByTagName('select').value = oldvalue;
                cell1.getElementsByTagName('select').addEventListener('click', function (event) {
                  event.stopPropagation();
                });
            }
      }

    }
    function ss(type, result) {
      try {
            var robj = JSON.parse(result);
            if (robj.errcode != 0) {
                ErrorMessage = robj.errmsg;
                alert(ErrorMessage);
            } else {
                RowsCount++;
            }
      } catch (ss_e) {
            ErrorMessage=(ss_e);
            alert(ErrorMessage);
      }
      if (RowsCount == document.getElementById('mtable').rows.length) {
            document.getElementById('Button4').removeAttribute("disabled");
            document.getElementById('saved').style.color = 'green';
            document.getElementById('saved').innerHTML = "保存所有成功。";
            window.setTimeout(function () {
                document.getElementById('saved').style.color = 'red';
                document.getElementById('saved').innerHTML = "";
            }, 1000);


            callServerFunction("", "save_att_data", "{ypz_cid:'" +document.getElementById('cid').value+"',com_name:'"+document.getElementById('com_name').value + "'}", ss4);
      }
    }
    function ss4(type, result) {
      if (JSON.stringify(result) == "\"true\"") {
      } else {
            alert('同步更新简历信息失败,请点击修改简历按钮提交修改。' + JSON.stringify(result));
      }
    }
    function ss3(type, result) {
      try {
            var robj = JSON.parse(result);
            if (robj.errcode != 0) {
                ErrorMessage = robj.errmsg;
                alert(ErrorMessage);
            } else {
                RowsCount++;
            }
      } catch (ss3_e) {
            ErrorMessage = (ss3_e);
            alert(ErrorMessage);
      }
    }
    function tojsonstr(str) {
      var prv = str.replace(/["\\]/g, '\\$&').replace(/<[^>]*>/g, '').replace(/<[^>]*>/g, '') ;
      return prv;
    }
    function saveall() {
      var mt = document.getElementById('mtable');
      if (mt.rows.length == 0) {
            document.getElementById('saved').style.color = '#4169E1';
            document.getElementById('saved').innerHTML = "请添加行后再执行保存操作...";
            window.setTimeout(function () {
                document.getElementById('saved').style.color = 'red';
                document.getElementById('saved').innerHTML = "";
            }, 3000);
            return;
      }
      RowsCount = 0;
      ErrorMessage = "";
      document.getElementById('saved').style.color = '#4169E1';
      document.getElementById('saved').innerHTML = "正在保存...";

      var _com = "att_" + document.getElementById('com_name').value;
      var pj = JSON.parse(document.getElementById('pjson').value);
      var dj = JSON.parse(document.getElementById('djson').value);
      var jtcy = pj.cols;
      for (var i = 0; i < mt.rows.length; i++) {
            var mt_row = mt.rows;
            dj.cid = mt_row.id;
            dj.sortid = (i + 1);
            for (var j = 0; j < mt_row.cells.length; j++) {
                var cell1 = mt_row.cells;
                var _value = cell1.innerText;
                if (cell1.getElementsByTagName('input').length > 0) {
                  _value = cell1.getElementsByTagName('input').value;
                } else if (cell1.getElementsByTagName('select').length > 0) {
                  _value = cell1.getElementsByTagName('select').value;
                }
                dj.fname] =tojsonstr(_value);
            }
            callServerFunction("", "saveInfo", "{jdata:'" + JSON.stringify(dj).replace(/['\\]/g, '\\$&') + "'}", ss);
      }
    }
    function ss2(type, result) {
      try {
            var robj = JSON.parse(result);
            if (robj.errcode != 0) {
                ErrorMessage = robj.errmsg;
                alert(ErrorMessage);
            } else {
                RowsCount++;
                var curid = document.getElementById('curid').value;
                var mt_row = document.getElementById(curid);
                document.getElementById('mtable').deleteRow(mt_row.rowIndex);
                document.getElementById('saved').style.color = 'red';
                document.getElementById('saved').innerHTML = "";
                alert('删除当前行成功!');
            }
      } catch (ss2_e) {
            ErrorMessage = (ss2_e);
            alert(ErrorMessage);
      }
    }

    function delinfo() {
      var curid = document.getElementById('curid').value;
      if (curid == "") {
            alert('请选中记录后再执行删除操作。');
            return;
      }
      RowsCount = 0;
      ErrorMessage = "";
      var _com = "att_" + document.getElementById('com_name').value;
      var dj = JSON.parse(document.getElementById('djson').value);
      var mt_row = document.getElementById(curid);
      dj.cid = mt_row.id;
      callServerFunction("", "deleteInfo", "{jdata:'" + JSON.stringify(dj).replace(/['\\]/g, '\\$&') + "'}", ss2);
    }
    function validall(extip) {
      

      var _com = "att_" + document.getElementById('com_name').value;
      var mt = document.getElementById('mtable');

      var pj = JSON.parse(document.getElementById('pjson').value);
      var dj = JSON.parse(document.getElementById('djson').value);
      var jtcy = pj.cols;
      for (var i = 0; i < mt.rows.length; i++) {
            var mt_row = mt.rows;
            for (var j = 0; j < mt_row.cells.length; j++) {
                var cell1 = mt_row.cells;
                var _value = cell1.innerText;
                if (cell1.getElementsByTagName('input').length > 0) {
                  _value = cell1.getElementsByTagName('input').value;
                } else if (cell1.getElementsByTagName('select').length > 0) {
                  _value = cell1.getElementsByTagName('select').value;
                }
                var isvalid = simplecheck(cell1, _value, true, extip+"第" + (i + 1) + "行:");
                if (isvalid == false) {
                  mt_row.style.backgroundColor = '#B22222';
                  
                  return false;
                }
            }
      }
      return true;
    }
    function validchange(obj) {
      document.getElementById('saved').innerText = '修改了'+obj.parentNode.getAttribute('cname')+'待保存';
    }
    function validsave(extip) {
      if (document.getElementById('saved').innerText != '') {
            return false;
      }
      return true;
    }
    function addRow() {
      if (validall('') == false) {
            return;
      }
      RowsCount = 0;
      ErrorMessage = "";

      var _com = "att_" + document.getElementById('com_name').value;
      var pj = JSON.parse(document.getElementById('pjson').value);
      
      var jtcy=pj.cols;
      var mt = document.getElementById('mtable');
      var maxCount = parseInt(pj.maxRowCount, 10);
      if (mt.rows.length >= maxCount) {
            alert("本内容最多允许添加" + maxCount + "行。");
            return;
      }
      var row = mt.insertRow(-1); // -1 表示在表的末尾插入新行
      row.id = gGuid();
      row.setAttribute("onclick", "setrow(this)");
      setrow(row);
      var dj = JSON.parse(document.getElementById('djson').value);
      dj["cid"] = row.id;
      dj["sortid"] = mt.rows.length;

      callServerFunction("", "saveInfo", "{jdata:'" + JSON.stringify(dj) + "'}", ss3);
      document.getElementById('saved').style.color = 'red';
      document.getElementById('saved').innerHTML = "添加新行未保存";
      ScrollToBottom();
    }
    function gGuid() {
      return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(//g, function (c) {
            var r = Math.floor(Math.random() * 16);
            var v = c === 'x' ? r : (r & 0x3 | 0x8);
            return v.toString(16);
      });
    }
    function ScrollToBottom() {
      $("html, body").animate({ scrollTop: $(document).height() - $(window).height() });
    }
</script>

Jquery引用

这是一组基于Jquery的自定义开发的扩展应用库,请下载我的资源:
https://download.csdn.net/download/michaelline/88615565
举行引用,本库用于调用服务器静态方法等功能利用。
C# 服务端操作 

服务端紧张用于对已有数据的提取显示并初始化到主编辑表中的行,并提供生存及删除操作的静态方法,紧张方法说明见下表:
序号方法名返回类型说明1public void InitPage()void紧张用于提取已有数据表数据并显示到主编辑表 mtable 的数据行,怎样提取数据请参照我的文章  《C# 利用IDbDataAdapter / IDataReader 实现通用数据集获取》 
2public static string saveInfo(string jdata)string 生存行信息到数据表,参数为提交的Json数据包,
生存数据操作请参照我的文章《C#利用IDbCommand实现通用数据库脚本实行程序》
3public static string deleteInfo(string jdata)string删除行信息到数据表,参数为提交的Json数据包,生存数据库操作请参照我的文章《C#利用IDbCommand实现通用数据库脚本实行程序》4private static string String2Json(String s)string规范字符串,以符合Json字符串要求 实现示例代码如下:
   <%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%@ Import Namespace="System.Data"%>
<%@ Import NameSpace="System.Data.SqlClient"%>
<%@ Import Namespace="System.IO"%>
<%@ Import Namespace="System.Web.Services"%>
<script language="C#" runat="server">
public CosysJaneCommonAPI.CODAL dal = new CosysJaneCommonAPI.CODAL();
void Page_Load(Object sender, EventArgs e)
{
    if (Page.IsPostBack) { return; }
    InitPage();
}

public void InitPage()
{
    dal.RunAt = Page.Form;
    string _xmbh = "001";
    string _p_att_json = pjson.Text;
    string _sfzh = "120102";
    xmbh.Text = _xmbh;
    sfzh.Text = _sfzh;
   
    com_name.Text = Request.QueryString["com_name"];
    Newtonsoft.Json.Linq.JObject jobj = Newtonsoft.Json.Linq.JObject.Parse(pjson.Text);
    djson.Text = "{";
    _sql = "select ";
    HtmlTableRow trow = new HtmlTableRow();
    ttable.Attributes["style"] = jobj["att_" + com_name.Text]["ttable_style"].ToString();
    mtable.Attributes["style"] = jobj["att_" + com_name.Text]["mtable_style"].ToString();
    for (int i = 0; i < jobj["att_" + com_name.Text]["cols"].Count(); i++)
    {
      HtmlTableCell tcell = new HtmlTableCell();
      tcell.InnerText = jobj["att_" + com_name.Text]["cols"]["cname"].ToString();
      tcell.Attributes["style"] = jobj["att_" + com_name.Text]["cols"]["td_style"].ToString();
      trow.Cells.Add(tcell);
      djson.Text += string.Format("\"{0}\":\"{1}\",", jobj["att_" + com_name.Text]["cols"]["fname"].ToString(), "");
      _sql += jobj["att_" + com_name.Text]["cols"]["fname"].ToString() + ",";
    }
    ttable.Rows.Add(trow);
    djson.Text += string.Format("\"{0}\":\"{1}\"", "xmbh", _xmbh);
    djson.Text += string.Format(",\"{0}\":\"{1}\"", "sfzh",_sfzh);
    djson.Text += string.Format(",\"{0}\":\"{1}\"", "sortid", "");
    djson.Text += string.Format(",\"{0}\":\"{1}\"", "cid", "");
    djson.Text += string.Format(",\"{0}\":\"{1}\"", "com_name", com_name.Text);
    djson.Text += "}";
    _sql = _sql + "cid from att_" + com_name.Text+" where xmbh=@xmbh and sfzh=@sfzh order by sortid";
    paras.Clear();
    paras.Add(new SqlParameter("xmbh", _xmbh));
    paras.Add(new SqlParameter("sfzh", _sfzh));
    rv = dal.GetDataSet(_sql, paras);
    if (dal.ErrorMessage != "")
    {
      return;
    }
    topnavs.Visible = true;
    ttable.Style["top"] = "37px";
    mtable.Style["top"] = "67px";
    if (dal.RowsCount == 0)
    {
      return;
    }
    dt = ((DataSet)rv).Tables;

    for (int i = 0; i < dt.Rows.Count; i++)
    {
      HtmlTableRow hrow = new HtmlTableRow();
      if (_zwmc == "" || (_bcbz == "true" && _bcsm != ""))
      {
            hrow.Attributes["onclick"] = "setrow(this)";
      }
      hrow.ID = dt.Rows["cid"].ToString();
      for (int j = 0; j < dt.Columns.Count-1; j++)
      {
            HtmlTableCell hcell = new HtmlTableCell();
            hcell.Attributes["style"] = jobj["att_" + com_name.Text]["cols"]["td_style"].ToString();
            hcell.Attributes["cName"] = jobj["att_" + com_name.Text]["cols"]["cname"].ToString();
            hcell.Attributes["checkSchema"] = jobj["att_" + com_name.Text]["cols"]["check"].ToString();
            hcell.InnerText = dt.Rows.ToString()].ToString();
            hrow.Cells.Add(hcell);
      }
      mtable.Rows.Add(hrow);
    }

}

public static string saveInfo(string jdata)
{
    Newtonsoft.Json.Linq.JObject jobj = Newtonsoft.Json.Linq.JObject.Parse(jdata);
    string tablename = "";
    string inssql = "";
    string inslist = "";
    string insparas = "";
    string updsql = "";
    string updparas = "";
    ArrayList paras = new ArrayList();
    paras.Clear();

    foreach (KeyValuePair<string, Newtonsoft.Json.Linq.JToken> kvp in jobj)
    {
      string key = kvp.Key.ToString();
      string value = kvp.Value.ToString();
      if (key == "com_name" && (value == "jtcy" || value == "shgx" || value == "jypx" || value == "gzjl"))
      {
            tablename = "att_"+value;
      }
      else
      {
            inslist += key + ",";
            insparas +="@"+ key + ",";
            updparas += string.Format(" {0}=@{1},",key,key);
            paras.Add(new SqlParameter(key, value));
      }
    }
    if (inslist.Length > 1)
    {
      inslist = inslist.Substring(0, inslist.Length - 1);
      insparas = insparas.Substring(0, insparas.Length - 1);
      inssql = string.Format("insert into {0} ({1}) values({2});", tablename, inslist, insparas);
    }
    if (updparas.Length > 1)
    {
      updparas = updparas.Substring(0, updparas.Length - 1);
      updsql = string.Format("update {0} set {1} where cid=@cid;", tablename, updparas);
    }
    string sql = string.Format(" if not exists(select cid from {0} where cid=@cid) begin {1} end else begin {2} end", tablename, inssql, updsql);
   
    CosysJaneCommonAPI.CODAL dal = new CosysJaneCommonAPI.CODAL();
   dal.ExecDbScripts(sql, paras);
   string rv = "{\"errcode\":0,\"errmsg\":\"\"}";
   if (dal.ErrorMessage != "")
   {
       rv="{\"errcode\":2,\"errmsg\":\""+String2Json(dal.ErrorMessage)+"\"}";
   }
   else if (dal.RowsCount == 0)
   {
       rv = "{\"errcode\":1,\"errmsg\":\"" + String2Json("未成功更新记录。") + "\"}";
   }
    return rv;
}

public static string deleteInfo(string jdata)
{
    Newtonsoft.Json.Linq.JObject jobj = Newtonsoft.Json.Linq.JObject.Parse(jdata);
    string tablename = "";
    string updsql = "";
    string updparas = "";
    ArrayList paras = new ArrayList();
    paras.Clear();

    foreach (KeyValuePair<string, Newtonsoft.Json.Linq.JToken> kvp in jobj)
    {
      string key = kvp.Key.ToString();
      string value = kvp.Value.ToString();
      if (key == "com_name" && (value == "jtcy" || value == "shgx"|| value == "jypx" || value == "gzjl"))
      {
            tablename = "att_"+value;
      }
      else if(key=="cid")
      {
            paras.Add(new SqlParameter(key, value));
      }
    }
    updsql = string.Format("delete from {0} where cid=@cid;", tablename);

    CosysJaneCommonAPI.CODAL dal = new CosysJaneCommonAPI.CODAL();
    dal.ExecDbScripts(updsql, paras);
    string rv = "{\"errcode\":0,\"errmsg\":\"\"}";
    if (dal.ErrorMessage != "")
    {
      rv = "{\"errcode\":2,\"errmsg\":\"" + String2Json(dal.ErrorMessage) +"\"}";
    }
    else if (dal.RowsCount == 0)
    {
      rv = "{\"errcode\":1,\"errmsg\":\"" + String2Json("未成功更新记录。") + "\"}";
    }
    return rv;
}

private static string String2Json(String s)
{

    StringBuilder sb = new StringBuilder();

    for (int i = 0; i < s.Length; i++)
    {

      char c = s.ToCharArray();

      switch (c)
      {

            case '\"':

                sb.Append("\\\""); break;

            case '\\':

                sb.Append("\\\\"); break;

            case '/':

                sb.Append("\\/"); break;

            case '\b':

                sb.Append("\\b"); break;

            case '\f':

                sb.Append("\\f"); break;

            case '\n':

                sb.Append("\\n"); break;

            case '\r':

                sb.Append("\\r"); break;

            case '\t':

                sb.Append("\\t"); break;

            default:

                if ((c >= 0 && c <= 31) || c == 127)//在ASCⅡ码中,第0~31号及第127号(共33个)是控制字符或通讯专用字符
                {



                }

                else
                {

                  sb.Append(c);

                }

                break;

      }

    }

    return sb.ToString();

}

</script>
   小结

由于一对多录入的特点,我们接纳了嵌入 iframe 元素的方法,然后传递参数名称 com_name,以决定利用Json配置文件中的节点信息 。
正常的情况下,我们还会有父项的录入界面,并提供有生存按钮,因此点击生存按钮时客户端大概还需要对 iframe 里的表格数据再举行一次校验或处理,访问iframe里的元素方法紧张通过iframe.contentWindow.document 处理,比如如下代码:
    var atts = new Array();
    atts.push('att_jypx');
    function before_submit() {
      for (var i = 0; i < atts.length; i++) {
            var p_att = document.getElementById('p_' + atts);
            if (p_att == undefined) { continue; }
            var p_att_ifr = document.getElementById('x_p_' + atts);
            var l_att = document.getElementById('l_' + atts);
            if (p_att_ifr.contentWindow.document.getElementById('mtable').rows.length == 0) {
                alert(l_att.innerText + "的内容需要添加。");
                return false;
            }

            if (p_att_ifr.contentWindow.validall(l_att.innerText+"内容的") == false) {
                return false;
            }
            if (p_att_ifr.contentWindow.validsave('')== false) {
                alert(l_att.innerText + "的内容有尚未或正在保存的内容,请保存后再进行提交。");
                return false;
            }
      }
      return true;
    }
   ​别的工具栏按钮的图片文件,我们可以按照本身的实际需要举行替换。本代码仅供您参考利用,感谢您的阅读,希望本文可以或许对您有所帮助。




免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: C#结合JS实现HtmlTable动态添加行并生存到数据库