0

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...

0

2 Answers 2

1

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
  );
Sign up to request clarification or add additional context in comments.

1 Comment

The "this" solution didn't work, assuming I put it in the correct place. If Tahir said the correct place, then it doesn't work. Your own awnser, however, worked perfectly! Thank you!
0

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

3 Comments

Apologize. I suppose it is difficult for me to imagine what the problem could be without the relevant markup and css.
I don't know why someone rated you down (not me), but I imagine it is because of a lack of explanation, especially since the asker is a new programmer. Your answer may help him work around the problem but not understand why there was a problem in the first place.
That could be the reason. I'll definitely try and improve on that. Thanks @Iftah. We are all learning.

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.