Pez Cuckow
Pez Cuckow

Reputation: 14412

jQuery variable scope within each

I am trying to build an array containing all the values of every form element. The alert works just find, but on console.log data is empty, am I failing to understand how scoping in javascript works?

  var data = new Array();
  $("#page2 input").each(function(index) {
      alert($(this).attr('id'));
      data[$(this).attr('id')] = $(this).val();
  });

Many thanks for your time,

Upvotes: 5

Views: 5302

Answers (5)

alex
alex

Reputation: 490233

One thing to know is that an Array in JavaScript can only ever have positive integer indexes (which are really treated as strings).

When you assign a string to the key, you are assigning properties to an Object.

You probably want something like this...

var data = {};
$("#page2 input").each(function() {
   data[this.id] = this.value;
});

jsFiddle.

If you wanted just the id attributes.

var data = $("#page2 input").map(function() { 
               return this.id;
           }).get();

jsFiddle.

Upvotes: 8

RobG
RobG

Reputation: 147383

Your question was:

...all the values of every form element...

but your selector was only for input elements in one particular form. Presuming that you actually wanted the values of all the controls in a form, then the following POJS may suit:

function getFormValues(formId) {
  var data = {};
  var form = document.getElementById(formId);

  if (form) {
    var control, controls = form.elements;

    if (controls) {
      var i = controls.length;

      while (i--) {
        control = controls[i];
        data[control.id] = control.value;
      }
    }
  } 
  return data;
}

Presuming that every control has an ID, which is not a requirement. If some controls don't have an id, you might want to use the name property instead, so:

        data[control.id || control.name] = control.value;

In some cases, your controls may not have an id or a name (e.g. controls that are needed for the form but whose values are not to be submitted, such as submit and reset buttons) so:

        var idOrName = control.id || control.name;
        if (idOrName) {
          data[idOrName] = control.value;
        }

You may also need to deal with controls having the same name, since the value of whichever one is accessed last will replace the value of previous same-named controls.

Upvotes: 1

user113716
user113716

Reputation: 322492

The scope is correct. If the console is not displaying entires in the Array, then I'm guessing that your ID attributes are not numeric.

Doesn't meant that the data isn't there. Just means that the console chooses to only display the numeric indices.

Consider the following input into Chrome's console:

var arr = new Array();
arr['test'] = 'test';

arr;  // []
arr.test;  // 'test'

While it is valid JavaScript to give a non numeric property to an Array, in most cases it is the wrong approach.

Upvotes: 1

mVChr
mVChr

Reputation: 50187

If you're using the input id as a key what you're creating is an Object, not an Array.

var data = new Object();

Upvotes: 0

SLaks
SLaks

Reputation: 887433

You're trying to make an object (new Object() or { }), not an array.

Upvotes: 1

Related Questions