jQuery Form - 序列化为多维数组?

Posted

技术标签:

【中文标题】jQuery Form - 序列化为多维数组?【英文标题】:jQuery Form - Serialize into multi dimensional array? 【发布时间】:2016-12-29 18:32:01 【问题描述】:

我需要从form 获取值,将其格式化为 JSON 并通过 AJAX 发布。这是我想要实现的格式:


  items: [
     id: 7, name: 'Book', price: 5.7 ,
     id: 5, name: 'Pencil', price: 2.5 
  ]

这是 html

(function($)
  
  var $form = $('form');
  
  // serializeArray format is way off from what I need
  var rawData = $form.serializeArray();
  console.log(rawData)
  
)(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form>
  <fieldset>
    <h2>Product 1</h2>
    <input type="hidden" name="items[0][id]" value="7">
    <input type="text" name="items[0][name]" value="Book">
    <input type="number" name="items[0][price]" value="5.7">
  </fieldset>
  
  <fieldset>
    <h2>Product 2</h2>
    <input type="hidden" name="items[1][id]" value="5">
    <input type="text" name="items[1][name]" value="Pencil">
    <input type="number" name="items[1][price]" value="2.5">
  </fieldset>
</form>

我应该循环并使用正则表达式来解析name吗?还是有内置方式?

如果需要,我可以更改&lt;form&gt; 格式。

【问题讨论】:

不,我的意思是我想从输入中获取所有数据以形成该 JSON。我需要通过 Ajax 发布它。我将编辑问题以使其更清晰 序列化在这里不起作用,需要手动进行 【参考方案1】:

这里不能使用默认的序列化,而是可以像这样手动进行序列化

(function($) 

  var $fieldsets = $('form fieldset');

  var items = $fieldsets.map(function(i, fs) 
    var obj = ;
    $(fs).find('input').each(function() 
      obj[this.name.match(/\[([^\[]*)\]$/)[1]] = this.value;
    );
    return obj;
  ).get();

  var rawData = 
    items: items
  ;
  console.log(rawData)

)(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form>
  <fieldset>
    <h2>Product 1</h2>
    <input type="hidden" name="items[0][id]" value="7">
    <input type="text" name="items[0][name]" value="Book">
    <input type="number" name="items[0][price]" value="5.7">
  </fieldset>

  <fieldset>
    <h2>Product 2</h2>
    <input type="hidden" name="items[1][id]" value="5">
    <input type="text" name="items[1][name]" value="Pencil">
    <input type="number" name="items[1][price]" value="2.5">
  </fieldset>
</form>

【讨论】:

【参考方案2】:

请看看这种方法。我们不能只使用$.serializeArray(),还需要一些自定义代码,如下所示。实际上,我们需要遍历所有 &lt;fieldset&gt; 来获取我们需要的 JSON:

(function($) 

  var $form = $('form');
  var fieldSets = $form.find("fieldset");
  var result = 
    items: []
  ;
  fieldSets.each(function() 
    var fields = ;
    $.each($(this).serializeArray(), function() 
      fields[this.name] = this.value;
    );
    result.items.push(fields);
  );

  console.log(result);
)(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form>
  <fieldset>
    <h2>Product 1</h2>
    <input type="hidden" name="id" value="7">
    <input type="text" name="name" value="Book">
    <input type="number" name="price" value="5.7">
  </fieldset>

  <fieldset>
    <h2>Product 2</h2>
    <input type="hidden" name="id" value="5">
    <input type="text" name="name" value="Pencil">
    <input type="number" name="price" value="2.5">
  </fieldset>
</form>

注意:稍微修改了 HTML,而不是 name="items[0][id]" 我给出的 name="id"

【讨论】:

谢谢,这似乎是更简单的解决方案。【参考方案3】:

是的,您需要自己解析name 字段。没有解析自定义字段的自动化方法。当然,有多种方法可以做到这一点。

注意:我假设您的 name="items[0][id]" 字段指定这必须是结果数组中的第 0 项,并且此类 &lt;input&gt; 字段集不一定按项目 # 升序排列DOM。换句话说,item[N] 应该控制它成为&lt;form&gt; 中的第 Q 个&lt;fieldset&gt;

您可以使用 serializeArray() 然后处理该数据:

(function($)
  
  var $form = $('form');
  var data = $form.serializeArray();
  var result =  items:[];
  data.forEach(function(input)
    nameArray = input.name.split(/[[\]]/);
    item = nameArray[1];
    prop = nameArray[3];
    if(typeof result.items[item] !== 'object')
      result.items[item]=;
    
    if(typeof result.items[item][prop] !== 'undefined')
      //Consistency check the name attribute
      console.log('Warning duplicate "name" property =' + input.name);
    
    result.items[item][prop]=input.value;
  );
  console.log(result);
)(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form>
  <fieldset>
    <h2>Product 1</h2>
    <input type="hidden" name="items[0][id]" value="7">
    <input type="text" name="items[0][name]" value="Book">
    <input type="number" name="items[0][price]" value="5.7">
  </fieldset>
  
  <fieldset>
    <h2>Product 2</h2>
    <input type="hidden" name="items[1][id]" value="5">
    <input type="text" name="items[1][name]" value="Pencil">
    <input type="number" name="items[1][price]" value="2.5">
  </fieldset>
</form>

或者,您可以直接从 DOM 处理它:

(function($)

  var result =  items:[];
 
  $('form fieldset input').each(function()
    nameArray = this.name.split(/[[\]]/);
    item = nameArray[1];
    prop = nameArray[3];
    if(typeof result.items[item] !== 'object')
      result.items[item]=;
    
    if(typeof result.items[item][prop] !== 'undefined')
      //Consistency check the name attribute
      console.log('Warning duplicate "name" property =' + this.name);
    
    result.items[item][prop]=this.value;
  );
  console.log(result);
)(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form>
  <fieldset>
    <h2>Product 1</h2>
    <input type="hidden" name="items[0][id]" value="7">
    <input type="text" name="items[0][name]" value="Book">
    <input type="number" name="items[0][price]" value="5.7">
  </fieldset>
  
  <fieldset>
    <h2>Product 2</h2>
    <input type="hidden" name="items[1][id]" value="5">
    <input type="text" name="items[1][name]" value="Pencil">
    <input type="number" name="items[1][price]" value="2.5">
  </fieldset>
</form>

【讨论】:

为什么你认为这个解决方案会帮助 OP? 感谢您的回答。 items[0] 只是避免重复名称的示例。我想可以使用重复的名称,例如 idname,就像 vijayP 的回答一样 @DarcCode,谢谢。复制name 属性通常很方便(它可用于对元素进行分组)(例如getElementsByName())。还有一次,请在问题中提到 HTML 可以更改。当我阅读这个问题时,我假设您正在尝试使用 javascript 来获取您想要的基于 HTML 的 JSON,该 HTML 具有该精确格式。考虑到它的编写方式,该假设和 vijayP 的假设(可以方便地更改 HTML)都是有效的。在问题中指出具体情况将有助于人们为您提供更好的答案。 @Makyen 感谢您的建议,下次我提出问题时会提供更多详细信息。

以上是关于jQuery Form - 序列化为多维数组?的主要内容,如果未能解决你的问题,请参考以下文章

使用Jettison的多维数组

jquery数组内多维对象

使用 jQuery 访问多维 JSON 数组中的数据

表示为一维的多维数组(模板化为 n 维)

将多维数组的列格式化为一维数组

在c ++中将多维数组初始化为类成员