Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.replaceWith() working only once

I am trying to implement a system of reputation of users in my site. So you can see the rep number after the name of the user every time he interacts (for example, every time he makes a comment). There is also a voting system which also alters the reputation of the user and I want the rep number to reflect that change. So I am calling a file through ajax which returns the new rep number for that user. The html/php file is something like this the first instance (if he makes a post):

echo '<div class="rep_user_id" id="rep_user_id_'.$posts_row['userid'].'"> '.$posts_row['user_rep'].'</div>';

and then (if he makes a comment):

echo '<div class="rep_user_id" id="rep_user_id_'.$com_row['userid'].'">'.$com_row['user_rep'].'</div>';

both give me this:

<div class="rep_user_id" id="rep_user_id_110">293</div>

Then the js:

function change_reps() {
var userid = $('.rep_user_id').attr('id').replace('rep_user_id_','');
$.ajax({
 url: "vote/get_reputation.php",
 data: "userid="+userid,
 success: function(server_response){
 $("body").ajaxComplete(function(event, request){
   var reputation = server_response;
   $('#rep_user_id_'+userid).replaceWith(''+reputation);
   $('#rep_user_id_'+userid).effect("highlight", {color:'red'}, 1000);
 });  } });  }

This function is called after success of another ajax (to update rep and votes). So, from this, what's working: once I click in any arrow up or down I can see the voting counter up or down but I only see the user rep change the very first instance only (post). Why is it changing only once and not throughout the whole document? Has anything to do that the comments section is called from another file (with an include)? FYI the effect works in all instances! Hope you can help. Thanks

EDIT: Since I have seen that I didn't explain myself very well I am adding a few more lines. The issue is that I can't modify multiple elements with the same id and class just one time (as opposed to change one element multiple times). So I have 293 many times throughout the page but the code posted is changing only one element! This is what triggers change_reps():

$("body").on("click", ".vote_com_up", function(){
   var com_id = $(this).attr('id').replace('vote_com_up_','');
   $.ajax({ 
    url: "vote/comment_vote.php",
    data: "com_action=2&com_id="+com_id,
    success: function(server_response){
    $(".vote_com_number").ajaxComplete(function(event, request){
     if(server_response == 'voted')
       { alert("Ya has votado en este post!");}
    else{
       var new_com_votes = server_response; 
       $("#vote_com_number_"+com_id).html(+new_com_votes);
    } }); } 
   }).done(function() {
    change_reps();
   });
   return false;
 }); 

I made a small jsfiddle to show what I want:

http://jsfiddle.net/CMgYb/1/

SOLUTION: Bryan Naegele was right: I needed classes instead of ids.

like image 812
Claudio Avatar asked Jan 10 '12 02:01

Claudio


3 Answers

You're accessing this element by id, then replacing it with something new. The only way this'll work a second time is if what you replace it with has the same id as it did before; I'm guessing it does not.

Are you sure you don't want to set the content of this element with the html function:

$('#rep_user_id_' + userid).html('' + reputation);

EDIT

Looking more closely at your PHP, it does look like you've coded this up to actually replace the entire div. Still though, I would recommend against coding your PHP to generate the correct element IDs. Consider trimming this PHP down so that you're just sending the content of the div. Then you can much more simply use html like above.

like image 54
Adam Rackis Avatar answered Oct 15 '22 10:10

Adam Rackis


According to the jQuery docs :

The .replaceWith() method removes content from the DOM and inserts new content in its place with a single call.

What this means is that when you do:

$('#rep_user_id_'+userid).replaceWith(''+reputation);

It changes:

<div class="rep_user_id" id="rep_user_id_110">293</div>
//to
293

So the second time it fires the ajax it cannot find the id rep_user_id. The easiest way to solve this would be to change the innerHTML with text() (note: you can also use hml() but in this case text() works better because there are no html tags).

$('#rep_user_id_'+userid).text(reputation);
like image 5
locrizak Avatar answered Oct 15 '22 11:10

locrizak


Probably has something to do with the fact that you are selecting an ID which will grab the first occurrence of that ID. You need to use classes.

like image 4
Bryan Naegele Avatar answered Oct 15 '22 10:10

Bryan Naegele