SoFunction
Updated on 2025-03-04

C# combined with JS to implement dynamic addition of HtmlTable and save it to the database

need

In web application projects, implementing one-to-many data management function is a common application. Therefore, a relatively lightweight design implementation table entry can be realized. In order to ensure the usability of functions and interface friendliness, the overall requirements are as follows:

1. The data grid can dynamically add rows, and rows can provide input boxes and selection boxes for input.

2. The data grid can delete selected rows.

3. The data grid can be moved up and down to reorder the selected rows.

4. The data validity verification function can be realized (such as required, digit limit, type limit, etc.).

5. Dangerous content such as input text needs to be filtered and blocked HTML tags.

6. Before adding a new line, judge the validity of an existing line. For those that have not passed the verification, new lines are not allowed to be added.

7. There are certain relevant prompt information for the modified, saved, and saved status.

8. Data storage realizes dynamic and refresh-free.

Sample operating environment

Operating system: Windows Server 2019 DataCenter

Database: Microsoft SQL Server 2016

.net version: .netFramework 4.0 or above

Development tools and related technologies: VS2019 C#, Jquery, Json, Javascript

Prepare the data source

Data table design

We create att_jypx (education and training experience table) in MS SQL Server, and its structure is as follows:

Serial number Field name type illustrate
1 cid uniqueidentifier Line unique identifier, unique key
2 xmbh varchar(20) Foreign key parent, refer to the project number
3 sfzh nvarchar(18) Foreign key parent, refer to ID number
4 nf1 nvarchar(4) Starting year
5 yf1 nvarchar(2) Starting month
6 nf2 nvarchar(4) Deadline year
7 yf2 nvarchar(2) Deadline month
8 xxmc nvarchar(100) School name
9 zy nvarchar(50) Majors studied
10 xl nvarchar(10) Education
11 byzlb nvarchar(50) Graduation Certificate Category
12 xh int Sorting number

Execute the following SQL statement to create a table:

CREATE TABLE [dbo].[att_jypx](
	[cid] [uniqueidentifier] ROWGUIDCOL  NOT NULL,
	[xmbh] [varchar](20) NOT NULL,
	[sfzh] [nvarchar](18) NOT NULL,
	[nf1] [nvarchar](4) NULL,
	[yf1] [nvarchar](2) NULL,
	[nf2] [nvarchar](4) NULL,
	[yf2] [nvarchar](2) NULL,
	[xxmc] [nvarchar](100) NULL,
	[zy] [nvarchar](50) NULL,
	[xl] [nvarchar](10) NULL,
	[byzlb] [nvarchar](50) NULL,
	[xh] [int] NULL,
 CONSTRAINT [PK_att_jypx] PRIMARY KEY CLUSTERED 
(
	[cid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
 
ALTER TABLE [dbo].[att_jypx] ADD  CONSTRAINT [DF_att_jypx_cid]  DEFAULT (newid()) FOR [cid]
GO

Other descriptions of the data table are as follows:

1. The CID field is GUID type, which can be used to identify the ID of the Row row object of HtmlTable and is used for storage.

2. The xmbh field and the sfzh field are referenced foreign keys. For demonstration purposes, we assume that the project number is ‘001’ and the ID number is ‘120102’

3. xh is used for sorting and recording order.

None of the above fields participates in the presentation of the HtmlTable table content to reduce the capacity of the data packet and only participates in foreign key operations.

UI and table structure Json configuration

For the presentation of HtmlTable table content, data structure and data verification, we will use Json files to configure it, and the configuration description is as follows:

Serial number item type illustrate
1 maxRowCount character Maximum number of rows allowed to be added
2 mtable_style character The style of HtmlTable editing
3 ttable_style character Title HtmlTable style
4 cols Array The column array defines variables. The following 5 to 12 are the properties of each array element object contained in cols
5 fname character Field name
6 cname character Field Chinese name or description
7  len number Field length
8 td_style character HtmlTabelCell cell style
9 ctl_style character Type or select the style of the control in the cell
10  input character You can enter text and select, corresponding to the input box and the selection box respectively
11  list character Used to select the option settings, separated by "|"
12  check character Used for data verification scheme settings, if set, please refer to the articleImplementation method of C# combined with JavaScript to verify data input of web controls_C# tutorial_I

The complete sample JSON is as follows:

{
  "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": "Start Year",
	      "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": "Start month",
	      "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": "Deadline Year",
	      "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": "Deadline",
	      "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": "School of the School",
	      "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": "Education",
	      "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": "The major you studied",
	      "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": "Graduation Certificate Category",
	      "len":50,
	      "td_style":"width:160px",
	      "ctl_style":"width:155px;border-radius:2px;border-width:1px;",
	      "input":"select",
 	     "list":"Full-time general higher education diploma | Adult higher education diploma | Higher education self-study examination diploma | Others",
 	     "check":"notnull"
   	    } 	 ]
             }
       ]
}

Json Packet Submission Configuration

The Json data packet is generated through the server based on Json configuration information, mainly including field name items, which are used for future data submission, because the submitted data method is still a Json data object, that is, a Json data packet. The initial format of the generation is as follows:

{"nf1":"",
"yf1":"",
"nf2":"",
"yf2":"",
"xxmc":"",
"zy":"",
"xmbh":"001",
"sfzh":"120102",
"xh":"",
"cid":"",
"com_name":"jypx"}

Design and implementation

Front-end UI

For the front-end UI, we mainly place some intermediate variable controls, table elements, etc., and the main elements are described in the table below:

Serial number Element Id type illustrate
1 curid TextBox Used to record the ID of the current point line
2 pjson TextBox Used to store Json configuration data
3 djson TextBox Used to store Json submission packets
4 ttable HtmlTable Title list for fixed display header
5 mtable HtmlTable Main edit table object
6 topnavs Div A set of toolbar object layers fixed to the top, including adding, deleting, moving up, moving down, saving buttons

The sample code is as follows:

<form  runat="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  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  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  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  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(('curid').value,1);" class="" />
<input  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(('curid').value,2);" class="" />
<input  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) {('Button4').removeAttribute('disabled');return;}saveall();if(('mtable').>0){ ('disabled','true');}" class="" />
<div  style="margin-left:10px; font-weight:bold; font-size:11pt; color:Red; "></div>
</div>
<table align="left"  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"  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 scripts

Javascript scripts implement table editing operations and communication with server methods through Ajax and save data. The main method descriptions are shown in the following table:

Serial number Method name parameter illustrate
1 simplecheck

chkobj: Cell object

_chkvalue: The value of the cell edit

allowAlert: Whether to allow pop-up prompts

etip: Extended prefix string that pops up

This method is used to verify data validity

2 swarp

mId: The ID of the current line

type: Move direction, 1 move up, 2 move down

Used to move sort operations on selected rows
3 chnRowSelColor rowobj: Current row object Used to highlight the color of the selected row and set the current row to editable state at the same time
4 tojsonstr str: The input value Perform safe detection of the input value, remove HTML tags, and special processing of single and double quotes to ensure that the characters passed by JSON strings are in compliance with legality
5 saveall Save all row records and submit database operations
6 delinfo Delete the currently selected row and submit the database operation
7 validall extip: Additional prefix prompt Perform data validity verification on all rows before saving
8 validchange obj: The currently edited control element Prompt the user to modify the value of which control element
9 validsave extip: Additional prefix prompt Used to check whether there are saved records
10 addRow Add a new row and submit to the database operation
11 gGuid Used to generate a GUID string when adding a new line
12 ScrollToBottom Used to automatically scroll to the bottom of the page when adding a new line

The complete example code is as follows:

&lt;script language="javascript"&gt;
    function simplecheck(chkobj, _chkvalue, allowAlert,etip) {
        check_result = true; check_errid = ''; check_errmsg = '';var _checkSchema = ('checkSchema');var _cName = ('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 &lt; _schemaList.length; k++) { if (_schemaList[k].toLowerCase() == 'notnull') { _reqeustnotnull = true; } }
        if ((!_reqeustnotnull) &amp;&amp; (_chkvalue == '')) { return check_result; }
        for (var j = 0; j &lt; _schemaList.length; j++) {
            var curSchema = _schemaList[j].toLowerCase(); check_errid = curSchema; var curErrmsg = ''; switch (true) { case curSchema == 'notnull': check_result = isNotNull(_chkvalue); curErrmsg = _cName + 'The content needs to be filled in!  '; break; case curSchema == 'number': check_result = isNumber(_chkvalue); curErrmsg = _cName + ' The entered value is unreasonable, please check it!  '; break; case curSchema == 'bnumber': check_result = isBNumber(_chkvalue); curErrmsg = _cName + ' The input value should be&gt;=0Positive number of,Please check!'; break; case curSchema == 'snumber': check_result = isSNumber(_chkvalue); curErrmsg = _cName + ' The entered value should be a negative number <0, please check it!  '; break; case curSchema == 'date': check_result = isDate(_chkvalue, _cName); check_errid = 'date'; check_errmsg = (check_result ? '' : _cName + ' The date entered is unreasonable,Please check!'); curErrmsg = ''; break; case ('minlen') != -1: var _slen = parseInt(('minlen'.length,  - 'minlen'.length), 10); if (isNaN(_slen)) { check_result = false; curErrmsg = _cName + 'The minimum digit parameter entered is unreasonable, please contact the software supplier!  '; } else { check_result = (_objlength &lt; _slen ? false : true); curErrmsg = _cName + 'The content requires minimum input' + _slen + 'Bit, please check!  '; } break; case ('maxlen') != -1: var _slen = parseInt(('maxlen'.length,  - 'maxlen'.length), 10); if (isNaN(_slen)) { check_result = false; curErrmsg = _cName + 'The maximum number of digits entered is unreasonable, please contact the software supplier!  '; } else { check_result = (_objlength &gt; _slen ? false : true); curErrmsg = _cName + 'Maximum allowable input' + _slen + 'Bit, please check!  '; } break; case ('mustlen') != -1: var _slen = parseInt(('mustlen'.length,  - 'mustlen'.length), 10); if (isNaN(_slen)) { check_result = false; curErrmsg = _cName + 'The limit digit parameters entered are unreasonable, please contact the software supplier!  '; } else { check_result = (_objlength != _slen ? false : true); curErrmsg = _cName + 'The content input length can only be' + _slen + 'Bit, please check!  '; } break; case curSchema == 'time': check_result = validRegs(_chkvalue, /^\d{1,2}:\d{1,2}:\d{1,2}$/); curErrmsg = _cName + ' The input time is unreasonable, please check it.  '; break; case curSchema == 'alpha': check_result = isAlpha(_chkvalue); curErrmsg = _cName + ' Only numbers, letters and underscores can be entered, please check.  '; break; case curSchema == 'mail': check_result = validRegs(_chkvalue, /^([a-zA-Z0-9._-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/); curErrmsg = _cName + ' The email address entered is unreasonable, please check it.  '; break; case curSchema == 'phone': check_result = validRegs(_chkvalue, /([a-zA-Z0-9\.-\u4e00-\u9fa5]{8,})$/); curErrmsg = _cName + ' The phone number entered is unreasonable, please check it.  '; break; case curSchema == 'mobile': check_result = validRegs(_chkvalue, /^1(3[0-9]|5[012356789]|8[056789])\d{8}$/); curErrmsg = _cName + ' The mobile phone number entered is unreasonable, please check it.  '; break; case curSchema == 'money': check_result = validRegs(_chkvalue, /^\d+(\.\d+)?$/); curErrmsg = _cName + ' The content entered does not meet the requirements of the currency type, please check it.  '; break; case curSchema == 'zip': check_result = validRegs(_chkvalue, /^[1-9]\d{5}$/); curErrmsg = _cName + ' The zip code entered is unreasonable, please check it.  '; break; case curSchema == 'int': check_result = validRegs(_chkvalue, /^[-\+]?\d+$/); curErrmsg = _cName + ' You need to enter an integer, please check.  '; break; case curSchema == 'en': check_result = validRegs(_chkvalue, /^[A-Za-z]+$/); curErrmsg = _cName + 'You can only enter English uppercase and uppercase letters, please check.  '; break; case curSchema == 'cn': check_result = validRegs(_chkvalue, /^[\u0391-\uFFE5]+$/); curErrmsg = _cName + ' You can only enter Chinese, please check.  '; break; case curSchema == 'url': check_result = validRegs(_chkvalue, /([\w-]+\.)+[\w-]+(\/[\w- .\/?%&amp;=]*)?/); curErrmsg = _cName + ' The URL entered is unreasonable, please check it.  '; 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 != '') &amp;&amp; (allowAlert)) { ('saved').innerHTML = etip + curErrmsg; alert(etip + curErrmsg); return check_result; }
            }
        }
        return check_result;
    }
    function checkIdcard(idcard) {
        var _idcard = idcard;  var Errors = new Array('', 'The number of ID numbers is incorrect!', 'Identity card number date of birth is out of range or contains illegal characters!', 'Identity card number verification error!', 'Illegal ID card area!', '');
        if (_idcard == '') { return Errors[5]; }
        var area = { 11: 'Beijing', 12: 'Tianjin', 13: 'Hebei', 14: 'Shanxi', 15: 'Inner *', 21: 'Liaoning', 22: 'Jilin', 23: 'Heilongjiang', 31: 'Shanghai', 32: 'Jiangsu', 33: 'Zhejiang', 34: 'Anhui', 35: 'Fujian', 36: 'Jiangxi', 37: 'Shandong', 41: 'Henan', 42: 'Hubei', 43: 'Hunan', 44: 'Guangdong', 45: 'Guangxi', 46: 'Hainan', 50: 'Chongqing', 51: 'Sichuan', 52: 'Guizhou', 53: 'Yunnan', 54: 'Tibet', 61: 'Shaanxi', 62: 'Gansu', 63: 'Qinghai', 64: 'Ningxia', 65: '*', 71: '*', 81: 'Hongkong', 82: 'Macao', 91: 'foreign' }
        var _idcard, Y, JYM; var S, M; var idcard_array = new Array(); idcard_array = _idcard.split('');
        if (area[parseInt(_idcard.substr(0, 2))] == null) { return Errors[4]; }
        switch (_idcard.length) {
            case 15: if ((parseInt(_idcard.substr(6, 2)) + 1900) % 4 == 0 || ((parseInt(_idcard.substr(6, 2)) + 1900) % 100 == 0 &amp;&amp; (parseInt(_idcard.substr(6, 2)) + 1900) % 4 == 0)) {
                    ereg = /^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}$/;
                } else {
                    ereg = /^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}$/;
                }
                if ((_idcard)) {
                    var iS = 0; var iW = new Array; iW[0] = 7; iW[1] = 9; iW[2] = 10; iW[3] = 5; iW[4] = 8; iW[5] = 4; iW[6] = 2; iW[7] = 1; iW[8] = 6; iW[9] = 3; iW[10] = 7; iW[11] = 9; iW[12] = 10; iW[13] = 5; iW[14] = 8; iW[15] = 4; iW[16] = 2;
                    var LastCode = '10X98765432'; var perIDNew; perIDNew = _idcard.substr(0, 6); perIDNew += '19'; perIDNew += _idcard.substr(6, 9);
                    for (var i = 0; i &lt; 17; i++) { iS += parseInt((i, 1)) * iW[i]; }
                    var iY = iS % 11; perIDNew += (iY, 1);
                    return Errors[0];
                } else {
                    return Errors[2];
                }
                break;
            case 18: if (parseInt(_idcard.substr(6, 4)) % 4 == 0 || (parseInt(_idcard.substr(6, 4)) % 100 == 0 &amp;&amp; parseInt(_idcard.substr(6, 4)) % 4 == 0)) {
                    ereg = _idcard.substr(6, 2) == '19' ? /^[1-9][0-9]{5}19[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}[0-9Xx]$/ : /^[1-9][0-9]{5}20[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}[0-9Xx]$/;
                } else {
                    ereg = _idcard.substr(6, 2) == '19' ? /^[1-9][0-9]{5}19[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}[0-9Xx]$/ : /^[1-9][0-9]{5}20[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}[0-9Xx]$/;
                }
                if ((_idcard)) {
                    S = (parseInt(idcard_array[0]) + parseInt(idcard_array[10])) * 7 + (parseInt(idcard_array[1]) + parseInt(idcard_array[11])) * 9 + (parseInt(idcard_array[2]) + parseInt(idcard_array[12])) * 10 + (parseInt(idcard_array[3]) + parseInt(idcard_array[13])) * 5 + (parseInt(idcard_array[4]) + parseInt(idcard_array[14])) * 8 + (parseInt(idcard_array[5]) + parseInt(idcard_array[15])) * 4 + (parseInt(idcard_array[6]) + parseInt(idcard_array[16])) * 2 + parseInt(idcard_array[7]) * 1 + parseInt(idcard_array[8]) * 6 + parseInt(idcard_array[9]) * 3;
                    Y = S % 11; M = 'F'; JYM = '10X98765432'; M = (Y, 1); if (M == idcard_array[17]) return Errors[0]; else { return Errors[3]; } 
                } else { return Errors[2]; } break; default: return Errors[1]; break;
        } 
    }
    function getid(id) { alert(checkIdcard(id)) }
    function per18To15(perIDSrc) { rstr = ''; for (var i = 0; i &lt; 17; i++) { if ((i == 6) || (i == 7)) { continue; } rstr += (i); } return rstr; }
    function per15To18(perIDSrc) {
        var iS = 0; var iW = new Array;
        iW[0] = 7; iW[1] = 9; iW[2] = 10; iW[3] = 5; iW[4] = 8; iW[5] = 4; iW[6] = 2; iW[7] = 1; iW[8] = 6; iW[9] = 3; iW[10] = 7; iW[11] = 9; iW[12] = 10; iW[13] = 5; iW[14] = 8; iW[15] = 4; iW[16] = 2;
        var LastCode = '10X98765432'; var perIDNew; perIDNew = (0, 6); perIDNew += '19'; perIDNew += (6, 9);
        for (var i = 0; i &lt; 17; i++) { iS += parseInt((i, 1)) * iW[i]; }
        var iY = iS % 11; perIDNew += (iY, 1); return perIDNew;
    }
    var aCity = { 11: 'Beijing', 12: 'Tianjin', 13: 'Hebei', 14: 'Shanxi', 15: 'Inner *', 21: 'Liaoning', 22: 'Jilin', 23: 'Heilongjiang', 31: 'Shanghai', 32: 'Jiangsu', 33: 'Zhejiang', 34: 'Anhui', 35: 'Fujian', 36: 'Jiangxi', 37: 'Shandong', 41: 'Henan', 42: 'Hubei', 43: 'Hunan', 44: 'Guangdong', 45: 'Guangxi', 46: 'Hainan', 50: 'Chongqing', 51: 'Sichuan', 52: 'Guizhou', 53: 'Yunnan', 54: 'Tibet', 61: 'Shaanxi', 62: 'Gansu', 63: 'Qinghai', 64: 'Ningxia', 65: '*', 71: '*', 81: 'Hongkong', 82: 'Macao', 91: 'foreign' }
    function cidInfo(sId) {
        var iSum = 0; var info = '';
        if (!/^\d{17}(\d|x)$/(sId))
            return false; sId = (/x$/i, 'a');
        if (aCity[parseInt((0, 2))] == null) return 'Error: Illegal area'; sBirthday = (6, 4) + '-' + Number((10, 2)) + '-' + Number((12, 2));
        var d = new Date((/-/g, '/'))
        if (sBirthday != (() + '-' + (() + 1) + '-' + ()))
            return 'Error: Illegal birthday';
        for (var i = 17; i &gt;= 0; i--) iSum += ((2, i) % 11) * parseInt((17 - i), 11)
        if (iSum % 11 != 1) return 'Error: Illegal certificate number';
        return aCity[parseInt((0, 2))] + ',' + sBirthday + ',' + ((16, 1) % 2 ? 'male' : 'female')
    }
function PositionLen(s){var i,str1,str2,str3,nLen;	str1 =s;nLen = 0;for(i=1;i&lt;=;i++){str2=(i-1,i);str3=escape(str2);if(&gt;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)&gt;=0?true:false:false);}
function isSNumber(str){if(str==''){return true;}return (!isNaN(str)?parseInt(str,10)&lt;0?true:false:false);}
function isAlpha(_str){return (_str.replace(/\w/g,'').length == 0);}
function isAN(_str){var reg = /^(([a-z]+[0-9]+)|([0-9]+[a-z]+))[a-z0-9]*$/i;return (_str);}
function validRegs(_value,_Regs){return _Regs.test(_value); }
function isVisibled(obj){   if( (=='none')||( (==0)&amp;&amp;(==0) ) )       return false; if(){if(['display']=='none') return false;}  return true;}
function isFocused(obj){   if( (==false)&amp;&amp;(isVisibled(obj)) )       return true;   return false;}
function isDate(str,cname,notip){if(str==''){return true;}
str=(/\//g,'-');
dt=(' ');if(&gt;2){if(!notip) alert(cname+'Date input is incorrect!  May include illegal date components.  ');return false;	} dt1=dt[0].split('-');if(!=3){if(!notip) 	alert(cname+'Date input is incorrect!  The date part should be YYYY-MM-DD.  ');return false;}dt1n=(dt1[0]+dt1[1]+dt1[2]).split('');for(var i=0;i&lt;;i++){if((isNaN(dt1[i])||(ctrim(dt1[i])==''))){if(!notip) 	alert(cname+'character:'+dt1[i]+', Numbers must be entered in the year, month, day and part!  ');	return false;}	}_year=parseInt(dt1[0],10);	_month=parseInt(dt1[1],10);	_day=parseInt(dt1[2],10);if((_year&lt;1000)||(_year&gt;9999)||(_month&lt;1)||(_month&gt;12)||(_day&lt;1)||(_day&gt;31)){if(!notip) alert(cname+'The numbers entered in the year, month and day part are unreasonable, please check!  ');return false;	}v_date31=new Array;v_date31[0]=4;v_date31[1]=6;v_date31[2]=9;v_date31[3]=11;if((getArrayIndex(v_date31,_month)!=-1)&amp;&amp;(_day&gt;30)){if(!notip) alert(cname+'month:'+_month+', the input range of days is unreasonable!  ');	return false;}if(_month==2){	if(((_year%4==0)&amp;&amp;(_year%100!=0))||(_year%400==0)){	if(_day&gt;29){if(!notip) alert(cname+'month:'+_month+', the input range of days is unreasonable!  ');return false;	}}else{	if(_day&gt;28){if(!notip) alert(cname+'month:'+_month+', the input range of days is unreasonable!  ');return false;	}}	}	return true;   }
function getArrayIndex(xArray,find){_rs=-1;for(var j=0;j&lt;;j++){if(xArray[j]==find){_rs=j;	break; 	}}	return _rs;	}
function ctrim(ename){ if(ename==undefined) return '';	return ((/(^\s*)|(\s*$)/g, '')).replace(/^[\s \t]+|[\s \t]+$/, '');}
 
 
    var RowsCount = 0;
    var ErrorMessage = "";
 
    function swarp(mId, stype) {
        var mObj = (mId);
        if (mObj == undefined) {
            return false;
        }
        var premObj = ;
        if (stype == 2) {
            premObj = ;
        }
        if (premObj == null) return false;
        if (stype == 1) {
            (mObj, premObj);
        } else if (stype == 2) {
            (premObj, mObj);
        }
    }
    function setrow(rowobj) {
        ('curid').value = ;
        chnRowSelColor(rowobj);
    }
    function chnRowSelColor(rowobj) {
        var _com = "att_" + ('com_name').value;
        var mt = ('mtable');
        for (var i = 0; i &lt; ; i++) {
            var mt_row = [i];
            mt_row. = '';
            if (mt_row.id == ) {continue;}
            for (var j = 0; j &lt; mt_row.; j++) {
                var cell1 = mt_row.cells[j];
                if (('input').length &gt; 0) {
                     = ('input')[0].(/&lt;[^&gt;]*&gt;/g, '');
                }else 
                if (('select').length &gt; 0) {
                         = ('select')[0].(/&lt;[^&gt;]*&gt;/g, '');
                }
            }
        }
         = 'rgb(235,235,235)';
        var pj = (('pjson').value);
        var jtcy = pj[_com][0].cols;
        var isadd = false;
        if ( == 0) {
            isadd = true;
        }
        for (var i = 0; i &lt; ; i++) {
            var cell1 = isadd==true?(i):[i];
            var ctype = jtcy[i].input;
            var innerhtml = "";
            var oldvalue = "";
            if(isadd==true){
                ("checkSchema",jtcy[i].check);
                ("cName",jtcy[i].cname);
            }
            if (ctype == "text") {
                oldvalue = ;
                innerhtml = "&lt;input type='" + ctype + "' onchange='validchange(this)' placeholder='" + jtcy[i].cname + "'style='" + jtcy[i].ctl_style + "'/&gt;";
            } else if (ctype == "select") {
                oldvalue = ;
                innerhtml = "&lt;" + ctype + " onchange='validchange(this)' style='" + jtcy[i].ctl_style + "' /&gt;";
                innerhtml += "&lt;option value=''&gt;" + jtcy[i].cname + "&lt;/option&gt;";
                var items = jtcy[i].("|");
                for (var j = 0; j &lt; ; j++) {
                    innerhtml += "&lt;option&gt;" + items[j] + "&lt;/option&gt;";
                }
                innerhtml += "&lt;/" + ctype + "&gt;";
            }
             = innerhtml;
             = jtcy[i].td_style;
            ('click', function (event) {
                ();
                if ( != ('curid').value) {
                    setrow();
                }
            });
            if (('input').length &gt; 0) {
                ('input')[0].value=oldvalue;
                ('input')[0].addEventListener('click', function (event) {
                    ();
                });
            } else if (('select').length &gt; 0) {
                ('select')[0].value = oldvalue;
                ('select')[0].addEventListener('click', function (event) {
                    ();
                });
            }
        }
 
    }
    function ss(type, result) {
        try {
            var robj = (result);
            if ( != 0) {
                ErrorMessage = ;
                alert(ErrorMessage);
            } else {
                RowsCount++;
            }
        } catch (ss_e) {
            ErrorMessage=(ss_e);
            alert(ErrorMessage);
        }
        if (RowsCount == ('mtable').) {
            ('Button4').removeAttribute("disabled");
            ('saved'). = 'green';
            ('saved').innerHTML = "Save all successful.";
            (function () {
                ('saved'). = 'red';
                ('saved').innerHTML = "";
            }, 1000);
 
 
            callServerFunction("", "save_att_data", "{ypz_cid:'" +('cid').value+"',com_name:'"+('com_name').value + "'}", ss4);
        }
    }
    function ss4(type, result) {
        if ((result) == "\"true\"") {
        } else {
            alert('The synchronous update of resume information failed. Please click the Modify resume button to submit the modification.  ' + (result));
        }
    }
    function ss3(type, result) {
        try {
            var robj = (result);
            if ( != 0) {
                ErrorMessage = ;
                alert(ErrorMessage);
            } else {
                RowsCount++;
            }
        } catch (ss3_e) {
            ErrorMessage = (ss3_e);
            alert(ErrorMessage);
        }
    }
    function tojsonstr(str) {
        var prv = (/["\\]/g, '\\$&amp;').replace(/&lt;[^&gt;]*&gt;/g, '').replace(/&lt;[^&gt;]*&gt;/g, '') ;
        return prv;
    }
    function saveall() {
        var mt = ('mtable');
        if ( == 0) {
            ('saved'). = '#4169E1';
            ('saved').innerHTML = "Please add the line before performing the save operation...";
            (function () {
                ('saved'). = 'red';
                ('saved').innerHTML = "";
            }, 3000);
            return;
        }
        RowsCount = 0;
        ErrorMessage = "";
        ('saved'). = '#4169E1';
        ('saved').innerHTML = "Saving...";
 
        var _com = "att_" + ('com_name').value;
        var pj = (('pjson').value);
        var dj = (('djson').value);
        var jtcy = pj[_com][0].cols;
        for (var i = 0; i &lt; ; i++) {
            var mt_row = [i];
             = mt_row.id;
             = (i + 1);
            for (var j = 0; j &lt; mt_row.; j++) {
                var cell1 = mt_row.cells[j];
                var _value = ;
                if (('input').length &gt; 0) {
                    _value = ('input')[0].value;
                } else if (('select').length &gt; 0) {
                    _value = ('select')[0].value;
                }
                dj[jtcy[j].fname] =tojsonstr(_value);
            }
            callServerFunction("", "saveInfo", "{jdata:'" + (dj).replace(/['\\]/g, '\\$&amp;') + "'}", ss);
        }
    }
    function ss2(type, result) {
        try {
            var robj = (result);
            if ( != 0) {
                ErrorMessage = ;
                alert(ErrorMessage);
            } else {
                RowsCount++;
                var curid = ('curid').value;
                var mt_row = (curid);
                ('mtable').deleteRow(mt_row.rowIndex);
                ('saved'). = 'red';
                ('saved').innerHTML = "";
                alert('Delete the current line successfully!  ');
            }
        } catch (ss2_e) {
            ErrorMessage = (ss2_e);
            alert(ErrorMessage);
        }
    }
 
    function delinfo() {
        var curid = ('curid').value;
        if (curid == "") {
            alert('Please select the record before performing the deletion operation.  ');
            return;
        }
        RowsCount = 0;
        ErrorMessage = "";
        var _com = "att_" + ('com_name').value;
        var dj = (('djson').value);
        var mt_row = (curid);
         = mt_row.id;
        callServerFunction("", "deleteInfo", "{jdata:'" + (dj).replace(/['\\]/g, '\\$&amp;') + "'}", ss2);
    }
    function validall(extip) {
        
 
        var _com = "att_" + ('com_name').value;
        var mt = ('mtable');
 
        var pj = (('pjson').value);
        var dj = (('djson').value);
        var jtcy = pj[_com][0].cols;
        for (var i = 0; i &lt; ; i++) {
            var mt_row = [i];
            for (var j = 0; j &lt; mt_row.; j++) {
                var cell1 = mt_row.cells[j];
                var _value = ;
                if (('input').length &gt; 0) {
                    _value = ('input')[0].value;
                } else if (('select').length &gt; 0) {
                    _value = ('select')[0].value;
                }
                var isvalid = simplecheck(cell1, _value, true, extip+"Third" + (i + 1) + "OK:");
                if (isvalid == false) {
                    mt_row. = '#B22222';
                    
                    return false;
                }
            }
        }
        return true;
    }
    function validchange(obj) {
        ('saved').innerText = 'Modified'+('cname')+'To be saved';
    }
    function validsave(extip) {
        if (('saved').innerText != '') {
            return false;
        }
        return true;
    }
    function addRow() {
        if (validall('') == false) {
            return;
        }
        RowsCount = 0;
        ErrorMessage = "";
 
        var _com = "att_" + ('com_name').value;
        var pj = (('pjson').value);
        
        var jtcy=pj[_com][0].cols;
        var mt = ('mtable');
        var maxCount = parseInt(pj[_com][0].maxRowCount, 10);
        if ( &gt;= maxCount) {
            alert("This content is allowed to be added at most" + maxCount + "OK.");
            return;
        }
        var row = (-1); // -1 means inserting a new row at the end of the table         = gGuid();
        ("onclick", "setrow(this)");
        setrow(row);
        var dj = (('djson').value);
        dj["cid"] = ;
        dj["sortid"] = ;
 
        callServerFunction("", "saveInfo", "{jdata:'" + (dj) + "'}", ss3);
        ('saved'). = 'red';
        ('saved').innerHTML = "Add a new line not saved";
        ScrollToBottom();
    }
    function gGuid() {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
            var r = (() * 16);
            var v = c === 'x' ? r : (r &amp; 0x3 | 0x8);
            return (16);
        });
    }
    function ScrollToBottom() {
        $("html, body").animate({ scrollTop: $(document).height() - $(window).height() });
    }
&lt;/script&gt;

Jquery Quotations

This is a set of extended application libraries based on Jquery, which are referenced. This library is used for calling server static methods and other functions.

C# server operation

Serial number Method name Return type illustrate
1 public void InitPage() void It is mainly used to extract existing data table data and display data rows to the main editing table mtable. Please refer to the article for extracting data.C# uses IDbDataAdapter/IDataReader to achieve general dataset acquisition_C# Tutorial_Me
2 public static string saveInfo(string jdata) string

Save row information to the data table. The parameters are submitted Json data packets. Please refer to the article to save data operations.C# uses IDbCommand to implement a general database script execution program_C# tutorial_Me

3 public static string deleteInfo(string jdata) string Delete row information to the data table. The parameters are submitted Json data packets. Please refer to the article to save the database operation.C# uses IDbCommand to implement a general database script execution program_C# tutorial_Me
4 private static string String2Json(String s) string Canonical strings to comply with Json string requirements

The implementation sample code is as follows:

&lt;%@ Page Language="C#" %&gt;
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:///TR/xhtml1/DTD/"&gt;
&lt;%@ Import Namespace=""%&gt;
&lt;%@ Import NameSpace=""%&gt;
&lt;%@ Import Namespace=""%&gt;
&lt;%@ Import Namespace=""%&gt;
&lt;script language="C#" runat="server"&gt;
public  dal = new ();
void Page_Load(Object sender, EventArgs e)
{
    if () { return; }
    InitPage();
}
 
public void InitPage()
{
     = ;
    string _xmbh = "001";
    string _p_att_json = ;
    string _sfzh = "120102";
     = _xmbh;
     = _sfzh;
    
    com_name.Text = ["com_name"];
     jobj = ();
     = "{";
    _sql = "select ";
    HtmlTableRow trow = new HtmlTableRow();
    ["style"] = jobj["att_" + com_name.Text][0]["ttable_style"].ToString();
    ["style"] = jobj["att_" + com_name.Text][0]["mtable_style"].ToString();
    for (int i = 0; i &lt; jobj["att_" + com_name.Text][0]["cols"].Count(); i++)
    {
        HtmlTableCell tcell = new HtmlTableCell();
         = jobj["att_" + com_name.Text][0]["cols"][i]["cname"].ToString();
        ["style"] = jobj["att_" + com_name.Text][0]["cols"][i]["td_style"].ToString();
        (tcell);
         += ("\"{0}\":\"{1}\",", jobj["att_" + com_name.Text][0]["cols"][i]["fname"].ToString(), "");
        _sql += jobj["att_" + com_name.Text][0]["cols"][i]["fname"].ToString() + ",";
    }
    (trow);
     += ("\"{0}\":\"{1}\"", "xmbh", _xmbh);
     += (",\"{0}\":\"{1}\"", "sfzh",_sfzh);
     += (",\"{0}\":\"{1}\"", "sortid", "");
     += (",\"{0}\":\"{1}\"", "cid", "");
     += (",\"{0}\":\"{1}\"", "com_name", com_name.Text);
     += "}";
    _sql = _sql + "cid from att_" + com_name.Text+" where xmbh=@xmbh and sfzh=@sfzh order by sortid"; 
    ();
    (new SqlParameter("xmbh", _xmbh));
    (new SqlParameter("sfzh", _sfzh));
    rv = (_sql, paras);
    if ( != "")
    {
        return;
    }
     = true;
    ["top"] = "37px";
    ["top"] = "67px";
    if ( == 0)
    {
        return;
    }
    dt = ((DataSet)rv).Tables[0];
 
    for (int i = 0; i &lt; ; i++)
    {
        HtmlTableRow hrow = new HtmlTableRow();
        if (_zwmc == "" || (_bcbz == "true" &amp;&amp; _bcsm != ""))
        {
            ["onclick"] = "setrow(this)";
        }
         = [i]["cid"].ToString();
        for (int j = 0; j &lt; -1; j++)
        {
            HtmlTableCell hcell = new HtmlTableCell();
            ["style"] = jobj["att_" + com_name.Text][0]["cols"][j]["td_style"].ToString();
            ["cName"] = jobj["att_" + com_name.Text][0]["cols"][j]["cname"].ToString();
            ["checkSchema"] = jobj["att_" + com_name.Text][0]["cols"][j]["check"].ToString();
             = [i][[j].ToString()].ToString();
            (hcell);
        }
        (hrow);
    }
 
}
[WebMethod(BufferResponse = true)]
public static string saveInfo(string jdata)
{
     jobj = (jdata);
    string tablename = "";
    string inssql = "";
    string inslist = "";
    string insparas = "";
    string updsql = "";
    string updparas = "";
    ArrayList paras = new ArrayList();
    ();
 
    foreach (KeyValuePair&lt;string, &gt; kvp in jobj)
    {
        string key = ();
        string value = ();
        if (key == "com_name" &amp;&amp; (value == "jtcy" || value == "shgx" || value == "jypx" || value == "gzjl"))
        {
            tablename = "att_"+value;
        }
        else
        {
            inslist += key + ",";
            insparas +="@"+ key + ",";
            updparas += (" {0}=@{1},",key,key);
            (new SqlParameter(key, value));
        }
    }
    if ( &gt; 1)
    {
        inslist = (0,  - 1);
        insparas = (0,  - 1);
        inssql = ("insert into {0} ({1}) values({2});", tablename, inslist, insparas);
    }
    if ( &gt; 1)
    {
        updparas = (0,  - 1);
        updsql = ("update {0} set {1} where cid=@cid;", tablename, updparas);
    }
    string sql = (" if not exists(select cid from {0} where cid=@cid) begin {1} end else begin {2} end", tablename, inssql, updsql);
    
     dal = new ();
   (sql, paras);
   string rv = "{\"errcode\":0,\"errmsg\":\"\"}";
   if ( != "")
   {
       rv="{\"errcode\":2,\"errmsg\":\""+String2Json()+"\"}";
   }
   else if ( == 0)
   {
       rv = "{\"errcode\":1,\"errmsg\":\"" + String2Json("The record was not updated successfully.") + "\"}";
   }
    return rv;
}
[WebMethod(BufferResponse = true)]
public static string deleteInfo(string jdata)
{
     jobj = (jdata);
    string tablename = "";
    string updsql = "";
    string updparas = "";
    ArrayList paras = new ArrayList();
    ();
 
    foreach (KeyValuePair&lt;string, &gt; kvp in jobj)
    {
        string key = ();
        string value = ();
        if (key == "com_name" &amp;&amp; (value == "jtcy" || value == "shgx"|| value == "jypx" || value == "gzjl"))
        {
            tablename = "att_"+value;
        }
        else if(key=="cid")
        {
            (new SqlParameter(key, value));
        }
    }
    updsql = ("delete from {0} where cid=@cid;", tablename);
 
     dal = new ();
    (updsql, paras);
    string rv = "{\"errcode\":0,\"errmsg\":\"\"}";
    if ( != "")
    {
        rv = "{\"errcode\":2,\"errmsg\":\"" + String2Json() +  "\"}";
    }
    else if ( == 0)
    {
        rv = "{\"errcode\":1,\"errmsg\":\"" + String2Json("The record was not updated successfully.") + "\"}";
    }
    return rv;
}
 
private static string String2Json(String s)
{
 
    StringBuilder sb = new StringBuilder();
 
    for (int i = 0; i &lt; ; i++)
    {
 
        char c = ()[i];
 
        switch (c)
        {
 
            case '\"':
 
                ("\\\""); break;
 
            case '\\':
 
                ("\\\\"); break;
 
            case '/':
 
                ("\\/"); break;
 
            case '\b':
 
                ("\\b"); break;
 
            case '\f':
 
                ("\\f"); break;
 
            case '\n':
 
                ("\\n"); break;
 
            case '\r':
 
                ("\\r"); break;
 
            case '\t':
 
                ("\\t"); break;
 
            default:
 
                if ((c &gt;= 0 &amp;&amp; c &lt;= 31) || c == 127)//In ASC II code, No. 0 to 31 and No. 127 (33 in total) are control characters or communication-specific characters                {
 
 
 
                }
 
                else
                {
 
                    (c);
 
                }
 
                break;
 
        }
 
    }
 
    return ();
 
}
 
&lt;/script&gt;

summary

Due to the one-to-many entry feature, we adopted the method of embedding the iframe element and then passed the parameter name com_name to decide to use the node information in the Json configuration file.

Under normal circumstances, we will also have a parent entry interface and provide a save button. Therefore, when clicking the save button, the client may also need to verify or process the table data in the iframe again. The method of accessing elements in the iframe is mainly processed, such as the following code:

    var atts = new Array();
    ('att_jypx');
    function before_submit() {
        for (var i = 0; i &lt; ; i++) {
            var p_att = ('p_' + atts[i]);
            if (p_att == undefined) { continue; }
            var p_att_ifr = ('x_p_' + atts[i]);
            var l_att = ('l_' + atts[i]);
            if (p_att_ifr.('mtable'). == 0) {
                alert(l_att.innerText + "The content needs to be added.");
                return false;
            }
 
            if (p_att_ifr.(l_att.innerText+"Content") == false) {
                return false;
            }
            if (p_att_ifr.('')== false) {
                alert(l_att.innerText + "The content has not yet or is being saved. Please save it before submitting it.");
                return false;
            }
        }
        return true;
    }

In addition, we can replace the image files of the toolbar buttons according to our actual needs.

The above is the detailed process steps for implementing HtmlTable dynamically adding rows and saving them to the database through C# combined with JS. For more information about the implementation of HtmlTable dynamically adding and saving in C# JS, please pay attention to my other related articles!