使用动态输入将表单数据序列化为JSON

时间:2022-11-24 08:41:01

I am trying to serialize my form data (name arrays) and so far I am only able to serialize the last object in the array. I can dynamically append a set of form fields and when I click submit it will still only append the new (last) object in the array. I've tried a lot of different ways to do this and this is the closest I've come. Here is the code in a playground - http://www.bootply.com/pv7fFLC1uJ. Example of what I would like to see:

我正在尝试序列化我的表单数据(名称数组),到目前为止,我只能序列化数组中的最后一个对象。我可以动态附加一组表单字段,当我单击提交时,它仍然只会在数组中附加新的(最后一个)对象。我已经尝试了很多不同的方法来做到这一点,这是我最接近的方式。这是操场上的代码 - http://www.bootply.com/pv7fFLC1uJ。我希望看到的例子:

{
  timeZonePicker: "-7",
  start: "09:00",
  end: "17:00",
  content: "San Francisco"
}
{
  timeZonePicker: "-3",
  start: "09:00",
  end: "17:00",
  content: "São Paulo"
}

HTML

<form class="form-inline fields_wrapper">
    <select class="form-control timeZonePicker" name="timeZonePicker[]" id="timeZoneId">
      <option value="-12" >(GMT -12:00) Eniwetok, Kwajalein</option>......
    </select>
    <input type="time" class="form-control start" name="start[]" value="">
    <input type="time" class="form-control end" name="end[]" value="">
    <input type="text" class="form-control content" name="content[]" value="">
</form>

jQuery

$.fn.serializeObject = function(options) { 
    var data = $(this).serializeArray(), obj = {};   
    $.each(data, function(i, el) {
        console.log(data);
        var key = el.name;
        //remove the brackets from each html name array
        if (key.slice(-1) == "]") {
          key = key.slice(0,-2);
        }  
        if (el.name in options) {
            obj[options[key]] = obj[options[key]] || {};
            obj[options[key]][key] = el.value;
        }
        else {
            obj[key] = el.value;
        }
    });
    return obj;
};

2 个解决方案

#1


0  

You aren't creating and returning an array. your object properties get overwritten in each iteration of each and you only return one object which is the last iteration

您不是在创建和返回数组。您的对象属性会在每次迭代中被覆盖,并且您只返回一个最后一次迭代的对象

try (untested):

$.fn.serializeObject = function(options) { 
    var data = $(this).serializeArray(), 
        // results array
        res = [];   
    $.each(data, function(i, el) {

      var obj={}

        console.log(data);
        var key = el.name;
        //remove the brackets from each html name array
        if (key.slice(-1) == "]") {
          key = key.slice(0,-2);
        }  
        if (el.name in options) {
            obj[options[key]] = obj[options[key]] || {};
            obj[options[key]][key] = el.value;
        }
        else {
            obj[key] = el.value;
        }

      res.push(obj)
    });
  // return array instead of the single object
    return res;
};

Whole thing would be a lot simpler if you gave wrapper of each row of data a common class and looped over those instead creating your own object without using serializeArray()

如果你给每一行数据的包装器提供一个公共类,并在不使用serializeArray()的情况下创建自己的对象,那么整个事情会简单得多。

#2


0  

As charlietfl said, you are returning just a single object, not an array.

正如charlietfl所说,你只返回一个对象,而不是一个数组。

The way you are doing it, you iterate through all objects that you have in the form at the same time. If you wish to go down that road, you have to know when you have created a single object, so you can add it into the array.

按照您的方式,您可以同时遍历表单中的所有对象。如果您希望沿着这条路前进,您必须知道何时创建了单个对象,因此您可以将其添加到数组中。

Here is a simple solution (not the prettiest one tho):

这是一个简单的解决方案(不是最漂亮的一个):

//build the json objects for each set of form fields
$.fn.serializeObject = function(options) { 
  var data = $(this).serializeArray(), obj = {}, all = []; 
    $.each(data, function(i, el) {
        var key = el.name;
        //remove the brackets from each html name array
        if (key.slice(-1) == "]") {
          key = key.slice(0,-2);
        }  
        if (el.name in options) {
            obj[options[key]] = obj[options[key]] || {};
            obj[options[key]][key] = el.value;
        }
        else {
            obj[key] = el.value;
        }

      if ((i + 1) % Object.keys(options).length == 0) {
        all.push(obj);
        obj = {};
      }
    });
    return all;
};

#1


0  

You aren't creating and returning an array. your object properties get overwritten in each iteration of each and you only return one object which is the last iteration

您不是在创建和返回数组。您的对象属性会在每次迭代中被覆盖,并且您只返回一个最后一次迭代的对象

try (untested):

$.fn.serializeObject = function(options) { 
    var data = $(this).serializeArray(), 
        // results array
        res = [];   
    $.each(data, function(i, el) {

      var obj={}

        console.log(data);
        var key = el.name;
        //remove the brackets from each html name array
        if (key.slice(-1) == "]") {
          key = key.slice(0,-2);
        }  
        if (el.name in options) {
            obj[options[key]] = obj[options[key]] || {};
            obj[options[key]][key] = el.value;
        }
        else {
            obj[key] = el.value;
        }

      res.push(obj)
    });
  // return array instead of the single object
    return res;
};

Whole thing would be a lot simpler if you gave wrapper of each row of data a common class and looped over those instead creating your own object without using serializeArray()

如果你给每一行数据的包装器提供一个公共类,并在不使用serializeArray()的情况下创建自己的对象,那么整个事情会简单得多。

#2


0  

As charlietfl said, you are returning just a single object, not an array.

正如charlietfl所说,你只返回一个对象,而不是一个数组。

The way you are doing it, you iterate through all objects that you have in the form at the same time. If you wish to go down that road, you have to know when you have created a single object, so you can add it into the array.

按照您的方式,您可以同时遍历表单中的所有对象。如果您希望沿着这条路前进,您必须知道何时创建了单个对象,因此您可以将其添加到数组中。

Here is a simple solution (not the prettiest one tho):

这是一个简单的解决方案(不是最漂亮的一个):

//build the json objects for each set of form fields
$.fn.serializeObject = function(options) { 
  var data = $(this).serializeArray(), obj = {}, all = []; 
    $.each(data, function(i, el) {
        var key = el.name;
        //remove the brackets from each html name array
        if (key.slice(-1) == "]") {
          key = key.slice(0,-2);
        }  
        if (el.name in options) {
            obj[options[key]] = obj[options[key]] || {};
            obj[options[key]][key] = el.value;
        }
        else {
            obj[key] = el.value;
        }

      if ((i + 1) % Object.keys(options).length == 0) {
        all.push(obj);
        obj = {};
      }
    });
    return all;
};