user2144363
user2144363

Reputation: 47

Can you manipulate HTML generated in jQuery?

To put it simply I'm loading in a div with jQuery when a button is clicked. However within this div is another button. The button that is loaded in, I can't seem to manipulate/select it with jQuery. Here is an example to best demonstrate what I'm attempting:

http://codepen.io/projodesign/pen/zlvaB

Here's the jQuery:-

$(document).ready(function(){
  $('.button').click(function(){
    $(this).after('<div class="added-element">IM THE ADDED DIV</div><div class="remove-added-element">REMOVE DIV</div>')
  });

  $('.remove-added-element').click(function(){
    $('.added-element').hide();
  });
});

My jQuery knowledge is pretty basic, so any pointers to go about this in a better way would be great. Obviously I could put this in the HTML, but I want there to be an infinite amount of divs available to be added. Hope this all made sense.

Upvotes: 0

Views: 119

Answers (2)

Ryan Mitchell
Ryan Mitchell

Reputation: 744

Problem of order of execution. You are adding the event handler to .remove-added-element before it exists.

If you move that handler up into your .button click handler, then your problems will go away.

$('.button').click(function(){
    $(this).after('<div class="added-element">IM THE ADDED DIV</div><div class="remove-added-element">REMOVE DIV</div>');
    $('.remove-added-element').click(function(){
        $('.added-element').hide();
    });
});

EDIT

nzifnab's solution is better. You can alter the code I gave above to circumvent the problems he raised, but why would you do it when his way is so simple?

DOUBLE EDIT

Since you say below that you want to follow this solution, you do need to follow certain steps to avoid the problems nzifnab raised. I think changing and adapting his suggestion like this would do what you want:

$('.button').click(function(){
    $(this).after('<div class="added-element">IM THE ADDED DIV</div><div class="remove-added-element">REMOVE DIV</div>');
    $(this).find('.remove-added-element').click(function(){
        $(this).closest('.added-element').hide();
    });
});

Upvotes: 1

nzifnab
nzifnab

Reputation: 16110

jsfiddle: http://jsfiddle.net/zW7zA/

You need to use event delegation. Try the on method:

$(document).ready(function(){
  $('.button').on('click', function(){
    $(this).after('<div class="added-element">IM THE ADDED DIV<div class="remove-added-element">REMOVE DIV</div></div>')
  });

  $(document).on('click', '.remove-added-element', function(){
    $(this).closest('.added-element').hide();
  });
});

The reason this works and yours doesn't is because, when you bind directly to .remove-added-element that element doesn't exist on the page yet when the script runs, so no events get bound. With this new form of delegation it is binding the event to document which does exist, and then when things are clicked it is checking if they match the given selector.

I had to modify a couple of things that aren't going to work for your current script.

Your 'remove' code where it just was $('.added-element').hide() was going to remove all new elements, even if you'd clicked the link several times. This new code will only hide the one section where the remove button was clicked (closest looks at the nearest parent that matches the selector).

I'm not a big fan of binding an event inside of your original event handler, because then if you click the button multiple times you are going to be binding many events - and with the given code some of those events will "double up" (You're going to end up binding 10 events to the first new element if you clicked the button 10 times, 9 events to the second, 8 events to the third, etc) unless you modify it.

This way is easier, it will only bind the one event.

Upvotes: 1

Related Questions