0

I am currently getting data from a repeatable group form through serializeArray() as an object with this syntax:

group_field[0][address]:"street one"
group_field[0][number]:"10000"
group_field[0][city]:"nyc"
group_field[1][address]:"street two"
group_field[1][number]:"600"
group_field[1][city]:"washington"
group_field[2][address]:"street three"
group_field[2][number]:"34000"
group_field[2][city]:"paris"

I am trying to convert this to a multidimensional array, or nested object structure to group all the fields depending on the index between the first square brackets.

desired output:

group_fields = [
   "0": {
       "address": "street one",
       "number": "10000",
       "city": "nyc",
   },
   "1": {
       "address": "street two",
       "number": "600",
       "city": "washington",
   },
   "2": {
       "address": "street three",
       "number": "34000",
       "city": "paris",
   },
}

I have tried several things, I will write the last point i got to after alot of different unsuccessful methods:

var values = {};
var params = {};

$.each(theForm.serializeArray(), function(i, field) {
  values[field.name] = decodeURIComponent(field.value);
});

for (var key in values){
        if (values.hasOwnProperty(key)) {
            var matches = key.match(/[^[\]]+(?=])/g);
            if(matches != null  && matches.length > 0) {
                var index = matches[0];
                var theKey = matches[1];
                var theVal = values[key];
                var single = {
                          [theKey]: theVal,
                        }
                params[matches[0]].push(single);
            }
        }
    }

this obviously does not work.

Any help appreciated

4
  • Why don't you handle the data from form as JSON and then serialize it? A thought. Commented Oct 25, 2017 at 14:34
  • The block at the top does not resemble what serializeArray returns. Please update the question with the HTML of the form. Commented Oct 25, 2017 at 14:40
  • JSON.parse(JSON.stringify(obj)) please try this Commented Oct 25, 2017 at 14:42
  • @FerhatBAŞ: That won't help in the slightest. Commented Oct 25, 2017 at 14:45

1 Answer 1

1

What you've quoted doesn't look like the result of serializeArray, but working from what I believe your form looks like, it's not that hard. The main thing is that serializeArray returns an array of {name, value} objects, so we just have to isolate the two significant parts of the group_field names and then use those to build up our array with the objets in it. See comments:

var theForm = $("form");
// Create the array
var group_fields = [];
// Loop through the fields
theForm.serializeArray().forEach(function(entry) {
  // Get the index and prop name from the entry name
  var nameparts = /^group_field\[(.+)\]\[(.*)\]$/.exec(entry.name);
  // Get the group entry if we already have it
  var group = group_fields[nameparts[1]];
  if (!group) {
    // We don't, create and add it
    group = group_fields[nameparts[1]] = {};
  }
  // Set the property (address, street, etc.)
  group[nameparts[2]] = entry.value;
});
console.log(group_fields);
.as-console-wrapper {
  max-height: 100% !important;
}
<form>
    <input type="hidden" name="group_field[0][address]" value="street one">
    <input type="hidden" name="group_field[0][number]" value="10000">
    <input type="hidden" name="group_field[0][city]" value="nyc">
    <input type="hidden" name="group_field[1][address]" value="street two">
    <input type="hidden" name="group_field[1][number]" value="600">
    <input type="hidden" name="group_field[1][city]" value="washington">
    <input type="hidden" name="group_field[2][address]" value="street three">
    <input type="hidden" name="group_field[2][number]" value="34000">
    <input type="hidden" name="group_field[2][city]" value="paris">
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Or using ES2015+ (since you used computed property names in your original attempted solution):

const theForm = $("form");
// Create the array
const group_fields = [];
// Loop through the fields
theForm.serializeArray().forEach(entry => {
  // Get the index and prop name from the entry name
  const [ , index, prop] = /^group_field\[(.+)\]\[(.*)\]$/.exec(entry.name);
  // Get the group entry if we already have it
  var group = group_fields[index];
  if (!group) {
    // We don't, create and add it
    group = group_fields[index] = {};
  }
  // Set the property (address, street, etc.)
  group[prop] = entry.value;
});
console.log(group_fields);
.as-console-wrapper {
  max-height: 100% !important;
}
<form>
    <input type="hidden" name="group_field[0][address]" value="street one">
    <input type="hidden" name="group_field[0][number]" value="10000">
    <input type="hidden" name="group_field[0][city]" value="nyc">
    <input type="hidden" name="group_field[1][address]" value="street two">
    <input type="hidden" name="group_field[1][number]" value="600">
    <input type="hidden" name="group_field[1][city]" value="washington">
    <input type="hidden" name="group_field[2][address]" value="street three">
    <input type="hidden" name="group_field[2][number]" value="34000">
    <input type="hidden" name="group_field[2][city]" value="paris">
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much, you script worked flawlessly. I did not think about matching the brackets content during the serialization. since not all fields were named like the group fileds I just had to add a regExp test before the exec.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.