zoukankan      html  css  js  c++  java
  • 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=" 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;
        };
    View Code

    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;
    
        };
    View Code

    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:
                            }
                        }
                    });
    
                }
    
            }
        };
    View Code

    以上都只是简单介绍思路,虽然写出来只有一点点,但是 当时在开发时在某些点却时想了很久,因为针对项目做了很多的特殊修改,所以这里只实现很基本的功能,代码也仅供参考,主要还是实现的思路

    三  总结

       项目在几天前已经上线了,用户的反应还不错,也算对得起自己的付出吧,当时承担着项目延期的风险,决定用js来做的理由很简单,只是想把用户体验做的好一点。

    做完后想想,有时候我们应该对自己要求高一点,不要总活在自己的舒适区,有挑战才能有成长。

    源码示例下载:http://files.cnblogs.com/zery/WebApplication1.rar

    如果您觉得本文有给您带来一点收获,不妨点个推荐,为我的付出支持一下,谢谢~

    如果希望在技术的道路上能有更多的朋友,那就关注下我吧,让我们一起在技术的路上奔跑

  • 相关阅读:
    1203 有穷自动机
    1111 评论
    C语言文法 改
    用户调研
    阅读《构建之法》 第8 第9 第10章
    sprint冲刺(第二天)
    sprint初步计划(第一天)
    作业6 团队项目之需求
    作业5 四则运算 测试与封装 5.1 5.2
    作业5 四则运算 测试与封装 5.1
  • 原文地址:https://www.cnblogs.com/zery/p/3917695.html
Copyright © 2011-2022 走看看