javascript - JQuery - 将表单数据序列化为关联数组

标签 javascript jquery arrays associative-array

<分区>

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

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

serializeArray 的输出

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

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

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

最佳答案

2021 年更新

这是一个非常古老的问题,如今现代 JavaScript 更加宽容,使得发布的原始解决方案已经过时,对 JavaScript 的改进也使 jQuery 变得相当过时。

自从这篇原帖以来,我们突飞猛进,支持serializing在字体/后端环境中传入和传出 JSON 的数组、对象甚至两者的嵌套组合要简单得多。

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

原生

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

公理

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)


下面是旧的过时内容

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

这两个功能各有利弊; 我使用 serializeAssoc 来简化直接通用值访问的表单数据,通常在 JS 验证中。

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

序列化关联

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

$.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;
};

序列化对象

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

$.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;
};

用法:

添加函数

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

示例表格

<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>

使用函数

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

动态表单示例

<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>

动态表单输出

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

关于javascript - JQuery - 将表单数据序列化为关联数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19643310/

相关文章:

c# - 将参数发送到 jQuery 的 Ajax 无效

javascript - 单击后禁止单击元素

javascript - 自动隐藏 tabbable 内的 "Load more"按钮

jquery - 为什么 jQuery.html() 能够成功接受 jQuery 对象,尽管文档说它不能?

JQuery Dialog 的 CSS 内容在换页时会保留

php - 在模型中获取值使用 asArray Yii2

arrays - 如何获取远程服务器主机名作为变量并使用它?

javascript ->var 是什么意思?

javascript - 使用 jquery 延迟 css 触发

c - 一遍又一遍地在String中使用struct(C语言)