目录
需求
效果视频演示
范例运行环境
准备数据源
数据表设计
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(教育培训经历表),其结构如下表:
序号 | 字段名 | 类型 | 说明 |
---|---|---|---|
1 | cid | uniqueidentifier | 行唯一标识,唯一键 |
2 | xmbh | varchar(20) | 外键父项,指项目编号 |
3 | sfzh | nvarchar(18) | 外键父项,指身份证号 |
4 | nf1 | nvarchar(4) | 起始年份 |
5 | yf1 | nvarchar(2) | 起始月份 |
6 | nf2 | nvarchar(4) | 截止年份 |
7 | yf2 | nvarchar(2) | 截止月份 |
8 | xxmc | nvarchar(100) | 学校名称 |
9 | zy | nvarchar(50) | 所学专业 |
10 | xl | nvarchar(10) | 学历 |
11 | byzlb | nvarchar(50) | 毕业证类别 |
12 | xh | int | 排序号 |
执行如下 创建表的 SQL 语句:
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
数据表的其它说明如下:
1、CID字段为GUID类型,可用于标识 HtmlTable 的 Row 行对象的 ID 并用于存储。
2、xmbh 字段和 sfzh 字段是引用的外键,我们为了演示方便假设为 项目编号 为‘001’、身份证号为‘120102’
3、xh 为排序记录顺序所用。
以上的所述字段均不参与 HtmlTable 表格内容的呈现,以降低数据包的容量,只参与外键操作。
UI及表结构Json配置
对于 HtmlTable 表格内容的呈现、数据结构及数据验证的校验,我们将使用Json文件进行配置,配置说明如下:
序号 | 项 | 类型 | 说明 |
---|---|---|---|
1 | maxRowCount | 字符 | 允许添加的最大行数 |
2 | mtable_style | 字符 | 主体编辑HtmlTable的风格 |
3 | ttable_style | 字符 | 标题HtmlTable的风格 |
4 | cols | 数组 | 列数组定义变量,以下5到12均为 cols 所包含每一数组元素对象的属性 |
5 | fname | 字符 | 字段名 |
6 | cname | 字符 | 字段中文名或说明 |
7 | len | 数字 | 字段长度 |
8 | td_style | 字符 | HtmlTabelCell 单元格的风格 |
9 | ctl_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 | 类型 | 说明 |
---|---|---|---|
1 | curid | TextBox | 用于记录当前点行的ID |
2 | pjson | TextBox | 用于存储Json配置数据 |
3 | djson | TextBox | 用于存储Json提交数据包 |
4 | ttable | HtmlTable | 标题列表格,用于固定显示表头 |
5 | mtable | HtmlTable | 主编辑表格对象 |
6 | topnavs | Div | 一组固定于顶端的工具栏对象层,包括新增、删除、上移、下移、保存按钮 |
示例代码如下:
Javascript 脚本
Javascript 脚本实现表格编辑操作及通过Ajax与服务器方法通信,并保存数据的功能,主要方法说明见下表:
序号 | 方法名称 | 参数 | 说明 |
---|---|---|---|
1 | simplecheck | chkobj:单元格对象 _chkvalue:单元格编辑的值 allowAlert:是否允许弹出提示 etip:弹出提示的扩展前缀字串 | 本方法用于数据有效性的校验 |
2 | swarp | mId:当前行的ID stype:移动方向,1上移,2下移 | 用于对选中行的移动排序操作 |
3 | chnRowSelColor | rowobj:当前行对象 | 用于高亮显示选中行的颜色,并同时将当前行设置为可编辑状态 |
4 | tojsonstr | str:输入的值 | 对输入的值进行安全检测,并移除HTML标记,对单引号双引号做特殊处理,以保证JSON字符串传递的字符合法性 |
5 | saveall | 保存所有行记录并提交数据库操作 | |
6 | delinfo | 删除当前选中的行并提交数据库操作 | |
7 | validall | extip:附加的前缀性提示 | 保存前对所有行进行数据有效性校验 |
8 | validchange | obj:当前编辑的控件元素 | 提示用户当前正修改哪个控件元素的值 |
9 | validsave | extip:附加的前缀性提示 | 用于检验是否正有保存的记录 |
10 | addRow | 添加一个新行并提交到数据库操作 | |
11 | gGuid | 用于增加新行时生成一个GUID字符串 | |
12 | ScrollToBottom | 用于增加新行时自动滚动到页面底部 |
完整示例代码如下:
Jquery引用
这是一组基于Jquery的自定义开发的扩展应用库,请下载我的资源:
https://download.csdn.net/download/michaelline/88615565
进行引用,本库用于调用服务器静态方法等功能使用。
C# 服务端操作
服务端主要用于对已有数据的提取显示并初始化到主编辑表中的行,并提供保存及删除操作的静态方法,主要方法说明见下表:
序号 | 方法名 | 返回类型 | 说明 |
---|---|---|---|
1 | public void InitPage() | void | 主要用于提取已有数据表数据并显示到主编辑表 mtable 的数据行,如何提取数据请参照我的文章 《C# 利用IDbDataAdapter / IDataReader 实现通用数据集获取》 |
2 | public static string saveInfo(string jdata) | string | 保存行信息到数据表,参数为提交的Json数据包, 保存数据操作请参照我的文章《C#利用IDbCommand实现通用数据库脚本执行程序》 |
3 | public static string deleteInfo(string jdata) | string | 删除行信息到数据表,参数为提交的Json数据包,保存数据库操作请参照我的文章《C#利用IDbCommand实现通用数据库脚本执行程序》 |
4 | private static string String2Json(String s) | string | 规范字符串,以符合Json字符串要求 |
实现示例代码如下:
<%@ Page Language="C#" %> <%@ Import Namespace="System.Data"%> <%@ Import NameSpace="System.Data.SqlClient"%> <%@ Import Namespace="System.IO"%> <%@ Import Namespace="System.Web.Services"%>
小结
由于一对多录入的特点,我们采用了嵌入 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[i]); if (p_att == undefined) { continue; } var p_att_ifr = document.getElementById('x_p_' + atts[i]); var l_att = document.getElementById('l_' + atts[i]); 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; }
另外工具栏按钮的图片文件,我们可以按照自己的实际需要进行替换。本代码仅供您参考使用,感谢您的阅读,希望本文能够对您有所帮助。
还没有评论,来说两句吧...