Mattallurgy Mattallurgy -4 years ago 52
HTML Question

Use HTML input 'name' attribute to yield an Object

In ExpressJS using body-parser, there exists the functionality to parse as a JavaScript object (or JSON, I'm not entirely sure) a set of input elements which have the same name attribute with defined keys.

HTML (e.g.):

<input type="text" class="name" name="name[foo]" placeholder="input1"/>
<input type="text" class="name" name="name[bar]" placeholder="input2"/>


JavaScript (e.g.):

var obj = req.body.name;


The object
obj
is understood by JavaScript to be
{ "foo" : input1, "bar" : input2 }


I am trying to get similar functionality using standard jQuery to handle several related form inputs. What I have tried so far—to no avail—is the following:

$(".name")
yields an Object containing the literal HTML (not helpful for grabbing the key-value pairs).

$(".name").map(function () {return $(this).val();}).get();
yields an array of values, but no keys.

$("input[name='name']")
and
$("input[name='name[]']")
yield nothing.

I have also tried the following to convert the inputs to an array, but it still does not serve the purpose of pulling the information from the form as a JavaScript object/JSON:

$.fn.inputsToArray = function () {
var values= [];
$.each(this, function (i, field) {
values.push(field.value);
});
return values;
};


Is there a way to accomplish what I am trying to do without NodeJS / body-parser?




Solution:

Thanks to gaetanoM's excellent solution (accepted below), I was able to create a generic jQuery function that can be called on any jQuery object (obviously, it'll only work properly if the element is in the
<input ... name="example[key]" ... />
format, but I digress).

The function is called thusly:

var output = $(":input[name^=example]").inputsToObject();


The function is defined as the following:

$.fn.inputsToObject = function () {
var values = {};
values = $(this).get().reduce(function (acc, ele) {
var key = ele.name.match(/\[(.*)\]$/)[1];
acc[key] = $(ele).val();
return acc;
}, {})
return values;
}

Answer Source

For the first you need $(':input[name^=name]') in order to select all input fields having the name attribute starting with name. With .get() you transform the jQuery result into an array on which you can apply .reduce():

var result = $(':input[name^=name]').get().reduce(function(acc, ele) {
    var key = ele.name.match(/\[(.*)\]$/)[1];  // get the key
    acc[key] = ele.getAttribute('placeholder'); // add to retval
    return acc;
}, {});
console.log(result);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<input type="text" class="name" name="name[foo]" placeholder="input1"/>
<input type="text" class="name" name="name[bar]" placeholder="input2"/>

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download