1

Say I have object:

function obj()
{
  this.prop1;
  this.prop2;
  this.prop3;
}

and an array of obj's

  objects = [new obj(),new obj(),new obj()];

I want to easily iterate through each using jquery where the class name is equivalent to the property of the object.

var itemsIWantToBind = ["prop1","prop2","prop3"];
for(j=0;j<itemsIWantToBind.length;j++)
{
    $("."+itemsIWantToBind[j]).unbind().blur(function(){
        var id = $(this).siblings(".objID").html();
        if(id >= 0)
        {
            objects[id].itemsIWantToBind[j] = $(this).text());
        }
    });

}

My issue is I want to be able use a variable variable to iterate through the items for this

objects[id].itemsIWantToBind[j] = $(this).text());  
            ^^^^^^^^^^^^^^^^^

the indicated part does not correctly bind the value of the array item as it is trying to bind the property name of it instead.

In php it would be the same as:

foreach($itemsIwantToBind as $item)
{
   $objects[$id]->$item = "Something";
}

Is there a simple way to do this in JavaScript?

Marc B
  • 356,200
  • 43
  • 426
  • 500
Jeff
  • 480
  • 1
  • 5
  • 17
  • Yes, use square brackets: `something[propertyName]` – georg Feb 23 '15 at 19:02
  • `objects[id][itemsIWantToBind[j]]`? – Marc B Feb 23 '15 at 19:04
  • See also http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example – georg Feb 23 '15 at 19:11
  • @MarcB: That would get him close, but `j` will be invalid by the time the event occurs. – T.J. Crowder Feb 23 '15 at 19:13
  • Note: The answer is correctly answered by @T.J.Crowder but the issue was due to itemsIwantToBind and j being out of scope for the blur method, so the code above won't work even with the proper notation :) – Jeff Feb 23 '15 at 19:22

1 Answers1

3

Use brackets notation:

var o = new obj();
o.prop1 = "I'm the value";
var s = "prop1";
console.log(o[s]); // "I'm the value"

I think this is how this relates to your code:

["prop1","prop2","prop3"].forEach(function(prop) {  // **A**
    $("."+prop).unbind().blur(function(){
        var id = $(this).siblings(".objID").html();
        if(id >= 0)
        {
            objects[id][prop] = $(this).text());    // **B**
        }
    });
});

(B) is the place where we actually use the name, but note the (A) change to so that we get a value that won't change. You can't just use

// Wrong unless we also change the loop
objects[id][itemsIWantToBind[j]] = $(this).text());

because j will be be beyond the end of the array when the event occurs.

forEach is an ES5 feature that can readily be shimmed for old browsers. Or you can use jQuery's $.each instead:

$.each(["prop1","prop2","prop3"], function(i, prop) {  // **A**
    $("."+prop).unbind().blur(function(){
        var id = $(this).siblings(".objID").html();
        if(id >= 0)
        {
            objects[id][prop] = $(this).text());       // **B**
        }
    });
});
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    Ah, I had tried that, but my issue was with variable scope(this is correct, I'll accept when I can). My array, itemsIWantToBind , was out of scope for the .blur() method I called. Thanks for the help! – Jeff Feb 23 '15 at 19:06
  • @Jeff: That's strange, it isn't in the question -- but then, I'm guessing the question is a fairly condensed version of the actual code. :-) – T.J. Crowder Feb 23 '15 at 19:08
  • 1
    @t-j-crowder Yeah, I realized this after. I can't call itemsIWantToBind OR j from within the blur method but you correctly answered the question I posted; just my error was else where and realized it after I asked this! Thanks again for your help :) – Jeff Feb 23 '15 at 19:10
  • @Jeff: LOL -- "new" in 2009, when the 5th edition spec was finalized. :-) All sorts of nifty additions to arrays -- `map`, `some`, `reduce`... – T.J. Crowder Feb 23 '15 at 19:34