0

Ok, my coding is a little weak, but I'm learning. I have a code simular to

$.post("test.php", {"data":"data"}, function(grabbed){
    $.each(grab, function(i, item){
        var place = document.getElementById("div");
        var para = createElement("p");
        para.innerHTML = item.name;
        para.onclick = function(){
            document.getElementById(?para?).innerHTML = ?item.price?;
        }
        place.appendChild(para);
    });
}, "json");

My question is how would I use say, item.price in the onclick function. I haven't actually tried yet, but I'm pretty sure that referencing the data retrieved from the request won't work in the dynamically loaded onclick function.

My function works a little differently but the basic principle is on here. Any advise would be appreciated, or perhaps someone can point me in the right direction.

I was thinking of assigning ids to the div or para and using those in the function somehow. I also thought of using cookies to store the data I want, but I can't figure it out. Is there something else I need to know or try.

1
  • I forgot to add "json", at the end of the post request. grab is an array of objects, so item is a array member with named properties. Sorry Commented Aug 25, 2015 at 16:49

2 Answers 2

1

Your question concerns the concept of closures in JavaScript.

Closures are functions that refer to independent (free) variables. In other words, the function defined in the closure 'remembers' the environment in which it was created.

Consider the following code snippet:

var foo = (function(){
    var remembered = "yea!";

    return function(){
        console.log("Do you remember? - " + remembered);
    };
})();

foo(); // prints: Do you remember? - yea!

That said, looking at your code:

...
// the function assigned to `onclick` should remember
// the variable `item` in the current context.
para.onclick = function(){
    document.getElementById(?para?).innerHTML = ?item.price?;
}
...

That works since you're using JQuery's $.each() for iteration. And here is a demonstration: http://jsfiddle.net/55gjy3fj/

However if you were doing the iteration with a plain for-loop, you would have to wrap the handler inside another closure:

var getHandler = function(para, item){
    return function(){
        document.getElementById(the_id_here).innerHTML = item.price;
    };
};
para.onclick = getHandler(para, item);
...

This fiddle demonstrates the point: http://jsfiddle.net/63gh1gof/

Here's a fiddle that summarises both cases:

Sign up to request clarification or add additional context in comments.

3 Comments

yeah but don't these dynamically loaded functions forget the data involved.
Ok, so what your saying is that as long as I assign values to everything i need inside of the onclick function that it will remember the value I assign.
the function always remembers its environment. Since item is inside the context where the function was created. it will remember item, and by that you will be able to reference the exact item as it was available when the function was created. To clearly demonstrate this, take a look at this fiddle: jsfiddle.net/ato01crh
1

Since you're already using jQuery, this could be the perfect opportunity to get introduced to .data(). Use it to save an arbitrary object to the dom element, and then reference it later in the onclick-listener.

var para = $('<p/>').html(item.name).data('item', item);
para.click(function() {
    $(this).data('item') // item!!!
});
$('#div').append(para);

Actually, here you could write a more efficient method using jQuery's delegated event handlers.

Just attach the event handler to the parent element:

$('#div').on('click', 'p', function() {
    $(this).data('item') // item!!!
});

4 Comments

I'll get my head round it
I don't think this will work as there are multiple items in the array that is retrieved. So I can't set a global variable and if I define it in the function, it's still not going to be accessable through the dynamically loaded onclick function.
There's no global variable, you're attaching the object to the dom node!
actually sorry were you saying that .data actually remembers the item.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.