25

I have many inputs on a page. I want to create an associative array with each input's name and value using jQuery. I've tried:

<input class="activeInput" type="text" name="key1" value="red">
<input class="activeInput" type="text" name="key3" value="France">

inputValues = $('.activeInput').val();

EDIT - Thanks to the insightful comments, it seems maybe creating an object is a better way to go. Any suggestions on how to create an object instead?

Don P
  • 60,113
  • 114
  • 300
  • 432

6 Answers6

55

You can use .each() to iterate over the elements and add the names and values to a map (a plain object) like this:

var map = {};
$(".activeInput").each(function() {
    map[$(this).attr("name")] = $(this).val();
});

alert(map.key1); // "red"

See it in action.

Jon
  • 428,835
  • 81
  • 738
  • 806
  • Hey Jon, if I had for instance 10 inputs with the same class name, how can I capture those using the code above in a comma separated field. I just need a long string of their values, separated by a comma. – user1011713 Dec 19 '13 at 19:53
  • 5
    @user1011713: Use `.map` to get `$(this).val()` from each element, then `Array.join` to concatenate the values. – Jon Dec 19 '13 at 19:56
22

To create an array of values you can do this:

var $inputValues = $('.activeInput')
  .map((i, el) => el.val())
  .toArray();

To create an object with keys and values you can do this:

var data = $('.activeInput')
  .toArray()
  .reduce((accumulator, element) => {
    accumulator[element.name] = element.value;
    return accumulator;
  }, {});
Samuel Willems
  • 301
  • 3
  • 12
  • @AdamFriedman I would like to point out that this is not a syntactic error, and it was actually removed in an earlier edit. I do however prefer this style for readability. – Samuel Willems Oct 27 '17 at 09:43
  • 1
    Sorry, not syntax error per se, but your browser will throw an error if in your map() function you use "this" instead of "$(this)". – Adam Friedman Oct 30 '17 at 20:38
  • @AdamFriedman Oh that's funny, you're actually right. I was told last year that I should remove it because `this` would already be a jQuery object in this context... You did miss a spot though. – Samuel Willems Oct 31 '17 at 10:59
6

By running them through a loop you can create an object with string accessible values. Javascript doesn't have the concept of an associative array, but using bracket syntax you can access properties on an object in much the same way an associative array works in PHP.

var values = {};
$('.activeInput').each(function() {
    values[this.name] = this.value;
});

console.log(values['key1'], values['key3']);
// Note, this is the same as above.
console.log(values.key1, values.key3);

In your console you should see: red France

Here is a JsFiddle http://jsfiddle.net/rEtVt/ for it.

This is also referred to as a hashmap (concept) used for quick lookups.

earl3s
  • 2,393
  • 1
  • 23
  • 24
  • 1
    This creates an array with properties. Not an associative array. – Kevin B Oct 23 '12 at 18:58
  • 1
    @KevinB is correct. I updated to reflect that. Also not sure why the other answers use JQuery in the loop to get the name and value when you can directly access them as this.name, this.value. – earl3s Oct 23 '12 at 23:29
  • @earl3s: `this.name` is fine, but `.val()` works on ` – Jon Oct 24 '12 at 00:07
  • @Jon yes, but these are `` elements! – Kevin B Oct 24 '12 at 03:11
  • @KevinB: Sure, but since jQuery is in the picture anyway why not write more generic code? – Jon Oct 24 '12 at 07:53
  • @Jon it's a matter of opinion in most cases and isn't worth arguing over. Both get the same result, one just gets there faster. No one ever said it was wrong to do it one way or the other. Both are correct. – Kevin B Oct 24 '12 at 14:03
2
var inputValues = new Array();
$('input').each(function(){
    inputValues[$(this).attr('name')] = $(this).val();
});

That is assuming, of course, that you want the value of all inputs.


That being said, many reasons not to use and Array have been brought to my attention.

circusdei
  • 1,967
  • 12
  • 28
  • ... Why is `inputValues` an array if you are treating it like an object? After your each the array still has a length of 0. – Kevin B Oct 23 '12 at 18:21
  • because this ... "I want to create an associative array" – circusdei Oct 23 '12 at 18:22
  • Javascript doesn't have associative arrays, it has objects. `var inputValues = {}` – Kevin B Oct 23 '12 at 18:23
  • i suppose then ... habit. the advantage to using on obj being? – circusdei Oct 23 '12 at 18:24
  • The advantage being if you tried to loop through your array, you would iterate 0 times because it's length is still 0. – Kevin B Oct 23 '12 at 18:26
  • and why would one do that? if they're keyed by name, that makes no sense. – circusdei Oct 23 '12 at 18:26
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/18492/discussion-between-circusdei-and-kevin-b) – circusdei Oct 23 '12 at 18:27
  • 2
    I would compare using an array in this way to using this: `var inputValues = new String();`. Here's an example: http://jsfiddle.net/5BkbQ/ Notice how you get the exact same results using new String, new RegExp, and new Array. This because they are all objects. Why store object-like values in an array? It makes no sense in this case. Just because it works doesn't mean you should do it. – Kevin B Oct 23 '12 at 18:56
  • though, it was the question. +1 @KevinB for the finer points of JS objects. – circusdei Oct 23 '12 at 19:12
1

If you need to serialize form for ajax submission then you should have a look at serialize and serializeArray jQuery methods. Special cases may occur when you have many inputs with the same name attribute that have to make array on the server.

Otherwise, I would call jquery serializeArray on the form element and iterate over its results to convert it into object.

UPD: added example http://jsfiddle.net/zQNUW/

Andrey Kuzmin
  • 4,479
  • 2
  • 23
  • 28
-1

Try this:

var values = new Object() // creates a new instance of an object
$('.activeInput').each(function() {
    values[$(this).attr('name')] = $(this).val()
})

To check the object properties:

output = ""
for (property in values) {
  output += property + ': ' + values[property]+'; ';
}
alert(output)
  • `.val()` only gets the value of the first input. (and this answer just so happens to have the exact same code as in the question which isn't working. ) – Kevin B Oct 23 '12 at 18:18
  • 1
    Close, but `values.$(this).attr('name')` won't work. `values[$(this).attr('name')]` – Kevin B Oct 23 '12 at 18:57