【问题标题】:jQuery Form - Serialize into multi dimensional array?jQuery Form - 序列化为多维数组?
【发布时间】: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 发布它。我将编辑问题以使其更清晰
  • 序列化在这里不起作用,需要手动进行

标签: javascript jquery arrays json forms


【解决方案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 感谢您的建议,下次我提出问题时会提供更多详细信息。
    猜你喜欢
    • 1970-01-01
    • 2016-09-15
    • 2011-05-03
    • 2015-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多