JQuery - 将表单数据序列化为关联数组 [英] JQuery - Serialize form data to Associated Array

查看:46
本文介绍了JQuery - 将表单数据序列化为关联数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

与 $.serializeArray() 使用 jQuery 生成的数字索引格式相反,您如何将 HTML 表单数据序列化为关联数组?

jQuery.serializeArray 给出的输出使得很难使用数字索引键直接选择值,在表单输入中使用复选框时可能会发生轻微的索引偏移..

serializeArray 的输出

<预><代码>[0:[名称:'field-1',值:'val1'],1:[名称:'检查',值:'val2'],2:[名称:'检查',值:'val3']]

期望的输出 - 更可靠的格式和更简单的值访问

<预><代码>['field-1' : 'val1','检查':[0:'val2',1:'val3']]

解决方案

UPDATE 2021

这是一个非常老的问题,现在现代 JavaScript 变得更加宽容,使得最初发布的解决方案已经过时,对 JavaScript 的改进也使 jQuery 变得相当过时.

自从这篇原创文章以来,我们取得了长足的进步,支持序列化 数组、对象甚至两者的嵌套组合,在字体/后端环境中传入和传出 JSON 要简单得多.

看看以下提交复杂用户输入的选项:

原生

<块引用>

使用 JSON

https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/JSON

<块引用>

使用 JSON 请求选项获取示例

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#supplying_request_options

Axios

<块引用>

替代原生 ES6+ JavaScript 中的 fetch.Axios 会为你处理数组和对象的序列化.

https://github.com/axios/axios

NodeJS

<块引用>

QueryString - 如果您的项目支持,您可以从 NodeJS 导入这个帮助器类.

https://nodejs.org/api/querystring.html)


以下是过时的内容

对我有用的解决方案是编写我自己的 jQuery 函数 $.serializeAssoc() 和 $.serializeObject() 替代方案,它们也可以处理来自表单上多选选项的多维数组.

这两个函数各有优缺点;我使用 serializeAssoc 来简化直接通用值访问的表单数据,通常在 JS 验证中.

serializeObject 已经在使用自定义数字键索引的多功能表单中派上用场,简化了从多选字段的复杂表单设置或具有由 DOM 构建的值的表单提交的信息的数据配对,其中表单中的数据具有父级和子关系,serializeAssoc 不能很好处理.

serializeAssoc

以下函数允许长度检查,但存在自定义数字键索引问题,在 AJAX 调用中提交数组时会导致索引填充

$.fn.serializeAssoc = function() {无功数据 = {};$.each( this.serializeArray(), function( key, obj ) {var a = obj.name.match(/(.*?)\[(.*?)\]/);if(a !== null){var subName = a[1];var subKey = a[2];如果(!数据[子名称]){数据[子名称] = [ ];}如果(!subKey.length){subKey = data[subName].length;}如果(数据[子名称][子键]){if( $.isArray( data[subName][subKey] ) ) {数据[subName][subKey].push(obj.value);} 别的 {数据[subName][subKey] = [ ];数据[subName][subKey].push(obj.value);}} 别的 {数据[子名称][子键] = obj.value;}} 别的 {如果(数据[对象名称]){if( $.isArray( data[obj.name] ) ) {数据[obj.name].push(obj.value);} 别的 {数据[obj.name] = [ ];数据[obj.name].push(obj.value);}} 别的 {数据[obj.name] = obj.value;}}});返回数据;};


serializeObject

以下函数允许自定义数字索引而不会导致填充,但会阻止长度检查.如果需要,使用 each 循环检查索引键计数.如果在 AJAX 调用中提交对象,您必须首先使用 JSON.Stringify 并将值传递到要在服务器端解码的 var 中,因为直接使用会导致某些浏览器出现意外的行尾错误.

$.fn.serializeObject = function() {无功数据 = {};$.each( this.serializeArray(), function( key, obj ) {var a = obj.name.match(/(.*?)\[(.*?)\]/);if(a !== null){var subName = new String(a[1]);var subKey = new String(a[2]);如果(!数据[子名称]){数据[子名称] = { };数据[子名称].length = 0;};如果(!subKey.length){subKey = data[subName].length;}如果(数据[子名称][子键]){if( $.isArray( data[subName][subKey] ) ) {数据[subName][subKey].push(obj.value);} 别的 {数据[subName][subKey] = { };数据[subName][subKey].push(obj.value);};} 别的 {数据[子名称][子键] = obj.value;};数据[子名称].长度++;} 别的 {var keyName = new String(obj.name);如果(数据[键名]){if( $.isArray( data[keyName] ) ) {数据[keyName].push(obj.value);} 别的 {数据[键名] = { };数据[keyName].push(obj.value);};} 别的 {数据[键名] = obj.value;};};});返回数据;};


用法:

添加功能

样本表格

<输入类型=文本"名称=我的名字"/><选择名称=控制台"多个><选择的选项>PC</option><选择的选项>XBOX 360</option><选择的选项>PS3</option></选择><输入类型=文本"名称=样本[100]";值=马里奥"/><输入类型=文本"名称=样本[101]";值=兄弟"/><输入类型=提交"名称=提交"值=提交"/></表单>

使用函数

动态表单示例

<输入类型=文本"名称=我的名字"值=Spuggy"/><div id="字符"><输入类型=文本"名称=字符[]";值=马里奥"/><输入类型=文本"名称=字符[]";值=索尼克"/>

<div id="控制台"><输入类型=文本"名称=控制台[xbox]";值=XBOX 一"/><输入类型=文本"名称=控制台[游戏站]";值=PlayStation 4"/>

<输入类型=提交"名称=提交"值=提交"/></表单><脚本>(功能($){$('#myForm').submit(function(e){e.preventDefault();var formData = $('#myForm').serializeAssoc();控制台日志(表单数据);});})(jQuery);

动态表单输出

<预><代码>[myName: 'Spuggy',特点: [0:'马里奥',1:'索尼克'],安慰: ['xbox': 'Xbox One',游戏机":PlayStation 4"]]

How do you serialise HTML form data to an Associated Array as opposed to the numeric index format produced by $.serializeArray() using jQuery?

The output given by jQuery.serializeArray makes it difficult to directly select values using a numeric index key, Slight index shifts can occur when check boxes are used in form input..

Output of serializeArray

[
  0: [name: 'field-1', value: 'val1'],
  1: [name: 'check', value: 'val2'],
  2: [name: 'check', value: 'val3']
]

Desired Output - More reliable format and simpler value access

[
  'field-1' : 'val1',
  'check' : [ 0 : 'val2', 1 : 'val3' ]
]

解决方案

UPDATE 2021

This was a really old problem, Modern JavaScript is far more forgiving these days making the original solution posted obsolete, improvements to JavaScript have also made jQuery quite obsolete.

Since this original post, we have come leaps and bounds, support for serializing Arrays, Objects and even nested combinations of both, to and from JSON in the font/back-end environments is a lot more simple.

Take a look at the following options for submitting complex user input:

Native

Working with JSON

https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/JSON

Fetch Example with JSON Request Options

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#supplying_request_options

Axios

Alternative to fetch in native ES6+ JavaScript. Axios will take care of serialization of Arrays and Objects for you.

https://github.com/axios/axios

NodeJS

QueryString - You can import this helper class from NodeJS if supported by your project.

https://nodejs.org/api/querystring.html)


OLD OUT OF DATE CONTENT BELOW

Solution that worked for me was to write my own jQuery functions $.serializeAssoc() and $.serializeObject() alternatives that could also handle multidimensional arrays from multi selection options on forms.

These two functions have their pros and cons; I use serializeAssoc to simplify form data for direct generic value access, typically in JS Validation.

serializeObject has come in handy with multifunction forms using custom numeric key indexes, Simplifying data paring of information submitted from a complicated form set-up of multi-selection fields or forms with values built by DOM where data in a form has parent and child relationships, something serializeAssoc can't handle very well.

serializeAssoc

Following function allows length checks but presents problems with custom numeric key indexes, When submitting the array in an AJAX call it causes index padding

$.fn.serializeAssoc = function() {
  var data = {};
  $.each( this.serializeArray(), function( key, obj ) {
    var a = obj.name.match(/(.*?)\[(.*?)\]/);
    if(a !== null)
    {
      var subName = a[1];
      var subKey = a[2];

      if( !data[subName] ) {
        data[subName] = [ ];
      }

      if (!subKey.length) {
        subKey = data[subName].length;
      }

      if( data[subName][subKey] ) {
        if( $.isArray( data[subName][subKey] ) ) {
          data[subName][subKey].push( obj.value );
        } else {
          data[subName][subKey] = [ ];
          data[subName][subKey].push( obj.value );
        }
      } else {
        data[subName][subKey] = obj.value;
      }
    } else {
      if( data[obj.name] ) {
        if( $.isArray( data[obj.name] ) ) {
          data[obj.name].push( obj.value );
        } else {
          data[obj.name] = [ ];
          data[obj.name].push( obj.value );
        }
      } else {
        data[obj.name] = obj.value;
      }
    }
  });
  return data;
};


serializeObject

Following function below allows custom numeric indexes without causing padding but prevents length check. Check index key counts using an each loop if required. If submitting the object in an AJAX call you must first use JSON.Stringify and pass the value in a var to be decoded server side as direct usage causes an Unexpected end of line error in some browsers.

$.fn.serializeObject = function() {
    var data = {};
    $.each( this.serializeArray(), function( key, obj ) {
        var a = obj.name.match(/(.*?)\[(.*?)\]/);
        if(a !== null)
        {
            var subName = new String(a[1]);
            var subKey = new String(a[2]);
            if( !data[subName] ) {
              data[subName] = { };
              data[subName].length = 0;
            };
            if (!subKey.length) {
                subKey = data[subName].length;
            }
            if( data[subName][subKey] ) {
              if( $.isArray( data[subName][subKey] ) ) {
                data[subName][subKey].push( obj.value );
              } else {
                data[subName][subKey] = { };
                data[subName][subKey].push( obj.value );
              };
            } else {
                data[subName][subKey] = obj.value;
            };
            data[subName].length++;
        } else {
            var keyName = new String(obj.name);
            if( data[keyName] ) {
                if( $.isArray( data[keyName] ) ) {
                    data[keyName].push( obj.value );
                } else {
                    data[keyName] = { };
                    data[keyName].push( obj.value );
                };
            } else {
                data[keyName] = obj.value;
            };
        };
    });
    return data;
};


Usage:

Adding the function

<script>
  (function($){
    $.fn.serializeAssoc = function() {
      ... As Presented Above ...
    };
    $.fn.serializeObject = function() {
      ... As Presented Above ...
    };
  })(jQuery);
</script>

Sample Form

<form id="myForm">
  <input type="text" name="myName" />

  <select name="consoles" multiple>
    <option selected>PC</option>
    <option selected>XBOX 360</option>
    <option selected>PS3</option>
  </select>

  <input type="text" name="sample[100]" value="Mario" />
  <input type="text" name="sample[101]" value="Brothers" />

  <input type="submit" name="submit" value="Submit" />
</form>

Using the function

<script>
  (function($) {
    $('#myForm').submit(function(e){
      e.preventDefault();
      var formData = $('#myForm').serializeAssoc();
      console.log(formData);
    });
  })(jQuery);
</script>

Dynamic form example

<form id="myForm">
  <input type="text" name="myName" value="Spuggy" />

  <div id="characters">
    <input type="text" name="character[]" value="Mario" />
    <input type="text" name="character[]" value="Sonic" />
  </div>

  <div id="consoles">
    <input type="text" name="console[xbox]" value="XBOX One" />
    <input type="text" name="console[playstation]" value="PlayStation 4" />
  </div>

  <input type="submit" name="submit" value="Submit" />
</form>

<script>
  (function($) {
    $('#myForm').submit(function(e){
      e.preventDefault();
      var formData = $('#myForm').serializeAssoc();
      console.log(formData);
    });
  })(jQuery);
</script>

Dynamic form Output

[
  myName: 'Spuggy',
  character: [
    0: 'Mario',
    1: 'Sonic'
  ],
  console: [
    'xbox': 'XBOX One',
    'playstation': 'PlayStation 4'
  ]
]

这篇关于JQuery - 将表单数据序列化为关联数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆