开发者

Find li on newly prepended item

My application adds new posts to an <ul> using .prepend() and then uses the .ajax() function to add it to the database like so:

$("#add input[type=submit]").click(function(){
    newPost = $("#add textarea").val();
    $.ajax({
        type    : "POST", 
        url     : "/add", 
        data    : { "post" : newPost },
        success: function(data) {               

           $('#posts ul').prepend('<li id="1234"><p>'+newPost+'<p><span class="delete">Delete</span></li>');
        }
});

This works as intended, but as you can see I have a Delete button for each post and I delete post using the following jquery:

$(".delete").click(function(){
    var thiscache = $(this),
    post_id = thiscache.closest("li").find("p").attr("id");

    $.ajax({
        type    : "POST", 
        url     : "/delete", 
        data    : { "post_id" : post_id },

        success : function(r){ 
            thiscache.parent().slideUp('slow'); 
            },

    });
});

Delete will work with post that have been added previously, but if you add a post using the ajax form, and click delete nothing fires. What could be the cause of this? Maybe the new post <li> isn't in the DOM?

I created a JSfiddle without the Ajax functions. http://jsfidd开发者_C百科le.net/bhhgf If you add a new post it will append it, but you can not delete it. Deleting the current posting works just fine.

EDIT:

I also use jeditable with a custom event, but .live() will not tigger new post.

$("p").editable('/edit/save', {event : 'edit_button'});

$(".edit").live('click', function(){       
    $(this).closest("li").find("p").trigger('edit_button');
});


You should use the jQuery live() function. This will apply the handler to all current and future elements which match the given selector. Thus, your new elements appended to the document will have the handler attached to click.

 $(".delete").live('click', function(){
   var thiscache = $(this),
   post_id = thiscache.closest("li").find("p").attr("id");

   $.ajax({
      type    : "POST", 
      url     : "/delete", 
      data    : { "post_id" : post_id },

      success : function(r) { 
          thiscache.parent().slideUp('slow'); 
      },
   });
 });

Alternatively, you can just add the handler when you add new elements, e.g.:

 var deleteHandler = function() {
   var thiscache = $(this),
   post_id = thiscache.closest("li").find("p").attr("id");

   $.ajax({
      type    : "POST", 
      url     : "/delete", 
      data    : { "post_id" : post_id },

      success : function(r) { 
          thiscache.parent().slideUp('slow'); 
      },
   });
 });

 $(".delete").click(deleteHandler);

 $("#add input[type=submit]").click(function(){
   newPost = $("#add textarea").val();
   $.ajax({
     type    : "POST", 
     url     : "/add", 
     data    : { "post" : newPost },
     success: function(data) {               

     el = $('#posts ul').prepend('<li id="1234"><p>'+newPost+'<p><span class="delete">Delete</span></li>');
     el.find('.delete').click(deleteHandler);
   });
 });

This approach will selectively add handlers as it comes up.


for the dynamically added elements to the DOM you need to rebind the event handler to them or use .live or .delegate

$(".delete").live('click',function(){

});

or

$("#posts ul").delegate(".delete","click",function(){

});

jquery live

jquery delegate

for the edit link in your first ajax callback again call the jeditable on the desired elements

    $("#add input[type=submit]").click(function(){
        newPost = $("#add textarea").val();
        $.ajax({
            type    : "POST", 
            url     : "/add", 
            data    : { "post" : newPost },
            success: function(data) {               

               $('#posts ul').prepend('<li id="1234"><p>'+newPost+'<p><span class="delete">Delete</span></li>');
             //call editable here on the desired elements
             $("p").editable('/edit/save', {event : 'edit_button'});
            }
    });


The click event is only bound for the elements that exist at that time. The elements that you add after that are not affected.

Use the delegate method to bind the event handler to a parent element, so that events from newly added elements are also handled:

$("'#posts ul").delegate(".delete", "click", function(){
  ...

Edit:

The editable plugin doesn't work with delegate as it's not just an event handler. You would have to apply that to the list element after adding it:

$("#" + id + " p").editable('/edit/save', {event : 'edit_button'});

where id contains the id of the list element that you prepended. ("1234" in your example, but your actual id should not be only digits...)


Well, you need to use the live event like the prior poster says, but there is also an error in your add method because you put the id attribute on the li element, but in your html, you have the id attribute on the p element.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜