jquery表格动态增删改及取数据绑定数据完整方案
一 前言
上一篇Jquery遮罩插件,想罩哪就罩哪! 结尾的预告终于来了。
近期参与了一个针对内部员工个人信息收集的系统,其中有一个需求是在填写各个相关信息时,需要能动态的增加行当时公司有自己的解决方案 那就是用GridView 那个庞大的服务器控件,我一真就不怎么喜欢用服务器控件,于是极力说服PM用js来处理,并成功争取到了,先说下如果用GridView来处理的缺点,
1 生成的html代码会比较冗余,
2 每一个操作都会伴随页面回发,
3 每个操作都会刷新页面,这样的用户体验极差,就算用updatepanel也还是会有回发,
4 有点杀鸡用牛刀的感觉
那用js来处理以上的问题就都不存在了,重点是还能把js巩固一下(算是私心吧),由于项目的时间非常紧,而且又转成用js处理又没有相关的经验,整个过程压力还是很大的,免不了加班,但是做自己喜欢的事,就算加班我也是乐在其中
二 插件介绍
基本需求如下:
1 可以动态增加 删除行,
2 可以对行内数据进行校验,并支持自定义校验提示信息
3 能取到表格中的数据
4 能绑定后台数据到表格中
当然这只是大概的需求,还有很多小的细节就不写了,也不是本文的重点。下面详细写下每个功能的具体思路,当然我的肯定不是最好的思路,代码也肯定可再优化。
前后端数据交互过程如下:
前---后
前端取数据--->隐藏域---->后端取隐藏域值解析并存DB
后---前
后端取数据---->隐藏域----> 前端取隐藏域值添加到表格中
先看下效果
2.1 增加行 删除行
增加行
思路: 跳过第一行(也就是表头),复制第二行的html元素追加到表中,(在IE8中好像会将复制的行内文本值也会被追加到新的行中,这时需要遍历新的行将其清空)
代码如下
- //增加行
- $.fn.tables.addRow = function (gridId) {
- var tbRow = $("#" + gridId).find("tr").eq(1).html();
- var num = $("#" + gridId + " tr").length;
- $("#" + gridId).append("<tr id=" + num + ">" + tbRow + "</tr>");
- $("#" + gridId).find("tr").last().find("td").last().children().removeAttr("name").attr("value", "");
- };
删除行:
思路:点删除时通过当前元素找到其父元素"tr"然后再删除该"tr"元素
代码:
- //删除行
- //参数obj 当前对象
- $.fn.tables.deleteRow = function (obj) {
- var $this = $(obj);
- if ($this.parents("table").find("tr").length <= 2) {
- return false;
- }
- $this.parents("tr").remove();
- };
2.2 取表格内数据:
思路:为了让前端的数据到后端容易解析,决定用json格式,将实体的属性名添加到元素的name属性中,组成结果时用元素的name属性做名称,value属性做值
遍历表格中每一行,并添加到一个数组中。取到的结果格式就是这样的 {"Relation":"Zery","RelativesName":"Zhang"},传到后台时将其序列化成对象就可以了
- <input name="RelativesName" type="text" style="width: 100px" class="required" />
代码:
- //取表格所有数据
- //返回值为一个数组,数组内每一个元素对应一行内的数据;
- $.fn.tables.getResult = function (gridId) {
- var resultArray = new Array();
- $("#" + gridId).find("tr").slice(1).each(function () {
- var trResult = "{";
- $(this).find("td").each(function () {
- var $child = $(this).children();
- if ($child.length > 1) {
- //td下有多个元素的(多个元素会用"|"拼接起来)
- //td下有多个元素的暂时禁用
- //$child.each(function () {
- // //alert($(this).attr("type"));
- // switch ($(this).attr("type")) {
- // case "text":
- // //alert($child.val() + "文件框的!");
- // trResult += '"' + $(this).attr("name") + '"' + ":" + '"' + $(this).val() + '"' + ",";
- // break;
- // case "select":
- // // alert($(this).find("option:selected").text());
- // trResult += '"' + $(this).attr("name") + '"' + ":" + '"' + $(this).find("option:selected").val() + '"' + ",";
- // break;
- // case "checkbox":
- // if ($(this).attr("checked") === "checked") {
- // trResult += '"' + $(this).attr("name") + '"' + ":" + '"' + $(this).val() + '"' + ",";
- // }
- // break;
- // case "radio":
- // if ($(this).attr("checked") === "checked") {
- // trResult += '"' + $(this).attr("propertys") + '"' + ":" + '"' + $(this).val() + '"' + ",";
- // }
- // break;
- // default:
- // }
- //});
- // trResult.push(valueStr);
- } else {
- //td 下只有一个元素
- switch ($child.attr("type")) {
- case "text":
- trResult += '"' + $child.attr("name") + '"' + ":" + '"' + $child.val() + '"' + ",";
- break;
- case "select":
- trResult += '"' + $child.attr("name") + '"' + ":" + '"' + $child.find("option:selected").val() + '"' + ",";
- break;
- case "checkbox":
- if ($(this).attr("checked") === "checked") {
- trResult += '"' + $child.attr("name") + '"' + ":" + '"' + $child.val() + '"' + ",";
- } else {
- trResult += '"' + $child.attr("name") + '"' + ":0" + '"' + ",";
- }
- break;
- case "radio":
- if ($(this).attr("checked") === "checked") {
- trResult += '"' + $child.attr("propertys") + '"' + ":" + '"' + $child.val() + '"' + ",";
- } else {
- trResult += '"' + $child.attr("propertys") + '"' + ":0" + '"' + ",";
- }
- break;
- default:
- }
- }
- });
- trResult = trResult.substring(0, trResult.length - 1);
- resultArray.push(trResult + "}");
- });
- return resultArray;
- };
2.3 验证行数据:
思路:遍历每行中的元素根据元素类型来做判空处理,如果为空则在元素后追加提示信息,如果元素需要自定义错误信息时可以给元素加一个errormsg属性
代码:
- //验证行
- $.fn.tables.validateRow = function (gridId) {
- //是否验证通过
- var isPass = true;
- $("#" + gridId).find("tr").slice(1).each(function () {
- $(this).find("td").each(function () {
- if ($(this).children().hasClass('text-error'))
- {
- return isPass = false;
- }
- var $this = $(this).children();
- if ($this.length > 1) {
- //checkbox选中数
- if ($(this).find("input[type='checkbox']").length > 0) {
- var checkedNum = $(this).find("input[type='checkbox'][checked]").length;
- if (checkedNum <= 0) {
- //TODO:复选框应该默认有选中项目不需要做验证
- // message = "此字段必填";
- //return message;
- }
- }
- //radio选中数
- if ($(this).find("input[type='radio']").length > 0) {
- var radioNum = $(this).find("input[type='radio'][checked]").length;
- if (radioNum <= 0) {
- //TODO:复选框应该默认有选中项目不需要做验证
- //message = "此字段必填";
- //return message;
- }
- }
- } else {
- switch ($this.attr("type")) {
- case "text":
- var errorMsg = "此字段为必填项!";
- if ($this.hasClass("required")) {
- if ($.trim($this.val()) == "") {
- isPass = false;
- if ($this.attr("errormsg") == undefined) {
- $this.addClass('error').after("<span class='help-block text-error'>" + errorMsg + "</span>");
- } else {
- errorMsg = $this.attr("errormsg");
- $this.addClass('error').after("<span class='help-block text-error'>" + errorMsg + "</span>");
- }
- }
- }
- if ($this.hasClass("detepickers")) {
- if ($.trim($this.val()) == "") {
- isPass = false;
- $this.addClass('error').after("<span class='help-block text-error'>" + errorMsg + "</span>");
- }
- }
- break;
- case "select":
- //默认有选中项不需要做验证
- //若选中项为“请选择”时可以根据选中值来验证
- break;
- default:
- }
- }
- });
- });
- return isPass;
- };
2.4 绑定数据
思路: 后台取到值后序列化成json后通过隐藏域传到前端,前端根据元素的name属性值与 Json串中的的key 做对比如果相等则赋值, 需要注意的是 所有的元素我都是用type属性来区分的 如果该元素没有type属性则需要自己加上 如 select 元素 需要加上 type='select'
代码:
- //绑定数据
- $.fn.tables.bindData = function (gridId, tbResult) {
- //返回结果为一个数组
- // var result = $("#<%=hd"+gridId+".ClientID %>").val();
- var jsons = $.parseJSON(tbResult);
- if (jsons == null) {
- return;
- }
- var trHtml = $("#" + gridId).find("tr").slice(1).first().html();
- //遍历行结果
- for (var i = 0; i < jsons.length; i++) {
- var trnum = $("#" + gridId).find("tr").slice(1).length - 1;
- if (i > trnum) {
- $("#" + gridId).append("<tr>" + trHtml + "</tr>");
- }
- //遍历行中每一列的key
- for (var key in jsons[i]) {
- $("#" + gridId).find("tr").eq(i + 1).find("td").each(function () {
- var $child = $(this).children();
- if ($child.attr("name") === key || $child.attr("propertys") === key) {
- switch ($child.attr("type")) {
- case "text":
- $child.val(jsons[i][key]);
- break;
- case "select":
- //可以根据value 来设置选中项目
- $child.find("option").each(function () {
- var value = $(this).val();
- if (value === jsons[i][key]) {
- $(this).attr("selected", true);
- }
- });
- break;
- case "checkbox":
- //可以根据value 来设置选中项目
- $child.each(function () {
- var name = $(this).attr("name");
- if (name === key && $(this).val() === jsons[i][key]) {
- $(this).attr("checked", true);
- }
- });
- case "radio":
- $child.each(function () {
- var name = $(this).attr("propertys");
- if (name === key && $(this).val() === jsons[i][key]) {
- $(this).attr("checked", true);
- }
- });
- break;
- case "a":
- case "button":
- $child.attr("value", jsons[i][key]);
- break;
- default:
- }
- }
- });
- }
- }
- };
以上都只是简单介绍思路,虽然写出来只有一点点,但是 当时在开发时在某些点却时想了很久,因为针对项目做了很多的特殊修改,所以这里只实现很基本的功能,代码也仅供参考,主要还是实现的思路
三 总结
项目在几天前已经上线了,用户的反应还不错,也算对得起自己的付出吧,当时承担着项目延期的风险,决定用js来做的理由很简单,只是想把用户体验做的好一点。
做完后想想,有时候我们应该对自己要求高一点,不要总活在自己的舒适区,有挑战才能有成长。
源码示例下载:http://files.cnblogs.com/zery/WebApplication1.rar
如果您觉得本文有给您带来一点收获,不妨点个推荐,为我的付出支持一下,谢谢~
如果希望在技术的道路上能有更多的朋友,那就关注下我吧,让我们一起在技术的路上奔跑
jquery表格动态增删改及取数据绑定数据完整方案的更多相关文章
- jQuery EasyUI/TopJUI实现数据表格的增删改查功能(不写js,纯HTML实现!!!)
jQuery EasyUI/TopJUI实现数据表格的增删改查功能(不写js,纯HTML实现!!!) 废话不多说,直接贴上代码 <table id="configEdatagrid&q ...
- JQuery实现表格动态增加行并对新行添加事件
实现功能: 通常在编辑表格时表格的行数是不确定的,如果一次增加太多行可能导致页面内容太多,反应变慢:通过此程序实现表格动态增加行,一直保持最下面有多个空白行. 效果: 一:原始页面 二:表1增加新行并 ...
- 用AngularJS实现对表格的增删改查(仅限前端)
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- SQL server 创建 修改表格 及表格基本增删改查 及 高级查询 及 (数学、字符串、日期时间)函数[转]
SQL server 创建 修改表格 及表格基本增删改查 及 高级查询 及 (数学.字符串.日期时间)函数 --创建表格 create table aa ( UserName varchar(50 ...
- EasyUI-在行内进行表格的增删改操作
第一篇笔记中记录了如何实现表格的增删改,那个是点击之后跳出来一个对话框然后进行的,这里是在表格本身上进行的操作,也很简单,但是这里发现一个版本问题,也可以说是兼容性问题. 1.首先我们看引用的js和c ...
- easyui学习笔记2—在行内进行表格的增删改操作
第一篇笔记中记录了如何实现表格的增删改,那个是点击之后跳出来一个对话框然后进行的,这里是在表格本身上进行的操作,也很简单,但是这里发现一个版本问题,也可以说是兼容性问题. 1.首先我们看引用的js和c ...
- 【原生】js实现表格的增删改查
说在前面的,写给小白白的,大神请绕道~ 今天用原生js写一下动态表格的增删改查,主要是熟悉一下js的DOM操作. 首先,做一个表格,用来显示提交的数据,如图下: 此处,我添加了编号.姓名.密码.生日. ...
- js实现表格的增删改查
这份代码实现了对表格的增加,删除,更改,查询. 点击一次添加按钮,表格会增加一行. 点击重置按钮,输入框的内容会被清空. 添加一行后,最后两格为更改和删除.点击更改,原有内容会各自显示在一个输入框内, ...
- 基于AT UI实现表格的增删改查遇到的坑
基于AT UI实现表格的增删改查遇到的坑 坑一.表格数据加载的渲染报错 报错:Error in render: "TypeError: Cannot read property 'isChe ...
随机推荐
- (有趣)chrome不同浏览器版本对display:flex和溢出隐藏显示省略符号的bug
项目中碰到一个十分有趣的情形: 布局要求是这样:右边创建新订单是固定宽度80px,左侧是自适应宽度,溢出隐藏.如下图. 这里布局不用说肯定使用display:flex的.左侧flex:1;右侧widt ...
- 谷歌浏览器下载地址 chrome最新版本 百度云地址
每次下载更新谷歌浏览器是一件很蛋疼的事情.百度搜索"谷歌浏览器下载地址",居然有很多骗子网站,相信有很多不知所以的人中招了.收集了一些chrome的安装包,放在了百度云里面(打不开 ...
- 你所不知的 CSS ::before 和 ::after 伪元素用法
CSS 有两个说不上常用的伪类 :before 和 :after,偶尔会被人用来添加些自定义格式什么的,但是它们的功用不仅于此.前几天发现了 Creative Link Effects 这个非常有意思 ...
- mysql时间加减函数
先来看一个例子: select now(),now()+0; 可以看到now()函数可以返回一个时间也可以返回一个数字,就看大家如何使用.如果相对当前时间进行增加或减少,并不能直接加上或减去一个数字而 ...
- arcgis for flex展示GIS基本功能
1.地图框选搜索: 这是空间查询,在地图上框选一定的范围,然后搜索出在这个范围之内的所有信息,搜索到的详细信息在列表框显示出来 2.属性查询: 3.数据库展示: 4.绘制图形: 地图上绘制各种不同形状 ...
- C#和ASP.NET之事件
事件是一种用于类和类之间传递消息或触发新的行为的编程方式.通过提供事件的句柄,能够把控件和可执行的代码联系在一起, 如用户单击Button控件触发Click事件后就执行相应的事件处理代码. 事件的声明 ...
- SQLite学习笔记(六)&&共享缓存
介绍 通常情况下,sqlite中每个连接都会一个独立的pager对象,pager对象中管理了该连接的缓存信息,通过pragma cache_size指令可以设置缓存大小,默认是2000个page,每个 ...
- 安装mysql后的基本配置
1.添加环境变量 右键 此电脑->属性->高级系统设置->环境变量,在系统变量里面找到Path,双击.点击编辑,将mysql中bin文件的路径添加到最后一行,如:F:\AppSev\ ...
- springMVC基础controller类
此文章是基于 搭建SpringMVC+Spring+Hibernate平台 功能:设置请求.响应对象:session.cookie操作:ajax访问返回json数据: 创建springMVC基础con ...
- 【Windows编程】系列第十一篇:多文档界面框架
前面我们所举的例子中都是单文档界面框架,也就是说这个窗口里面的客户区就是一个文档界面,可以编写程序在里面输入或者绘制文本和图形输出,但是不能有出现多个文档的情况.比如下面的UltraEdit就是一个典 ...