一 前言

  上一篇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表格动态增删改及取数据绑定数据完整方案的更多相关文章

  1. jQuery EasyUI/TopJUI实现数据表格的增删改查功能(不写js,纯HTML实现!!!)

    jQuery EasyUI/TopJUI实现数据表格的增删改查功能(不写js,纯HTML实现!!!) 废话不多说,直接贴上代码 <table id="configEdatagrid&q ...

  2. JQuery实现表格动态增加行并对新行添加事件

    实现功能: 通常在编辑表格时表格的行数是不确定的,如果一次增加太多行可能导致页面内容太多,反应变慢:通过此程序实现表格动态增加行,一直保持最下面有多个空白行. 效果: 一:原始页面 二:表1增加新行并 ...

  3. 用AngularJS实现对表格的增删改查(仅限前端)

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  4. SQL server 创建 修改表格 及表格基本增删改查 及 高级查询 及 (数学、字符串、日期时间)函数[转]

    SQL server 创建 修改表格 及表格基本增删改查 及 高级查询 及 (数学.字符串.日期时间)函数   --创建表格 create table aa ( UserName varchar(50 ...

  5. EasyUI-在行内进行表格的增删改操作

    第一篇笔记中记录了如何实现表格的增删改,那个是点击之后跳出来一个对话框然后进行的,这里是在表格本身上进行的操作,也很简单,但是这里发现一个版本问题,也可以说是兼容性问题. 1.首先我们看引用的js和c ...

  6. easyui学习笔记2—在行内进行表格的增删改操作

    第一篇笔记中记录了如何实现表格的增删改,那个是点击之后跳出来一个对话框然后进行的,这里是在表格本身上进行的操作,也很简单,但是这里发现一个版本问题,也可以说是兼容性问题. 1.首先我们看引用的js和c ...

  7. 【原生】js实现表格的增删改查

    说在前面的,写给小白白的,大神请绕道~ 今天用原生js写一下动态表格的增删改查,主要是熟悉一下js的DOM操作. 首先,做一个表格,用来显示提交的数据,如图下: 此处,我添加了编号.姓名.密码.生日. ...

  8. js实现表格的增删改查

    这份代码实现了对表格的增加,删除,更改,查询. 点击一次添加按钮,表格会增加一行. 点击重置按钮,输入框的内容会被清空. 添加一行后,最后两格为更改和删除.点击更改,原有内容会各自显示在一个输入框内, ...

  9. 基于AT UI实现表格的增删改查遇到的坑

    基于AT UI实现表格的增删改查遇到的坑 坑一.表格数据加载的渲染报错 报错:Error in render: "TypeError: Cannot read property 'isChe ...

随机推荐

  1. 鼠标滑过图片变暗文字链接滑出jQuery特效

    效果体验:http://hovertree.com/texiao/jquery/7.htm HTML文件代码: <!DOCTYPE html> <html xmlns="h ...

  2. 【HTML5&CSS3进阶学习01】气泡组件的实现

    前言 气泡组件在实际工作中非常普遍,无论是网页中还是app中,比如: 我们这里所谓气泡组件是指列表型气泡组件,这里就其dom实现,css实现,js实现做一个讨论,最后对一些细节点做一些说明,希望对各位 ...

  3. 在SharePoint中创建可自定义属性的文件夹

    概况 阅读时间:约5分钟 适用版本:SharePoint Server 2010及以上 面向用户:普通用户.管理员.开发人员 难度指数:★★★☆☆ SharePoint中的文件夹分为2种,一种是文档库 ...

  4. SharePoint 2013 托管导航及相关配置

    设计完善的导航可告诉您网站的用户大量有关网站所提供业务.产品和服务的信息.通过更新导航背后的分类法,可以推动业务并保持更新,而不必在过程中重新创建其网站导航.在 SharePoint 2013 中,可 ...

  5. Java的异常处理

    Java的异常处理是通过5个关键字来实现的:try,catch,throw,throws,finally.JB的在线帮助中对这几个关键字是这样解释的:       Throws: Lists the ...

  6. __block 和 __weak的区别

    Blocks理解: Blocks可以访问局部变量,但是不能修改 如果修改局部变量,需要加__block __block int multiplier = 7; int (^myBlock)(int) ...

  7. Linux-1:安装&忘记密码&CRT连接centos 6.5

    我是在虚拟机VM安装的centos 6.5 一.Linux安装 Ctrl + Alt:鼠标退出LINUX界面 安装我是参考,当然也可以根据网上教程安装:http://oldboy.blog.51cto ...

  8. 微信小程序 - 开发指南

    一.下载并安装开发工具 下载地址 二.创建项目 打开开发工具 添加项目 进入预览和调试界面 代码编辑器 编译并预览 三.启动流程 四.适用场景 五.技术框架 六.科普 [图片较大 - 点击查看]

  9. Ant:build.xml 结构

     Ant build.xml 结构 project target task data property datatype v\:* {behavior:url(#default#VML);} o\:* ...

  10. DB2 JDBC

    官方文档: http://www-01.ibm.com/support/knowledgecenter/SSEPGG_10.1.0/com.ibm.db2.luw.apdv.java.doc/src/ ...