Robin Cox
Robin Cox

Reputation: 1490

Can't use variable inside of click event?

I have this code and it's javaScript and jQuery:

for (thisLooper = 1; thisLooper < 4; thisLooper++) {

    if ($("#writeComments"+thisLooper).length > 0) {
        $("#writeComments"+thisLooper+",#comments"+thisLooper+", #infoSpan"+thisLooper+"").hide();
        $("#toggleCommentForm"+thisLooper).click(function () {
            $("#writeComments+thisLooper").slideToggle();
        });
    }

}

What it does:

  1. Check if #writeComments1 exists
  2. If it exists, hide #writeComments1, #comments1 and #infoSpan1
  3. Then, if someone clicks on #toggleCommentForm1, slideToggle #writeComments1
  4. Do all this for #writeComments2 and it's friends
  5. Do all this for #writeComments3 and it's friends

With the code above nothing happens but if i replace:

$("#toggleCommentForm"+thisLooper).click(function () {
    $("#writeComments+thisLooper").slideToggle();
});

width this:

$("#toggleCommentForm"+thisLooper).click(function () {
    $("#writeComments1").slideToggle();
});

It all works but naturally only #writeComments1 slideToggles even if I click on #toggleCommentForm2 for instance.

My question is, why cant I use the variable "thisLooper" inside of the click events?

Upvotes: 0

Views: 229

Answers (2)

Ja͢ck
Ja͢ck

Reputation: 173572

The problem is that your loop variable is not properly closed over; instead of using a closure to fix that problem (which is what TrueBlueAussie explains in his answer), you could also consider binding the click handler to the element you wish to perform the slide on:

$("#toggleCommentForm"+thisLooper).click($.proxy(function () {
     // this is a jQuery object
     this.slideToggle();
}, $("#writeComments"+thisLooper));

Note, though, that anything more complex than just operating on a single jQuery object is better solved by a closure.

Upvotes: 0

iCollect.it Ltd
iCollect.it Ltd

Reputation: 93571

A closure in the loop will fix the immediate problem (and put the variable outside the string of course), so that the index value is retained in the click callback function.

for (index = 1; index < 4; index++) {
    (function(thisLooper){
        if ($("#writeComments"+thisLooper).length > 0) {
            $("#writeComments"+thisLooper+",#comments"+thisLooper+", #infoSpan"+thisLooper+"").hide();
            $("#toggleCommentForm"+thisLooper).click(function () {
                $("#writeComments"+thisLooper).slideToggle();
            });
        }
    })(index);

}

You should also create a local var rather than keep re-querying the selection but I need to see your full HTML first (as the code is a little odd)

Upvotes: 4

Related Questions