I'm trying to reorganize my code and make it more unobstrusive.
Mainly, there is a link for performing an action. If you click on the link, the action is performed via ajax (the ajax code is not on the code here) and the text is replaced by other text, offering the user the ability of undo the action. If the user click the Undo link, ajax restore the previous situation and the text offering the user perform the action it's shown again.
I've made a simpler version of my problem in a single html file (code below). There are two paragraphs. If you click on the link of the first paragraph, which uses inline onclick call, the code works as expected. But if you click on the link of the second paragraph, which uses jQuery onclick function, the Undo link doesn't work, and I can't figure out why.
Any help? Thanks a lot!
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title></title>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
$(function() {
$(".add2").click(function(){
var placeId = $(this).parents(".place").attr("id");
$("#" + placeId + " .add2").remove();
$("#" + placeId + " .actions").append("<span class=\"added\">Added!</span> <a class=\"undoadd2\" href=\"#\">Undo</a>");
return false;
})
$(".undoadd2").click(function(){
var placeId = $(this).parents(".place").attr("id");
$("#" + placeId + " .actions").find("span.added, a.add2").remove();
$("#" + placeId + " .actions").append("<a class='add2' onclick='copyPlace(\"" + placeId + "\"); return false;' href='#'>Add place</a>");
return false;
})
});
function addPlace(placeId){
$("#" + placeId + " .add").remove();
$("#" + placeId + " .actions").append("<span class=\"added\">Added!</span> <a class=\"undoadd\" href=\"#\" onclick=\"undoAddPlace('" + placeId + "'); return false;\">Undo</a>");
return false;
}
function undoAddPlace(placeId){
$("#" + placeId + " .actions").find("span.added, a.undoadd").remove();
$("#" + placeId + " .actions").append("<a class='add' onclick='addPlace(\"" + placeId + "\"); return false;' href='#'>Add place</a>");
return false;
}
</script>
</head>
<body id="home">
<div class="place" id="3435910">
<p class="actions"><a href="#" onclick="addPlace('3435910'); return false;" class="add">Add place</a></p>
</div>
<div class="place" id="3435912">
<p class="actions"><a href="#" class="add2">Add place</a></p>
</div>
</body>
</html>
Since you are dynamically adding new items to the DOM, you will have to register the
click
handler again on the new items. jQuery sets the handler when you call$('...').click(...)
.The click handler isn't being picked up when you append the element to the DOM. Try using jQuery to register the click handler by changing the line(s) that look like:
To
You might be able to do it more simply, but it looks like you could be adding more than one span to the paragraph so I went conservative. You could also probably chain off append, but I thought the reselect made the point clearer.
You can use
.live
for this.Update
Since jQuery 1.7, the
.on
method is preferred way to do this.Since jQuery 1.9 the
.live
method has been removed.Wow!! Thanks to all of you!
I've read about the live event and final working code is:
Previously I used remove() for delete the text that offers to perform the action. I've changed it for hide/show so I don't have to use live also in the first function.
Thanks again!
Just demonstrating the use of .end() for a more fluid solution: