PHP Ajax Comments
Continuing with a rather ‘Ajax’ theme after the last few tutorials on here i thought I’d go the full way and show you how to create a 140 character php and ajax comments tool. We’re using jQuery to perform the ajax request and create the user experience. You can download all the files needed to get this working at the bottom of this post, it includes the MySQL file to create the database table.
The Code
- The document ready function adds and removes the text ‘Leave your message here…’ from textarea. when you click in the box.
- Then we have the input .click function. The first section of the code checks that the user has added a comment and if not displays an error prompt telling them to add a message
- We then perform the Ajax bit by posting the data to submitComment.php, we show the thank you message and slide in the users comment at the top.
var loaderImage = new Image();
loaderImage.src = 'images/loader.gif';
$(document).ready(function(){
var messageArea = $('textarea#message');
messageArea.val('Leave your message here...').css('color', '#666666');
messageArea.click(function (){
$(this).val('').css('color', '#000000');
$(this).unbind('click').click(function(){
return false;
});
});
$('input#submit-comment').click(function(){
// Store vars
var message = messageArea.hide().val();
// Validation
if(message.length < 1 || message == "Leave your message here..."){
messageArea.fadeOut('slow', function(){
var errorMessage = 'Oops! You haven’t typed anything. Please have another go...';
var error = $('<div id="too-short"><span class="error">' + errorMessage + '</span></div>').insertBefore($(this));
error.hide().fadeIn('slow', function(){
setTimeout(function(){
error.hide();
messageArea.fadeIn('slow');
}, 2000);
});
});
return false;
}
var dataString = 'message='+ message;
// Show loader
var loader = $('<div id="loader"><img class="load-gif" src="' + loaderImage.src + '" /></div>').insertBefore($(this));
//alert (dataString);
$.ajax({
type: "POST",
url: "submitComment.php",
data: dataString,
success: function(data) {
$('#loader').find('img.load-gif').remove();
$('#loader').append('<span class="success">Thanks for your comment!</span>');
$('#loader').hide().fadeIn('slow');
$('span.limit').remove();
$('#comments').prepend(data);
$('#comments div.comment-unapproved:nth-child(1)').hide().slideDown('slow');
$('input#submit-comment').unbind('click').click(function(){
return false;
});
}
});
return false;
});
messageArea.keyup(function(){
var limit = 140;
var currentLength = $(this).val().length;
var charsLeft = limit - currentLength;
$('span.limit').html(charsLeft);
if(currentLength >= limit){
$(this).val($(this).val().substring(0, limit));
$('span.limit').html('0');
var textarea = document.getElementById('message');
textarea.scrollTop = textarea.scrollHeight + 9999;
}
});
});
The index.php main code
<div id="container">
<div id="comments">
<?php
include("dbConnector.php");
$connector = new DbConnector();
function date_diff($d1, $d2){
$d1 = (is_string($d1) ? strtotime($d1) : $d1);
$d2 = (is_string($d2) ? strtotime($d2) : $d2);
$diff_secs = abs($d1 - $d2);
$base_year = min(date("Y", $d1), date("Y", $d2));
$diff = mktime(0, 0, $diff_secs, 1, 1, $base_year);
$diffArray = array(
"years" => date("Y", $diff) - $base_year,
"months_total" => (date("Y", $diff) - $base_year) * 12 + date("n", $diff) - 1,
"months" => date("n", $diff) - 1,
"days_total" => floor($diff_secs / (3600 * 24)),
"days" => date("j", $diff) - 1,
"hours_total" => floor($diff_secs / 3600),
"hours" => date("G", $diff),
"minutes_total" => floor($diff_secs / 60),
"minutes" => (int) date("i", $diff),
"seconds_total" => $diff_secs,
"seconds" => (int) date("s", $diff)
);
if($diffArray['days'] > 0){
if($diffArray['days'] == 1){
$days = '1 day';
}else{
$days = $diffArray['days'] . ' days';
}
return $days . ' and ' . $diffArray['hours'] . ' hours ago';
}else if($diffArray['hours'] > 0){
if($diffArray['hours'] == 1){
$hours = '1 hour';
}else{
$hours = $diffArray['hours'] . ' hours';
}
return $hours . ' and ' . $diffArray['minutes'] . ' minutes ago';
}else if($diffArray['minutes'] > 0){
if($diffArray['minutes'] == 1){
$minutes = '1 minute';
}else{
$minutes = $diffArray['minutes'] . ' minutes';
}
return $minutes . ' and ' . $diffArray['seconds'] . ' seconds ago';
}else{
return 'Less than a minute ago';
}
}
// Work out the Date plus 8 hours
// get the current timestamp into an array
$timestamp = time();
$date_time_array = getdate($timestamp);
$hours = $date_time_array['hours'];
$minutes = $date_time_array['minutes'];
$seconds = $date_time_array['seconds'];
$month = $date_time_array['mon'];
$day = $date_time_array['mday'];
$year = $date_time_array['year'];
// use mktime to recreate the unix timestamp
// adding 19 hours to $hours
$timestamp = mktime($hours + 8,$minutes,$seconds,$month,$day,$year);
$theDate = strftime('%Y-%m-%d %H:%M:%S',$timestamp);
$query = "SELECT * FROM shoutbox ORDER BY ID DESC LIMIT 30";
$result = $connector->query($query);
while($row = $connector->fetchArray($result)) {
$date = strtotime($row['date']);
$dayMonth = date('d M', $date);
$year = date('y', $date);
$message = $row['content'];
$datediff = date_diff($theDate, $date);
?>
<div class="comment">
<div class="date">
<span class="day-month"><?php echo $dayMonth; ?></span>
<span class="year"><?php echo $year; ?></span>
</div>
<span class="content"><?php echo stripslashes($message);?> <span class="time"><?php echo $datediff; ?></span></span>
<div class="clear"></div>
</div>
<?php
}
?>
</div>
<div id="submission">
<form name="comment-submission">
<textarea id="message" name="message"></textarea>
<span class="limit">140</span>
<input type="submit" id="submit-comment" value=" " />
</form>
<div class="clear"></div>
</div>
</div>



Nice effect
Damn Ashley you are so cool
– I really love this commentbox and the effect!
Would you say that this could do as a commentsystem for each post on a blog? No huh?
@Brian thanks! you sure could use it on a blog, you might need to play around with it abit to get it working with wordpress but i can’t see it being that much of a problem.
Your jQuery selectors are inefficient. If you select like this $(‘div#loader’), it has to scan through every single div in the document to find one that should have a unique ID anyway. It’s much faster to simply use $(‘#loader’) which should be the same thing, since, as we said, IDs are unique. Same with your classes, when possible, $(‘.class’) is faster than $(‘img.class’). In fact, efficient selectors should never start with a tag (unless you’re manipulating the tag) if possible.
@Adam thanks for the feedback! I didn’t realise that, im still finding my way with jQuery
@Ashley – awesome!
Could it be possible to load people’s Gravatar then?
PHP Ajax Comments…
Continuing with a rather ‘Ajax' theme after the last few tutorials on here i thought I'd go the full way and show you how to create a 140 character php and ajax comments tool.
…
@Ashley, no problem. Sorry if that came off a little abrupt: just trying to give some constructive feedback to those learning along with you.
@adam not at all, that’s what my blog’s for, to get feedback and generate discussion!
@Brian if you were to get the users email address and save it in the variable $email from the database then you could easily show their gravatar by using the following line.
<img src="http://www.gravatar.com/avatar/.jpg”/>
Hi,
I have a problem. This is my error message:
Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in /home/user/public_html/shoutbox/dbConnector.php on line 34
Could you help me please?
Thamk you.
@alik have you changed the SQL queries in any way? a possible reason for this not working could be an error with one of the database queries. I suggest checking through each query to make sure you have the write table names in place and column names. Let me know how you get on or if you have any further problems Ash
Very nice script ! I finally find a shoutbox easy to edit
But, it’s possible that you add an auto-refresh each x seconds of the comments ?
I’ll try however even if I don’t know Jquery too much.
Thanks Ashley for all !
nice script!
I do have a question though, does this store/read data per uri?
I’m gonna grab it n play around a bit TY
“You can download all the files needed to get this working at the bottom of this post, it includes the MySQL file to create the database table”
I think that is missing from the *.zip file. If it is, please update the zip file with the mysql file. If not, well, mock me then for not being able to find it.
never mind, you need in table shoutbox
id, type int (although i don’t think it does anything
date, varchar (20 or so)
content, varchar (600 or however long you want the posting to be)
Hi could you help please, iv got an error saying….
Fatal error: Cannot redeclare date_diff() in C:\wamp\www\boxajax\index.php on line 139
i cant see the problem, but i am a new to php so it might be simple.
@luke can you save the file as index.phps and post a link to it so i can see your source code. sounds like your trying to run the date_diff() function twice, but without seeing your code i can’t be sure.
Ash
Im Working on local host so cant put on the server yet, i got the zip file downloaded from you, i changed the query so it connected to the database correctly in phpmyadmin, for some reason i cant read the .DS_Store FILE & _notes file, would that be my problem?
@luke ok the .DS_Store file is there just because i compressed it on a mac, you don’t need that file so can delete it.
Without seeing your code it’s a bit tricky to diagnose the problem but you could try commenting out, you can comment the code by putting two forward slashes as show below. The line is right at the end of the while loop block of code.
// $datediff = date_diff($theDate, $date);
If you comment that out you wont get any dates showing up but at least it might help find the problem.
Ok thanx Ashley ill give it a go, thanx for replying aswell most ppl dont on most sites,
@luke no problem let me know if you still have any problems
Hi me again im still having trouble, but i canciled out the “whole block” date_diff function all the way down to line 141, because just that one line was the same outcome, and doing that.. it works and uploads the date to the database and posts the message but i get an error…
Warning: date_diff() expects parameter 1 to be DateTime, string given in C:\wamp\www\boxajax\index.php on line 170 i think im getting close lol
@luke try commenting out these lines aswell as the function because otherwise your calling a function that doesn’t exist because it’s commented out.
//$date = strtotime($row['date']);
//$dayMonth = date(‘d M’, $date);
//$year = date(‘y’, $date);
$message = $row['content'];
//$datediff = date_diff($theDate, $date);
i finally done it, i think lol, if im right there was a tiny mistake with the code,
(1) I Changed the function name from “date_diff” to “datediff”
(2) I Changed the last line….
$datediff = date_diff($theDate, $date);
TO
$datediff = datediff($theDate, $date);
I might be wrong but it seems to work. basically just removed 2 lines.
@luke strange…. the underscore in the function name shouldn’t make a difference, however if it works for you
thats cool! good luck let me know if you have any other probs / questions.
U alright ash, i got that all sorted it works good now thanx, i ran into another problem and have been googling for ages but stil cant find anything or figure it out, so i thought with your back ground, was hoping maybe you could help me.
its hard to explain but ill give it a go lol.
I have an upload page that sends infomation to a table in the database,
id, title, src, tn_src, discription etc.
all this information is then displayed on a page called image.php.
Once clicked on a small image in my index page it goes to image.php page showing the bigger image with all the information i uploaded around it. image.php has its own id so it can display different infomation depending on the image.
for example:
http://localhost/fotostor/image.php?id=163
i have added the comment box to the image.php page this means no matter what small image you click on in index.php page the comments page is always there on the image.php page so the user can post a comment about the bigger image,
what i would like to do is insert the users comment to the database table next to my upload information, id, title, src, tn_src, discription [comments here]
what i was thinking was somet like this
$theQuery = “UPDATE images
SET content = ‘” . $theMessage . “‘, date = ‘” . $theDate . “‘
WHERE id = ‘” . pageid . “‘”;
but im not shaw how to grab the page id if u have any advise id really appreciate it,
Hey Luke,
No problem, this is the way i would do it.
i would have 2 tables.
1: photo_comments
2: photos
you stated above that your using the table id to pull in the big image. you can use that id to store in the photo_comments table so that each photo pulls only the comments that were left on that photo. if your still with me, all you need to do is do a mysql query on your comments table and say:
you can pick up any variable passed through a URL in PHP by writing:
$variableName = $_GET['id'];
‘id’ references the data passed in the url, this could be anything.
Then when a user posts a comment all you need to do is pick that photo id from the URL up again and set it in the comments table.
if you need to pass the variable through AJAX then you can pick up the GET variable when the page loads and set it in javascript like this:
Let me know if that helps
Thanx im gonna give it a go, thats exactly what im looking for, cheers, Cant belive you understood what i was saying, lol.
@luke no worries, let me know how you get on
Looks pretty nice to me. I’ll try to implement it in my next blog comments system. Nice work
Hi me again iv bin trying for ages i got this in my submit_coments.php
$id = mysql_escape_string($_GET['id']);
$q = “INSERT INTO shoutbox (id, date, content) VALUES (‘” . $id . “‘, ‘” . $theDate . “‘, ‘” . $theMessage . “‘)”;
$result = $mysqli->query($q) or die (‘error could not insert into shout box’);
and this in image.php (where the comment box is)
$id = mysql_escape_string($_GET['id']);
$q = “SELECT * FROM shoutbox WHERE id = ‘$id’ ORDER BY date DESC LIMIT 5″;
my table is named shoutbox which has 3 fields id, date and content, for some reason i jus cant ($_GET[id]); to work and display the page id in my shoutbox table. i think once that is done ill be ok.
@luke. Right i can see you problem. You need to add another field in the database table shoutbox, in the example below i’ve called it ‘image_id’. So take a look at the modified query below.
you can see that i’ve renamed the $_GET variable to $imageid because you need to store the id that refers to the specific image that the users is commenting on, So for example if i leave a comment on a photo of some flowers we don’t want that same comment to appear on a picture of the beach, so we need something unique in both tables that will link the data together with, so in this case we’re using the ‘id’ from the image table.
IMPORTANT NOTE: the reason you can’t get your current code to work is because the table ’shoutbox’ has an id which is set to auto increment meaning that every record that is added to the database will have a unique id, we call this field the PRIMARY KEY. You were trying to add the photo id in the shoutbox id and it was trying to increment it.
$imageid = mysql_escape_string($_GET['id']);
$q = “INSERT INTO shoutbox (id, date, content, image_id) VALUES (‘” . $id . “‘, ‘” . $theDate . “‘, ‘” . $theMessage . “‘, ‘” . $imageid . “‘)”;
$result = $mysqli->query($q) or die (‘error could not insert into shout box’);
you’ll need to modify your select query also. So the only thing tyou really need to do is ad another field to your shoutbox table.
make it: an INT value and you should be on your way
Hope that helps.
i havent set the id in my shout box table to auto increment, but every time write a message the id displays 0,
maybe, do i need a primary key in a table?
@luke You’ll need to make the id auto increment and set it as primary key, then you need to add the extra field that i explained above.
every thing works fine now i still cant get the id and i know why because image.php holds the id for that page and submitComment.php holds the date and message information, i need to some how get the value of $_GET['id'] from image.php and insert it into the database from submitComment.php. i think i need to do somet like what you said about ajax. im not to sure but ill figure it out.
Hi there,
I downloaded the zip file, but unable to find the sql file…
Please post the table structure here.
Regards,
TechZia
@techzia I’ve re-uploaded the shoutbox.zip file so you can download it again with the sql file as a .txt file.
Excellent Tutorial!
Nice Stuff
hi bro, nice tutorials and really helpful to me, thanks for this
Oye que pagina tan util te felicito…
How to edit comments?
@caio you’ll need to write a completely different script in order to edit the comments – it wouldn’t be too difficult though.
Is the download still good? I download the .zip file and when i extract it i get a shoutbox file with all kinds of weird characters inside…..
@Sebas yeah the download should be working fine. can you email me what you downloaded to ashley at dotdashcreate dot com so i can check it out.
Hi again Ashley.
Just wanted to say that I have made my own comment script, more simple then this though hehe. But I would love to use your date_fiff function.
Would you allow that?
And if so, I tried to upload your entire commentscript on my xampp server, but I get an error:
Fatal error: Cannot redeclare date_diff() in C:\xampp\htdocs\commentscript\index.php on line 139
Have you got any idea of why this is happening to me?
Thanks.
Brian.
Should say date_diff
@Brian sure feel free to use the date function for whatever you like
@Brian i’ll update the code, thanks
Oh thanks Ashley.
Hello Ashley.
Give me a heads up when you’ve updated the code.
I’ve figured it out, thanks.
Thanks, for the script really waht i’ve been looking for. Am sort of new to Php and Ajax and i have a little question. I intend using this comment script across multiple pages which should have their different comments. Could you please suggest an effecient way of doing this? Thanks
hello nice but i have this error on localhost with xampp
Fatal error: Cannot redeclare date_diff() in D:\xampp\htdocs\shoutbox(3)\shoutbox\index.php on line 139
can you help please
@hups what have you done to modify the code? the download works straight out of the folder.
i have nothing make only db and config to db
Leave a comment...
Connect
Latest Poll
Recent Posts
Design & Dev Jobs
Full-time and freelance job opportunities available at Authentic Jobs:
Post a job and reach web professionals everywhere.