views:

305

answers:

5

I'm trying to dynamically create and remove items from a list, it works just fine... sort of, I can remove items, and create items, but once an item has been created, I cannot remove it again, but I can remove the items present when the page loads.

Here is my code

<div class="list">
    <div class="item">
        <input type="text" value="" />
        <a href="" class="removeitem">Remove this item</a>
    </div>
    <div class="item">
        <input type="text" value="" />
        <a href="" class="removeitem">Remove this item</a>
    </div>
    <a href="" class="additem">Add item to list</a>
</div>

<script type="text/javascript">
// Add item to list
$('.additem').click(function(){
    var template = $($(this).prev().get(0)).clone();
    template.insertBefore($(this));
    return false;
});

// Remove item from list
$('.removeitem').click(function(){
    $(this).prev().parent().remove();
    return false;
});
</script>

I can remove the 2 original items, but when I create new ones, they cannot be removed

+5  A: 

You need to use live events rather than the normal style you are using at the moment.

The click events are bound on load, at which point only the original items are present to be bound.

You would use live events like this:

<script type="text/javascript">
// Add item to list
$('.additem').click(function(){
    var template = $($(this).prev().get(0)).clone();
    template.insertBefore($(this));
    return false;
});

// Remove item from list
$('.removeitem').live("click", function(){
    $(this).prev().parent().remove();
    return false;
});
</script>

There is an overhead to using live events (it has to monitor all events in the DOM and check if they match I believe). Therefore, only use them when necessary.

Garry Shutler
nice, now it works as intended
kristian nissen
No problem :) .
Garry Shutler
+3  A: 

Change:

$('.removeitem').click(function(){
    $(this).prev().parent().remove();
    return false;
});

to:

$('.removeitem').live("click", function(){
    $(this).prev().parent().remove();
    return false;
});
cletus
A: 

Does this work?

$('.removeitem').live("click", function(){
$(this).parent('div.item').remove();
return false;
});

Other using .live() is a good idea, as you already know.

rubayeet
A: 

The other option to live events would be to attach the click event to your template:

$('.additem').click(function(){
   var template = $($(this).prev().get(0)).clone();
   template.insertBefore($(this));
   $(template).click( function() { 
      $(this).prev().parent().remove();
      return false;
   };
   return false;
});

That way you aren't dealing with the overheads of live events. If you do choose to do this you might want to pull the remove code into a function eg:

<script type="text/javascript">
  function removeitem() {
      $(this).prev().parent().remove();
      return false;
  }
  // Add item to list
  $('.additem').click(function(){
    var template = $($(this).prev().get(0)).clone();
    template.insertBefore($(this));
    $(template).click(removeitem);
    return false;
  });
  // Remove item from list
  $('.removeitem').click(removeitem);
</script>
Scimon
A: 

But in a case of .hover()

adardesign