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.
精彩评论