Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert mutlidimensional inputs to JavaScript object

I've been trying to solve this one for several days now and it's driving me nuts. I have some data that needs to be submitted by Ajax. It is dynamic, so I don't know how many fields it has. On top of that the names of the fields are multidimensional and also dynamic. For example one might have inputs with the name data[name] and data[title] whilst another larger one might have data[images][0][src], data[images][0][alt], data[images][0][description], data[images][1][src], data[images][1][alt], data[images][1][description] with an unknown number of elements to the array. My problem is that I need to get an object I can submit via Ajax whilst maintaining the structure of the data.

I've tried serialising the data, but that just comes up with a string of name = value. I've tried serialise array as well, but that just gives me an array of [name, value]. I've managed to generate the object manually using a regex to split it up, but I can't find a way to merge the resultant objects together. The latest version of my code is:

$('.modal-content').find('input[name^="data"]').each(function () {
    var found = $(this).attr('name').match(re).reverse();
    var temp = $(this).val();
    $.each(found, function ()
    {
        str = this.substr(1, this.length - 2);
        var t = {};
        t[str] = temp;
        temp = t;
    });
    data = $.each({}, data, temp);
});

Unfortunately it doesn't merge them, it overwrites what is in data with what is in temp. If data has data.images[0].src = "mysrc" and temp has data.images[0].alt = "myalt" then I just end up with data.images[0].alt = "myalt" and src is no longer there.

There has to be a simple way to do this, hell at this point I'd even take a complicated way to do this. Can someone please help me with this?

like image 538
Styphon Avatar asked Sep 04 '26 06:09

Styphon


1 Answers

Although there is already an accepted answer. Here are my 5 cents:

IMHO working with regex should be avoided when possible. So my suggestion would be to change the HTML a bit, adding some classes to the div that contain the image and change the name attribute of the inputs:

<li class="col-xs-12 col-sm-6 col-md-4 col-lg-3 gallery-image ui-sortable-handle">
        <div class="my-image">
            <img src="http://localhost:8000/img/example.jpg">
            <input type="hidden" name="src" value="img/example.jpg">
            <div class="form-group">
                <label for="title-0">Title:</label>
                <input type="text" name="title" class="form-control" id="title-0" value="Default Example Image 1" placeholder="Title">
            </div>
            <div class="form-group">
                <label for="description-0">Description:</label>
                <input type="text" name="description" class="form-control" id="description-0" value="A default example image." placeholder="Description">
            </div>
            <div class="form-group">
                <label for="alt-0">Alt tag (SEO):</label>
                <input type="text" name="alt" class="form-control" id="alt-0" value="fluid gallery example image" placeholder="Alt tag">
            </div>
            <div class="form-group">
                <label for="order-0">Order:</label>
                <input type="number" name="order" class="form-control image-order" id="order-0" value="0">
            </div>
            <button type="button" class="btn btn-danger remove-gallery-image-btn">× Delete</button>
        </div>
    </li>
    <li class="col-xs-12 col-sm-6 col-md-4 col-lg-3 gallery-image ui-sortable-handle">
        <div class="my-image">
            <img src="http://localhost:8000/img/example.jpg">
            <input type="hidden" name="src" value="img/example.jpg">
            <div class="form-group">
                <label for="title-1">Title:</label>
                <input type="text" name="title" class="form-control" id="title-1" value="Default Example Image 2" placeholder="Title">
            </div>
            <div class="form-group">
                <label for="description-1">Description:</label>
                <input type="text" name="description" class="form-control" id="description-1" value="A default example image." placeholder="Description">
            </div>
            <div class="form-group">
                <label for="alt-1">Alt tag (SEO):</label>
                <input type="text" name="alt" class="form-control" id="alt-1" value="fluid gallery example image" placeholder="Alt tag">
            </div>
            <div class="form-group">
                <label for="order-1">Order:</label>
                <input type="number" name="order" class="form-control image-order" id="order-1" value="1">
            </div>
            <button type="button" class="btn btn-danger remove-gallery-image-btn">× Delete</button>
        </div>
    </li>

Then build the object matching this class:

var obj = {
  data: {
    images: []
  }
}

var groups = $('.my-image');

groups.each(function(idx, el) {
  var child = {}
  $(el).find('input').each(function(jdx, info){
    var $info = $(info);
    child[$info.attr('name')] = $info.val();
  });

  obj.data.images.push(child);
});

We would have the same result, but it might be less error prone. Here is a plunker.

like image 134
matheusr Avatar answered Sep 06 '26 18:09

matheusr