Okay so I thought I had solved this problem. But the solution still evades me!
I have a ajax powered social chat application allowing comments and likes etc built with php, mysql and jquery. But when I post a comment the ajax returns a duplicate post with comment updated, so when you comment again you end up with mutiple duplicate posts. The Msql entries are fine (ie no duplication). All my other functions and updates work fine, so this is a severe pain in the bum!
Apologies for the amount of code but I am just trying to give you all the information – all thoughts and answers much appreciated!
Here is the start page HTML:
<html>
<div class="usermsg">
<?php
$sql = "SELECT post.post, post.posttime, post.pid_imageurl, post.likes, user.name, comments.comment, user.uid_imageurl, comments.comment_uid, post.pid
FROM post
INNER JOIN user
ON post.uid=user.uid
LEFT JOIN comments
ON comments.comment_pid=post.pid
ORDER BY pid DESC";
$result = mysql_query($sql);
while($row=mysql_fetch_assoc($result)){?>
<?php
$pid = $row['pid'];
$formattime = date("g:i:a",$row['posttime']);
//echo $row['pid']; for testing
echo '<p class="speechbubble">'.$row['post'].'<br><br><img class= "userprofileimage" src="'.$row['uid_imageurl'].'" alt="user profile image"/> Posted by '.$row['name'].' at '.$formattime. '</p>';
?>
<p class="likepara">this post has <? echo $row['likes']; ?> likes <a class="like" pid=<? echo $row['pid']; ?> href="#">like</a></p>
<div class="editable" pid="<? echo $row['pid'];?>" contentEditable="true">add comment...</div>
<?php
$sql_comments = "SELECT comments.comment, comments.comment_time, user.name, user.uid_imageurl FROM comments
INNER JOIN user
ON comments.comment_uid = user.uid
WHERE comment_pid = '$pid' ORDER BY cid DESC";
$result_comments = mysql_query($sql_comments);
$numrows_comments=mysql_num_rows($result_comments);//num of rows
if($numrows_comments==0) //no comments
{
echo '<p class="commentsheader">Comments</p><br>';
echo 'This post has no comments yet, be the first!';
echo '<br><br><br><hr><br><br>';
}else{
echo '<p class="commentsheader">Comments</p><br>';
while($row=mysql_fetch_assoc($result_comments)){
$formattime_comment = date("g:i:a",$row['comment_time']);
echo '<p class="comment">'.$row['comment'].'<br><img class="commentprofileimage" src="'.$row['uid_imageurl'].'" alt="user profile image"/>Posted by '.$row['name']. ' at ' .$formattime_comment. '</p>';
//echo '<img class="commentprofileimage" src="'.$row['uid_imageurl'].'" alt="user profile image"/>'
}//$sql_comments
echo '<hr><br><br>';
}//else end
}//$sql
?>
</div><!--user msg--
</html>
The jquery function:
$(".editable").live('click', function(){
$(this).empty();
$(this).mouseout(function() {
var comment = $(this).html();
var postid = $(this).attr("pid");
var commentuserid = $("#loggedin").attr("uid");
if(comment == ""){
return false;
}else{
var datastring = 'comment=' + comment + '&postid=' + postid + '&commentuserid=' + commentuserid;
//save with ajax clear box and then load back in
$.ajax({
type: "POST",
url: "uploadcomment.php",
data: datastring,
success: function(data){
$(".usermsg").html(data);
}
});
}
});
});
the update php (basically the same as the inital html page being updated).
<?php
include("connectdb.php");
include_once("secure.php");
//still repeating posts when mutiple comments added?
$commentpostid = $_POST['postid'];
$commentuserid = $_POST['commentuserid'];
$comment = protect($_POST['comment']);
$time =time();
$comment = strip_tags($comment);
$time =time();
$sql_insert_comments = "INSERT INTO comments
(comment_uid, comment_pid, comment, comment_time)
VALUES
($commentuserid,$commentpostid, '$comment', $time)";
$insert_comments_result = mysql_query($sql_insert_comments);
?>
<?
$sql = "SELECT post.post, post.posttime, post.pid_imageurl, post.likes, user.name, comments.comment, user.uid_imageurl, comments.comment_uid, post.pid
FROM post
INNER JOIN user
ON post.uid=user.uid
LEFT JOIN comments
ON comments.comment_pid=post.pid
ORDER BY pid DESC";
$result = mysql_query($sql);
while($row=mysql_fetch_assoc($result)){?>
<?
$pid = $row['pid'];
$formattime = date("g:i:a",$row['posttime']);
echo '<p class="speechbubble">'.$row['post'].'<br><br><img class= "userprofileimage" src="'.$row['uid_imageurl'].'" alt="user profile image"/> Posted by '.$row['name'].' at '.$formattime. '</p>';
//echo '<p class="speechbubble">'.$row['post'].'</p>';
//echo '<p class="msgholder" >Posted by '.$row['name'].' at '.$formattime. '<img class= "userprofileimage" src="'.$row['uid_imageurl'].'" alt="user profile image"/></p>';
?>
<p class="likepara">this post has <? echo $row['likes']; ?> likes <a class="like" pid=<? echo $row['pid']; ?> href="#">like</a></p>
<div class="editable" pid="<? echo $row['pid'];?>" contentEditable="true">
add comment...
</div>
<?
$sql_comments = "SELECT comments.comment, comments.comment_time, user.name, user.uid_imageurl FROM comments
INNER JOIN user
ON comments.comment_uid = user.uid
WHERE comment_pid = '$pid' ORDER BY cid DESC";
$result_comments = mysql_query($sql_comments);
$numrows_comments=mysql_num_rows($result_comments);//num of rows
if($numrows_comments==0) //no comments
{
echo '<p class="commentsheader">Comments</p><br>';
echo 'This post has no comments yet, be the first!';
echo '<br><br><br><hr><br><br>';
}else{
echo '<p class="commentsheader">Comments</p><br>';
while($row=mysql_fetch_assoc($result_comments)){
$formattime_comment = date("g:i:a",$row['comment_time']);
//echo '<p class="comment">'.$row['comment'].'</p>';
//echo '<p class="commentposter">posted by '.$row['name']. ' at ' .$formattime_comment. '<img class="commentprofileimage" src="'.$row['uid_imageurl'].'" alt="user profile image"/></p>';
echo '<p class="comment">'.$row['comment'].'<br><img class="commentprofileimage" src="'.$row['uid_imageurl'].'" alt="user profile image"/>Posted by '.$row['name']. ' at ' .$formattime_comment. '</p>';
}//$sql_comments
echo '<hr><br><br>';
}//else end
}//$sql
?>
</div>
</div>
I think you should get rid of the post rendering in the update.php.
EDIT: I’m a bit lost in your code. As I see you’re completely rendering the post again and replace the original one.
You should only update the comments, actually you don’t have to get any html response from the ajax request. A success/fail flag would be enough. You can put the new comment from the editable area to the bottom (or top) of the comment list on success.
Update php:
You’ll get “OK” or “FAIL” as response data. So you can make the right move in JS:
You should slightly modify your comment list for this. You should put the comments into a container div, sou you’ll be able to append the new commit to the list with jQuery like
$("#post_1 div.comment_container").append($("<div/>").text('comment text'))Also needed to store the posts in signed wrappers to be able to figure out which post’s comment list should be updated. So the structure of the page should look like this:
EDIT: And the real solution would be to remove the “left join comments” from the query where you’re getting the post. The join multiplies the rows.
For instance:
You’ve got A, B post, with comments A <= a,b and B <= c,d,e.
The result of the query would be 5 lines if I’m correct.