Still. Learning Still. Learning - 6 months ago 18
Javascript Question

Every other class element that is dynamically created is working as intended - Jquery

My problem is this:


  • I click on #addition to create new .folder
    -.folderImg, .folderName and .folderMenu are appended to this .folder element in this same function



Then I have another function where I :

-click on .folderImg element to toggle .folderMenu

Now this works for the first .folder that I create, but as I create a second .folder, the first one that was created stops toggling it's .folderMenu but the second one now works.

As I create the third .folder element, now first and third work as intended but second .folder's toggle doesn't work.

Here is my Jquery:

$(document).ready(function() {
$("#accordion").accordion();
$("#wrap").on('click', "#addition", function(event) {
var folders = $(".folder").length;
var count = (1 + folders);
var folderName = prompt("Please enter folder name");
var addFolder = ("<div class=folder> </div>");
var addFolderImg = '<img class=folderImg src="folder-icon.png">';
var addFolderName = ("<h3 class=foldName>" + folderName + "</h3>");
var addFolderMenu = ("<div class=folderMenu></div>");
if (folders == 0) {
$("#addition").after(addFolder);
} else {
$(".folder").last().after(addFolder);
}
$(".folder").last().append(addFolderImg);
$(".folder").last().append(addFolderName);
$(".folder").last().append(addFolderMenu);
$(".folder").on("click", ".folderImg", function(event) {
$(this).siblings(".folderMenu").toggle();
});
});
});


I'm in trouble and a little bit frustrated, please, what is wrong with my code? I already did get answer about how things aren't bound correctly, but I just couldn't apply this knowledge to fix my code on my own. Such a noob!

Answer

You are assigning multiple event handlers to the same items again and again. Thereby you actually toggle an item multiple times. If that number of times is even, it is like nothing had happened.

You should not assign a click handler for .folderImg every time a folder is added, because it will apply for all .folderImg, also those for which you already assigned a click hander in the past. Instead you should define it only once and for all .folderImg elements, present and future.

To do that, move this code outside of the #wrap click handler, and apply it to document:

$(document).on("click", ".folderImg", function(event) {
  $(this).siblings(".folderMenu").toggle();
});

So code becomes:

$(document).ready(function() {
  $("#accordion").accordion();
  $("#wrap").on('click', "#addition", function(event) {
    var folders = $(".folder").length;
    var count = (1 + folders);
    var folderName = prompt("Please enter folder name");
    var addFolder = ("<div class=folder> </div>");
    var addFolderImg = '<img class=folderImg src="folder-icon.png">';
    var addFolderName = ("<h3 class=foldName>" + folderName + "</h3>");
    var addFolderMenu = ("<div class=folderMenu></div>");
    if (folders == 0) {
      $("#addition").after(addFolder);
    } else {
      $(".folder").last().after(addFolder);
    }
    $(".folder").last().append(addFolderImg);
    $(".folder").last().append(addFolderName);
    $(".folder").last().append(addFolderMenu);
  });
  // moved outside of above handler, and handling events as they bubble up to `document`:
  $(document).on("click", ".folderImg", function(event) {
     $(this).siblings(".folderMenu").toggle();
  });
});