marxin
marxin

Reputation: 3922

jQuery - passing variable to event by data

I would like to create some objects dynamically and bind events to them (not important what events).

I'm passing a number to the event in order to distinguish those items. There is my code:

$('#add_btn').click(function() {
    var cont = $('#buttons');

    for(var i=0; i<5; i++) {
        var new_btn = $('<input>').attr('type', 'button').val(i);

        new_btn.click(function() {
            alert(i);
        });

        cont.append(new_btn);
    }
});

When I click on any from newly created buttons, displayed number is 5.

I think that i variable is passing by reference, but the question is: how to avoid passing variable by reference? More, even if I crate new variable before binding event (so the reference should point to another object, for example new_val = i.toString()), value is still same for all buttons (then its 4, understandable).

I know that I can attach new_btn.data() and read it in event, but I'm not sure if it won't be an overhead.

Link to jsfiddle: http://jsfiddle.net/Jner6/5/.

Upvotes: 1

Views: 70

Answers (3)

Roko C. Buljan
Roko C. Buljan

Reputation: 206638

Don't make functions within a loop.

DEMO

var cont = $('#buttons');

$('#add_btn').click(function() {

    for(var i=0; i<5; i++) {
      $('<input>', {type:'button', value:i}).appendTo( cont );
    } 

});

cont.on('click', ':button', function() {
    alert( this.value );
});

Upvotes: 0

Arun P Johny
Arun P Johny

Reputation: 388436

Since you are using a closure scoped variable in a loop, inside the loop you need to create a private closure.

$('#add_btn').click(function () {
    var cont = $('#buttons');

    for (var i = 0; i < 5; i++) {
        (function (i) {
            var new_btn = $('<input>').attr('type', 'button').val(i);

            new_btn.click(function () {
                alert(i);
            });

            cont.append(new_btn);
        })(i)
    }
});

Upvotes: 2

antyrat
antyrat

Reputation: 27765

Seems like you run into closures issue, try this:

(function( i ) {
    new_btn.click(function() {
        alert(i);
    });
})( i );

This will create immediate invoked function that will closure your variable i so you can use it in future. For now you just overriding i variable in your for-loop so you will have always same value that will equal last for-loop iteration.

Upvotes: 0

Related Questions