JS表单序列化与反序列化代码

转载自:https://www.oschina.net/code/snippet_2438265_52549

JS表单序列化与反序列化代码.
jQuery有这两个方法 .serializeArray() 与.serialize().
.serializeArray()返回: Array
描述: 将用作提交的表单元素的值编译成拥有name和value对象组成的数组。例如[ { name: a value: 1 }, { name: b value: 2 },…]
一般用于Ajax POST
.serialize()返回: String
描述: 将用作提交的表单元素的值编译成字符串。如:single=Single&multiple=Multiple&multiple=Multiple3&check=check2&radio=radio1
一般用于GET

主要介绍.serializeArray()方法。
这个方法很方便,但是在多选的情况先会出现一些问题:
比如select,checkbox。此时返回的是[{multiple:Multiple},{multiple:Multiple3},{check:check1}},{check:check2}]
而我们期望的是[{multiple:[Multiple,Multiple3]},{check:[check1,check2]}]
而且我们通过ajax提交的请求数据根对象期望是json对象而不是直接的json数组。
针对上面说的情形我们写个工具方法用于处理:
想做试验:w3school去试验一把吧

表单序列化

/**
   * 序列化表单元素为JSON对象
   * @param form          Form表单id或表单jquery DOM对象
   * @returns {}
   */
  var serialize = function(form){
      var $form = (typeof(form)=="string" ? $("#"+form) : form);
      var dataArray =  $form.serializeArray();
     var result={};
      $(dataArray).each(function(){
          //如果在结果对象中存在这个值,那么就说明是多选的情形。
          if(result[this.name]){
              //多选的情形,值是数组,直接push
              result[this.name].push(this.value);
          }else{
              //获取当前表单控件元素
              var element = $form.find("[name='"+ this.name +"']")[0];
              //获取当前控件类型
              var type = ( element.type || element.nodeName ).toLowerCase();
              //如果控件类型为多选那么值就是数组形式,否则就是单值形式。
              result[this.name] = (/^(select-multiple|checkbox)$/i).test(type) ? [this.value] : this.value;
          }
      });
      return result;
  };

表单反序列化

/**
     * 设置表单值
     * @param form          Form表单id或表单jquery DOM对象
     * @param data          json对象,多选时为数组
     * 代码实现参考此开源项目https://github.com/kflorence/jquery-deserialize/
     */
    var deserialize = function(form,data){
        var rcheck = /^(?:radio|checkbox)$/i,
            rselect = /^(?:option|select-one|select-multiple)$/i,
            rvalue = /^(?:button|color|date|datetime|datetime-local|email|hidden|month|number|password|range|reset|search|submit|tel|text|textarea|time|url|week)$/i;

        var $form = (typeof(form)=="string" ? $("#"+form) : form);

        //得到所有表单元素
        function getElements( elements ) {
          //此处elements为jquery对象。这个map函数使用来便利elements数组的.如存在多个form表单,则便利多个form表单
            return elements.map(function(index, domElemen) {
                //this代表form表单,this.elements获取表单中的DOM数组. jQuery.makeArray 转换一个类似数组的对象成为真正的JavaScript数组。
                return this.elements ? jQuery.makeArray( this.elements ) : this;
              //过滤不启用的选项
            }).filter( ":input:not(:disabled)" ).get();
        }
        //把表单元素转为json对象
        function elementsToJson( elements ) {
            var current,elementsByName = {};
          //elementsByName对象为{控件名:控件元素或控件元素数组}
            jQuery.each( elements, function( i, element ) {
                current = elementsByName[ element.name ];
                elementsByName[ element.name ] = current === undefined ? element :
                    //如果已经是一个数组了,那么就添加,否则构造一个数组
                    ( jQuery.isArray( current ) ? current.concat( element ) : [ current, element ] );
            });
            return elementsByName;
        }

        var elementsJson = elementsToJson(getElements($form));
    //data是一个对象
        for(var key in data){
            var val = data[key];
            var dataArr = [];//更具数据直接构造一个jQUery序列化后的数组形式。
          //判断值是否为数组
            if( $.isArray(val)){
                for(var i= 0,v;v=val[i++];){
                    //是数组那么就变成多个对象形式
                    dataArr.push({name:key,value:v});
                }
            } else{
                //不是数组直接构造
                dataArr.push({name:key,value:val});
            }

            //根据数据构造的这个数组进行操作
            for(var m= 0,vObj;vObj=dataArr[m++];){
                var element;
                //如果表单中无元素则跳过
                if ( !( element = elementsJson[vObj.name] ) ) {
                    continue;
                }
              //判断元素是否为数组,暂时获取第一个元素,后面会有迭代赋值。
                var type = element.length?element[0]:element;
              //元素类型
                type = ( type.type || type.nodeName ).toLowerCase();

                var property = null;
              //是单值类型
                if ( rvalue.test( type ) ) {
                    element.value = (typeof(vObj.value)=="undefined" || vObj.value==null)?"":vObj.value;
                  //checkbox
                } else if ( rcheck.test( type ) ) {
                    property = "checked";
        //select
                } else if ( rselect.test( type ) ) {
                    property = "selected";
                }
                //判断类型是否为多选
                if(property) {
                    //如果是,则迭代多选的元素赋值
                    for(var n= 0,e;e=element[n++];){
                        if(e.value==vObj.value){
                          //设置选中
                            e[property] = true;
                        }
                    }
                }
            }
        }
    };
原创文章 45 获赞 151 访问量 11万+

猜你喜欢

转载自blog.csdn.net/u010697681/article/details/53713834