1

I created a simple voting system (+ and -) on Ajax for users comments. One page have 50 posted comments and you can vote for each "plus" or "minus". This data sent through the PHP script to the database. However, if a user votes, the PHP script is called 50 times - it is visible in Chrome developer tool. There are errors - more value than expected. Here is my code (two DIV buttons and the script).

Tell me please how to change the code to the script (up_vote.php or down_vote.php) is called only once.

<script type="text/javascript" src="raitings/jquery.js"></script>
<script type="text/javascript">$(function() {$(".vote").click(function() {

var id = $(this).attr("id");
var name = $(this).attr("name");
var dataString = 'id='+ id ;
var parent = $(this);

if(name=='down')
{
$(this).fadeIn(200).html('<img src="raitings/dot.gif" align="absmiddle">');
$.ajax({type: "POST", url: "raitings/down_vote.php", data: dataString, dataType : "html", cache: false, success: function(html)
   { parent.html(html);}
 });
}
else
{
$(this).fadeIn(200).html('<img src="raitings/dot.gif" align="absmiddle">');
$.ajax({type: "POST", url: "raitings/up_vote.php", data: dataString, dataType : "html", cache: false, success: function(html)
   { parent.html(html);
  }  });
}
return false;
    });
});
</script>

//php code below;
echo "<div class=\"box1\"><div class=\"up\"><a href=\"#\" class=\"vote\" title=\"+ 1\" alt=\"+ 1\" id=".$row["id"]." name=\"up\">".$up."</a></div>"
."<div class=\"down\"><a href=\"#\" class=\"vote\" title=\"- 1\" alt=\"- 1\"  id=".$row["id"]." name=\"down\">".$down."</a></div></div>\n";
6
  • Can't reproduce: jsfiddle.net/jxUKN is there any other js code you are omitting? Commented Oct 25, 2012 at 18:22
  • Or are you loading each individual comment via ajax? Commented Oct 25, 2012 at 18:26
  • I load all the comments via PHP. id the same two buttons, but different for all comments Commented Oct 25, 2012 at 18:29
  • 1
    Try replacing $(".vote").click(function() with $(".vote").unbind("click").click(function() Commented Oct 25, 2012 at 18:31
  • AAAA!!!! This work!!! Thank you very much. I spent a few days solving this problem. You're a genius! Maybe create an answer that I can set your help right answer? Commented Oct 25, 2012 at 18:38

4 Answers 4

1

Using jQuery, it's important to know that events are stackable, even if the event is exactly the same. For example:

$(".vote").click(function() { alert("hi"); });
$(".vote").click(function() { alert("hi"); });
$(".vote").click(function() { alert("hi"); });

If we ran these three lines verbatim, we'll have 3 different events attached. That is, we would get 3 alerts one after the other by clicking in an element with the vote class.

In addition, oftentimes it happens that pages being loaded through ajax carry the same <script></script> block of the parent page, and when this is the case, the code is inadvertently being processed again and again with every ajax call.

While I was not able to pinpoint exactly how is this happening by the code you provided, it seems this is the most likely scenario: your click handler event is being loaded several times, and as a result one click triggers several ajax calls.

The quick and dirty solution when this presents as I mentioned in the comments is replacing:

$(".vote").click(function()

By:

$(".vote").unbind("click").click(function()

Which thanks to the unbind function forces it to discard previously attached events every time a new one is attached, thus preventing it from having more than one event attached no matter how many times the code is processed.

While this will work, the better solution is, of course, to locate where is the js code being loaded multiple times and make sure it is loaded just once.

Sign up to request clarification or add additional context in comments.

Comments

0

$(".vote").each(function () { $(this).click( clickHandler .... etc should solve your problem.

1 Comment

Are you loading this script for each comment?? If that is the case you should not load the javascript each time but only once at the end of the page.
0

I don't fully understand how your version works but I would do it similar to this:

<a href="JavaScript:vote_up(200);"> + </a>
<a href="JavaScript:vote_down(200);"> - </a>

Where 200 would be the unique id of the comment. Then have a vote_up() and vote_down() function defined in a JavaScript and add your ajax requests there. That way it should not call the script more than once when +/- button is clicked.

Comments

0

You can disabled button before send you ajax request.

// Sample:

$(function() {
    $(".vote").click(function() {

    var id = $(this).attr("id");
    var name = $(this).attr("name");
    var dataString = 'id='+ id ;
    var parent = $(this);

    parent.fadeIn(200).html('<img src="raitings/dot.gif" align="absmiddle">');

    if(name=='down')
    {   
        $.ajax({
        type: "POST", 
        url: "raitings/down_vote.php", 
        data: dataString, 
        dataType : "html", 
        cache: false, 
        beforeSend: function() {
            parent.attr("disabled", true);
        },
        success: function(html) {
            parent.html(html);
        }
        });
    } else {    
        $.ajax({
        type: "POST", 
        url: "raitings/up_vote.php", 
        data: dataString, 
        dataType : "html", 
        cache: false, 
        beforeSend: function() {
            parent.attr("disabled", true);
        },
        success: function(html) {
            parent.html(html);
        }
        });
    }

    return false;
    });
});

1 Comment

But the user should be able to vote for the other comments after the vote a one.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.