Reputation: 81
how do i change id of a element every time it is clicked with jquery? I have this code which works fine on the first click, but then when clicked again, it still calls the old id.
$("#like<? echo $msgID;?>").click(function(){
$.post("like.php?status_id=<? echo $msgID;?>", $(this).serialize());
setTimeout(function() {
$("#likeDiv<? echo $msgID;?>").load('like-count.php?status_id=<? echo $msgID;?>');
$("#like<? echo $msgID;?>").attr("id","unlike<? echo $msgID;?>").text("Unlike");
},500);
});
$("#unlike<? echo $msgID;?>").click(function(){
$.post("unlike.php?status_id=<? echo $msgID;?>", $(this).serialize());
setTimeout(function() {
$("#likeDiv<? echo $msgID;?>").load('like-count.php?status_id=<? echo $msgID;?>');
$("#unlike<? echo $msgID;?>").attr("id","like<? echo $msgID;?>").text("Like");
},500);
});
Upvotes: 2
Views: 273
Reputation: 61
Have set up a jsfiddle here: http://jsfiddle.net/ewYbm/2/ with another example.
Assuming the following HTML:
<div class="article">
<a class="like btn" data-status-id="1" data-likes="0">Like</a>
</div>
<div class="article" >
<a class="like btn" data-status-id="2" data-likes="1">Like</a>
</div>
You could do something like this:
$('.article .btn')
// Initialize the count of likes from the data-likes attribute
.each(function(el, i){
$(this).append(' <span class="count">' + $(this).data('likes') + '</span>')
})
// Bind the click handler to toggle like/unlike state
.click(function(evt){
var btn = $(this),
statusID = btn.data('status-id'),
unliked = btn.hasClass('like'),
count = parseInt(btn.data('likes')),
postURL;
if(unliked){
postURL = 'like.php';
count = count + 1;
} else {
postURL = 'unlike.php';
count = count - 1;
}
// Save the like count as a data attr
btn.data('likes', count);
// Send an XHR request to like/unlike status (commented out here)
// $.post(postURL,
// { statusID: statusID },
// function(data){
btn
.toggleClass('like', !unliked)
.toggleClass('unlike', unliked)
.text(!unliked ? 'Like' : 'Unlike')
// update the count
.append(' <span class="count">' + count + '</span>')
// }
// );
});
Upvotes: 0
Reputation: 2284
The problem ocurrs because when you call jquery to bind the #unlike, at that time it doesnt exists (to that works you should use delegate/live events, Try this:
$(document).on('click','#like<? echo $msgID;?>',function(){
$.post("like.php?status_id=<? echo $msgID;?>", $(this).serialize());
var oLike = this;
setTimeout(function() {
$("#likeDiv<? echo $msgID;?>").load('like-count.php?status_id=<? echo $msgID;?>');
oLike.prop("id","unlike<? echo $msgID;?>")
oLike.text("Unlike");
},500);
});
$(document).on('click','#unlike<? echo $msgID;?>',function(){
$.post("unlike.php?status_id=<? echo $msgID;?>", $(this).serialize());
var oLike = this;
setTimeout(function() {
$("#likeDiv<? echo $msgID;?>").load('like-count.php?status_id=<? echo $msgID;?>');
oLike.prop("id","like<? echo $msgID;?>")
oLike.text("Like");
},500);
});
PS: once you didnt showed your HTML, in my example you could change the "document" for a more restrict context where you update your "IDs".
Try looking in this article at JQuery Events delegates section.
Upvotes: 0
Reputation: 150030
The problem isn't that the id isn't changing, it is that you've bound your click handlers already. In a general sense, if you do this:
$("#someId").click(...
it binds a click handler to the element that has that id at that moment, and the click handler continues to be bound to that element even if you change the id later.
In your case you start out trying to bind a click handler to two elements, one with id starting #like
and the other with id starting #unlike
, but only one such element exists initially and so only one handler is bound.
You need to either change to use delegated event handlers, which are bound to a parent element (or the document) and on click test whether the clicked item matches some selector, or combine the two click handlers into one handler that tests the current state of the element:
$("#like<? echo $msgID;?>").click(function () {
var isLike = $(this).text() === "Like",
url = isLike ? "like.php" : "unlike.php";
$.post(url + "?status_id=<? echo $msgID;?>", $(this).serialize());
setTimeout(function () {
$("#likeDiv<? echo $msgID;?>").load('like-count.php?status_id=<? echo $msgID;?>');
$("#like<? echo $msgID;?>").text(isLike ? "Unlike" : "Like");
}, 500);
});
You didn't show your html, but I'm assuming that the #like...
element is not inside the #likeDiv...
element (because if it was it would be reloaded by your .load()
and that would remove the click handler).
I can add some code to show how to do the two delegated handlers instead, but to my way of thinking it makes more sense to combine the handlers as already shown, because really it is the same element that is being clicked and just its displayed text needs to change.
(Also, as an aside, why are you using that setTimeout()
? Wouldn't it make sense to put that in a callback function as the third argument to $.post()
?)
Upvotes: 1