Sindre Sørensen Sindre Sørensen - 7 months ago 16
SQL Question

Using jQuery function in a php while loop

I'm having trouble with a jQuery script for voting on posts. I have a "frontpage" with a list of posts from a mysql db. On each post there is a little votebox you can either vote up or down.

jQuery/ajax script:

<script type="text/javascript">
$(document).ready(function() {

$('.plus-button').click(function(){
var postid = <?php echo $postloopid; ?>;
$('.minus-button').removeClass('disliked');
$(this).toggleClass('liked');
alert(postid);

$.ajax({
type:"POST",
url:"php/votesystem.php",
dataType : 'html',
data:'act=like&postid='+postid,
success: function(data){
$('.plus-button').html(data);
}
});
});
$('.minus-button').click(function(){
var postid = $(this).attr('id');
$('.plus-button').removeClass('liked');
$(this).toggleClass('disliked');

$.ajax({
type:"POST",
url:"php/votesystem.php",
dataType : 'html',
data:'act=dislike&postid='+postid,
success: function(data){
$('.minus-button').html(data);
}
});
});
});
</script>


Votebox.php

<?php
// If postid is from frontpage use $postloopid as $postid
if(isset($postloopid)){
$postid = $postloopid;
}
$postid = htmlentities($postid, ENT_QUOTES);;

include("connect.php");


//For test purposes
echo $postid;



// If user logged in show votebox
if(isset($_SESSION['username'])){

$userid = $_SESSION['userid'];

$sql2 = mysqli_query($connect,"SELECT * FROM posts WHERE id='$postid' AND deleted=0");

if($sql2){

$voterow = mysqli_fetch_assoc($sql2);



$checkupvote = $voterow['upvoters'];

$checkdownvote = $voterow['downvoters'];

$checkupvote = explode(" ",$checkupvote);

$checkdownvote = explode(" ",$checkdownvote);

if($checkupvote = array_search($userid,$checkupvote) == true){

echo '<div class="plus-button liked" name="like">+ ' . $voterow['totalupvotes'] . '</div>';

echo '<div class="minus-button" name="dislike">- ' . $voterow['totaldownvotes'] . '</div>';


}

elseif($checkdownvote = array_search($userid,$checkdownvote) == true){

echo '<div class="plus-button" name="like">+ ' . $voterow['totalupvotes'] . '</div>';

echo '<div class="minus-button disliked" name="dislike">- ' . $voterow['totaldownvotes'] . '</div>';


}

else{

echo '<div class="plus-button" name="like">+ ' . $voterow['totalupvotes'] . '</div>';

echo '<div class="minus-button" name="dislike">- ' . $voterow['totaldownvotes'] . '</div>';

}

}
else {
echo 'No result <br />';

}

}
else {
echo 'Cant find user';
}









?>


Frontpage:

<?php
$sql1 = mysqli_query($connect,"SELECT * FROM posts WHERE totalupvotes < $trendmin AND deleted=0 ORDER BY added DESC LIMIT 0,10");
if($sql1){
while($row = mysqli_fetch_array($sql1)){
$postloopid = $row['id'];


?>
<div id="postlist">

<div style="width:400px; font-size:18px; font-weight:bold;">
<a target="_blank" href="post.php?id=<?php echo $row['id']; ?>"><?php echo $row['title']; ?></a>
</div><br />
<article class="slide"><?php echo nl2br($row['post']); ?></article>





<br />
<?php include("php/votebox.php"); ?>
<br />
by <a style="font-size:18px;" href="profile.php?id=<?php echo $row['submittedby']; ?>"><?php echo $row['submitteduser']; ?></a>
at <span style="font-size:12px;"><?php echo $row['added']; ?></span><span style="float:right; margin-right: 10px;"><a target="_blank" href="post.php?id=<?php echo $row['id']; ?>#commentfield"><?php echo $row['totalcomments']; ?> comments</a></span>



</div>


<?php
}
}
?>


The problem now is that when I click the votebox buttons it turns out I only get the postid from the first loaded post from the while loop. Another problem I have is that my total up- and downvotes changes in all the posts on the list, not the specific post.

Any ideas?

Answer

The Javascript code isn't in the loop, it can't reference postloopid. Or if it is, you're binding all buttons of the class every time through the loop, and clicking on them will run all the handlers, incrementing all the posts.

You should put the post ID as a data field in the button, and then access that from the Javascript:

echo '<div class="plus-button liked" data-postid="'+$postid+'" name="like">+ ' . $voterow['totalupvotes'] . '</div>';

echo '<div class="minus-button" data-postid="'+$postid+'" name="dislike">- ' . $voterow['totaldownvotes'] . '</div>';

Then your Javascript can do:

$('.plus-button').click(function(){
    var postid = $(this).data('postid');
    $(this).siblings('.minus-button').removeClass('disliked');    
    $(this).toggleClass('liked');
    alert(postid);

    $.ajax({
        type:"POST",
        url:"php/votesystem.php",
        dataType : 'html',
        data:'act=like&postid='+postid,
        context: this,
        success: function(data){
            $(this).html(data);
        }
    });
});

I made the following changes to the JS:

  1. Use $(this).data('postid') to get postid.
  2. Only remove the disliked class from the sibling minus button, not all minus buttons on the page.
  3. Put the returned HTML just in this element, not in all plus buttons. I pass this in the context: parameter, so that the success function can refer to it.
Comments