Randy Schouten
Randy Schouten

Reputation: 39

jQuery click event on wrong element created via loop

I'm trying to dynamically create portfolio parts for my website in jQuery so I can add stuff later to it with ease through the database. I've got everything working, except the listener always redirects to the last listener created, it seems. So no matter which header I click, it always opens the last option, not the one clicked. Here's the code I have:

var portfolio_array = <?php echo json_encode($GLOBALS["portfolio_array"]); ?>;
        for (var i = portfolio_length - 1; i >= 0; i--) {
            var project_name = portfolio_array[i]["name"];
            var project_tag = portfolio_array[i]["tag"];
            var project_description = portfolio_array[i]["description"];
            var project_year = portfolio_array[i]["year"];
            var project_image = portfolio_array[i]["image"];

            $("projects").append("<project class = " + project_tag + ">");
            $("."+project_tag).append("<br><project_header class = project-header>" + project_name + "</project_header>");
            $("."+project_tag).append("<br><project-content class = slideable></project-content>");
            $("."+project_tag).children(".slideable").append("<project_description class = project-desc>"+project_description+"</project_description>");
            $("."+project_tag).children(".slideable").append("<br><project_image class = project-image>"+project_image+"</project_image>");
            //<img src="pic_mountain.jpg" alt="Mountain View" style="width:304px;height:228px;">

            $("."+project_tag).children(".slideable").hide(1000);

            //alert("Added a click listener to tag " + project_tag);
            $("."+project_tag).children(".project-header").click(function(event){
                $("."+project_tag).children(".slideable").slideToggle(400);
                //alert("Clicked " + project_tag);
            });
        };

I've tried debugging it through alerts, but couldn't find anything wrong with it other than the click alert always pointing to the last project created. The alert before the creation of the event is giving me the correct project names.

Anyone see what's wrong with this? I'm still kind of new to this, so if there might be a really stupid mistake somewhere in there that I don't know of yet...

Upvotes: 0

Views: 723

Answers (2)

Iftah
Iftah

Reputation: 9572

This is a classic mistake, the problem is all the click handlers are using the same project_tag, and its value changes by the time the handler is activated.

You can fix this as @TahirAhmed suggested by using the this of the handler (which is the DOM element that was clicked). This is actually prefered since you can bind the same click handler to many elements at once and use the this to differentiate.

Alternatively you can use a closure which will bind the handler function to the current value (at the time the function is bound).

eg.

$("."+project_tag).children(".project-header").click(
     (function(tag) {
          return function(event){   // returns a function that is bound to the "tag" parameter value
            $("."+tag).children(".slideable").slideToggle(400);
          }
      })(project_tag)  // use current value of project_tag
  );

Upvotes: 1

Tahir Ahmed
Tahir Ahmed

Reputation: 5737

I think changing $("."+project_tag) inside your click handler to $(this).parent() should help.

Upvotes: 0

Related Questions