To put things in context, I’m loading a list of items via Ajax, creating a div with main info for each one and want to display details on page when clicking on it. So I have that code in my onSuccess :
items = transport.responseText.evalJSON(); // my list of objects that contains all the details I'll need for that page
for (var itemID in items)
{
newDiv = ... // Creating my div with main infos
$('myDiv').appendChild(newDiv);
// More code to make everything look pretty and that works fine
Event.observe(newDiv, 'click', function() { loadItem(itemID); });
}
loadItem is my function that will display all the item details. And my problem is that itemID isn’t replace by its value when creating the observe event, so it always returns the same ID for all items.
Any idea how I can fix that ? I checked bind on prototype doc, that seemed to be made for those cases, but probably didn’t get it, since it wouldn’t work for me.
For a minimal-impact fix, replace your
Event.observeline with this:Explanation:
In your original code, the event handler functions you’re creating close over (have an enduring reference to) the
itemIDvariable, and so will use the value of that variable at of when the event handler is called, not as of when you assign it to the event. That value will be the last value thatitemIDhas in the loop — for all of the handler functions. More about closures here.With the minimal-impact revised code, we use Prototype’s
curryfunction, which will create a function for you that, when called, will call the underlying function with the arguments you gavecurry. (The name is from mathematics; Haskell Curry came up with the technique, though there are arguments he wasn’t the first to do so.) We could do the same thing ourselves:…but because Prototype has a general-purpose function for it, we don’t have to.
Off-topic: Is
itemsan array? If not, ignore this off-topic comment. If so, don’t usefor..into loop through it, or at least, not unless you take some precautions the code above doesn’t to do it properly. Details here, butfor..inis not for looping through the indexes of an array; it’s for looping through the properties of an object. Array objects may well have properties other than array indexes (and in fact, if you’re using Prototype, they do.)