views:

466

answers:

3

Hi all,

I'm trying to create a Stackoverflow like voting system, and I've run into a slight problem.

I have the following HTML that has jQuery onClick events wired to it:

<div id="c_<%=Html.Encode(Model.C.cID) %>" class="votes">
    <img src="../../Content/gfx/Up.png" class="up" alt="" />
    <span class="votecount"><%= Html.Encode(Model.C.VoteCount)%></span>
    <img src="../../Content/gfx/Down.png" class="down" alt="" />
</div>

The jQuery onClick looks like this:

 $(".up").click(function() {
    var id = $(this).parent().attr("id").split("_");       
    if (id[0] == "c") {
        //C Vote
        //id[1] contains the id number.
        $.post("/Vote/CUp", { id: id[1] }, function(data) {
            $(this).parent().children(".votecount").html(data.voteCount);                
        },
            "json"
        );
    } else {
        //R Vote
        $.post("/Vote/RUp", { id: id[1] }, function(data) {
            $(this).parent().children(".votecount").html(data.voteCount);
        },
            "json"
        );
    };                        
});

My problem lies in trying to update the vote count. I just can't work out how to update the votecount span with the values returned in the JSON object.

The JSON object is returning data, I've verified this using alert(data)

Help is much appreciated.

A: 

Try:

$(this).next(".votecount").html(data.voteCount);
karim79
Tried that.. Both .next(".votecount") and .prev(".votecount") respectively.. Alas no joy.. But thank you for the response none the less.
Jeremy
@Jeremy - have you tried `$(this).siblings('.votecount').html(data.voteCount);` ?
karim79
@karim79. Tried that today. No luck. It appears that $(this) doesn't work within a $.post function. But then again, I don't really understand jQuery so I'm probably wrong.
Jeremy
A: 

You could always try something like:

<div id="c_<%=Html.Encode(Model.C.cID) %>" class="votes">  
    <img src="../../Content/gfx/Up.png" class="up" alt="" />  
    <span class="votecount" id="vc_<%=Html.Encode(Model.C.cID) %>">
        <%= Html.Encode(Model.C.VoteCount)%>
    </span>  
    <img src="../../Content/gfx/Down.png" class="down" alt="" />  
</div>

with the following jQuery:

 $(".up").click(function() {
    var id = $(this).parent().attr("id").split("_");       
    if (id[0] == "c") {
        //C Vote
        //id[1] contains the id number.
        $.post("/Vote/CUp", { id: id[1] }, function(data) {
            $("#vc_"+data.id).html(data.voteCount);                
        },
            "json"
        );
    } else {
        //R Vote
        $.post("/Vote/RUp", { id: id[1] }, function(data) {
            $("#vc_"+data.id).html(data.voteCount);
        },
            "json"
        );
    };                        
});

And just make sure you pass the id back that you passed into the $.post() function in your data json object.

Note the adding of a unique identifier to the vote count div that we can call to.

mynameiscoffey
+2  A: 

In the scope of the $.post() callback, this will give you a reference to the XMLHttpRequest object, not the element that raised the earlier click event.

You can assign this to a variable in the scope of the click handler and it will still be available in $.post()'s callback. Something like this:

$(".up").click(function() {
  var id = $(this).parent().attr("id").split("_");

  // Due to the awesome magic of closures, this will be available
  //  in the callback.  "el" is a weak name for the variable, you
  //  should rename it.
  var el = this;

  if (id[0] == "c") {
    //C Vote
    //id[1] contains the id number.
    $.post("/Vote/CUp", { id: id[1] }, function(data) {
        // siblings() is an easier way to select that.
        $(el).siblings(".votecount").html(data.voteCount);                
    }, "json");
  } else {
    //R Vote
    $.post("/Vote/RUp", { id: id[1] }, function(data) {
        $(el).siblings(".votecount").html(data.voteCount);
    }, "json");
  };                        
});
Dave Ward