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

时间:2016-08-23 04:46:55

标签: javascript jquery arrays json forms

我需要从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>
&#13;
&#13;
&#13;

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

如果需要,我可以更改<form>格式。

3 个答案:

答案 0 :(得分:2)

您无法在此处使用默认序列化,而是可以执行手动序列化,例如

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

答案 1 :(得分:1)

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

注意:我假设你的name="items[0][id]"字段指定这必须是结果数组中的第0项,并且这些<input>字段集不一定是升序的在DOM中按项目#排序。换句话说,item[N]应该控制<fieldset>中的<form>

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

&#13;
&#13;
(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);
&#13;
<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>
&#13;
&#13;
&#13;

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

&#13;
&#13;
(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);
&#13;
<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>
&#13;
&#13;
&#13;

答案 2 :(得分:1)

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

&#13;
&#13;
(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);
&#13;
<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>
&#13;
&#13;
&#13;

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