PHP Ajax Comments

PHP Ajax Comments

1 Star2 Stars3 Stars4 Stars5 Stars
Posted on July 26, 2009

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

  1. The document ready function adds and removes the text ‘Leave your message here…’ from textarea. when you click in the box.
  2. 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
  3. 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&#8217;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) {
				$('div#loader').find('img.load-gif').remove();
				$('div#loader').append('<span class="success">Thanks for your comment!</span>');
				$('div#loader').hide().fadeIn('slow');
				$('span.limit').remove();
				$('div#comments').prepend(data);
				$('div#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


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>

demodownload

More tutorials from Papermashup
Comments
85 discussions around PHP Ajax Comments
  1. guilliam says:

    hello ashley thanks for this script!

    i also encountered the error with luke,
    Fatal error: Cannot redeclare date_diff() in path\shoutbox\index.php on line 139
    its on the local using xampp

    i have changed:
    function date_diff($d1, $d2){
    into:
    function datediff($d1, $d2){

    on line 94 if the index.php

    i wonder if this would affect on live server. will post back then.
    cheers!

  2. Kenny R says:

    Love this script Ash! I’m using a heavily modified version of this for various things in one of my projects, not only for ‘comments’ but also for various pages where the user is allowed to input records into the database and receive a result (things such as playlists, songs, status updates).

    Most of them allow the user to delete it as well, but only after the page is refreshed where the result is returned from a SELECT. Is there a quick way for me to retrieve the ID of the posted result and return it as a variable?

  3. dimas says:

    where can i find a commenting system ajax but i dont want a plugin install i want to put inside of my theme code wordpress
    thanks

  4. asds says:

    @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

  5. driblak says:

    Good one Thanks Ashley …..luke u too..for same error solved

  6. Zulian says:

    How can I add extra fields like name, email, pageid ect… to my database??? it seems only content field is working on adding a shout box. May be I need add it via javascript and too

    Please help me

  7. poncho says:

    how could i do if i want keep writing messages? ..not refreshing the page everytime i wanted to write ..

  8. Guby says:

    @Bangon Kali

    Thanks man !!!
    This was buugging me for some time but was lazy to figure it out myself
    Innternet makes us lazy bastards :-D

  9. mang peps says:

    great job. But I have one question ? I want the textarea to not be disabled after I posted something,.. How can I do that ?

  10. Bangon Kali says:

    For those who are having problems with the date_diff() function I suggest you rename the function. The function date_diff() is already defined internally by PHP, so re-using it again, especially for later versions of PHP (I’m using 5) would cause an error. I renamed all occurrences of date_diff() function (both calls and definition) in to date_subtract(). And it works fine now. :)

  11. Developer says:

    The script is good, but it have many things to improove. On first place dynamic loading comments. Now if one people write comment and other wanted to answer him immediately, the first people not be able to see the answer without page refresh.

  12. cross says:

    thanks man… it really help me!! :D

  13. sam says:

    i was wondering if anyone can tell me how can i repeatedly post comment by this, text field become disabled after posting the comment once.

  14. Brian says:

    The “&” character does not work using the script, Is there a fix for this as this is a very good comment script, thanks in advance

  15. Brian says:

    Found a bug with using “&” characters on the posts, anyone have a fix for this?? driving me crazy, thanks iin advance.

  16. Brian says:

    Hi, Great script, looks great. Is there any way to add this script to the bottom of a few pages although give each shout box a unqiue id? I’ve tried experimenting but I seem to be missing something. Any help would be much appreciated, thanks for the code!

  17. mitran says:

    Really good script… great effects… can i use it too…. :)

  18. JavaGenious says:

    Thanks for the useful information

  19. alex says:

    great effort! i was also wondering about the name – any easy way to integrate this?

  20. Has says:

    well done

  21. Anwar says:

    Great Post Ashley. Thanks a bunch. It works for me.

    I was trying to add another field where the user also enters their Name with the comments. I added a new row to the table called “name”, but i am having issues inserting this. Can you help me with this?

    Added this to the files (index and submit)

    $ query is:
    $message = $row['content'];
    $visitor = $row['name'];

    Span is:

    Get the message:
    $theVisitor = addslashes(strip_tags($_POST['visitor']));
    $theMessage = addslashes(strip_tags($_POST['message']));

    $theQuery = “INSERT INTO shoutbox (content, date, name) VALUES (‘” . $theMessage . “‘, ‘” . $theDate . “‘, ‘” . $theVisitor . “‘)”;

    As you can see, i am still learning. But any correction would be greatly appreciated
    When i insert names into the DB with a query, they do get displayed on the index page, but i am unable to insert them thru the website form

  22. Joseph says:

    Awesome! Just the ticket I’ve been looking for. Have a video blog, and want people to be able to comment without interrupting the playback of the video. Thanks for the post!

  23. Elvin says:

    I am having problems with this as well. Getting error on page 139 in index.php like others.

  24. kp says:

    can you send me these files would love to play with this. It seems the download link is broke.

  25. Bigaltheking says:

    Hey Ashely,
    Script looks awesome, i was wondering if there is a way to limit the amount of comments on a page, and once there are more, it would add pages of comments.

    eg. http://www.cbc.ca – there comments on any stories.

    So if the comments counted 10, then the 11th would be at page 2 of the comments.

    Im a pure amatuer at this kinda stuff, i do understand the basics, any help would be awesome.

    Thanks,

  26. firas says:

    i think there is something wrong with the download file

  27. hups says:

    i have nothing make only db and config to db

  28. hups says:

    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

  29. Wale Afolabi says:

    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

  30. I’ve figured it out, thanks.

  31. Hello Ashley.

    Give me a heads up when you’ve updated the code. :)

  32. 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.

  33. Sebas says:

    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…..

    • Ashley says:

      @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.

  34. Caio says:

    How to edit comments?

    • Ashley says:

      @caio you’ll need to write a completely different script in order to edit the comments – it wouldn’t be too difficult though.

  35. rapcylix says:

    Oye que pagina tan util te felicito…

  36. evans ebot says:

    hi bro, nice tutorials and really helpful to me, thanks for this

  37. deil says:

    Nice Stuff

  38. Mark says:

    Excellent Tutorial!

  39. TechZia says:

    Hi there,

    I downloaded the zip file, but unable to find the sql file… :-(

    Please post the table structure here.

    Regards,
    TechZia

  40. luke says:

    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.

  41. luke says:

    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?

    • Ashley says:

      @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.

  42. luke says:

    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.

    • Ashley says:

      @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.

  43. Yash says:

    Looks pretty nice to me. I’ll try to implement it in my next blog comments system. Nice work :)

  44. luke says:

    Thanx im gonna give it a go, thats exactly what im looking for, cheers, Cant belive you understood what i was saying, lol.

  45. luke says:

    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,

    • Ashley says:

      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:

      // remember to escape anything passed through a GET variable
      $photoId = mysql_escape_string($_GET['id']);
      SELECT * FROM photo_comments WHERE photo_id=’$photoId’ ORDER BY id DESC

      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:

      // this is jquery
      var photoID = ”;

      // now you pass this to the comments php page through ajax

      Let me know if that helps :)

  46. luke says:

    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.

    • Ashley says:

      @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.

  47. luke says:

    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

    • Ashley says:

      @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);

  48. luke says:

    Ok thanx Ashley ill give it a go, thanx for replying aswell most ppl dont on most sites,

  49. luke says:

    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?

    • Ashley says:

      @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.

  50. luke says:

    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.

    • Ashley says:

      @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

  51. sulla says:

    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)

  52. sulla says:

    “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.

  53. james says:

    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

  54. Catar4x says:

    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 !

  55. Alik says:

    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.

    • Ashley says:

      @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 :)

  56. Adam S says:

    @Ashley, no problem. Sorry if that came off a little abrupt: just trying to give some constructive feedback to those learning along with you.

  57. Pingback: CSS Brigit | PHP Ajax Comments

  58. @Ashley – awesome!

    Could it be possible to load people’s Gravatar then?

  59. Adam S says:

    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.

  60. 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?

    • Ashley says:

      @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.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Looking for a registry cleaner to speed up your PC and show a full diagnostics?
Faster surfing with Dish Network High Speed Internet

Never miss an update from Papermashup

Get notified about the latest tutorials and downloads.

Subscribe by Email

Get alerts directly into your inbox after each post and stay updated.
Subscribe
OR

Subscribe by RSS

Add our RSS to your feedreader to get regular updates from us.
Subscribe

Get in contact

Please use the form below to get in touch.

About Me

I'm Ashley Ford, Co-founder and Technical Director at Harkable.com London, UK. Previously I worked at InMobi, Spotify and MySpace. My interests include photography and making short videos I'm also an avid F1 fan. I'm always working on side projects. Here are a few: Easy Poll, We Deliver.



What do you specialise in?

I spend a lot of time coding in PHP and MySQL, as well as front end XHTML and CSS. I also specialise in javascript and the jQuery framework as well as being an avid designer. You can find me on dribbble

Interested in advertising?

If you'd like to advertise on Papermashup.com you can find details here Or use the contact link below for further advertising opportunities.

How do I contact you

You can contact me here. and I'm available for consultation, freelance, programming book reviews.

Get on the mailing list

Join over 3000 people who have subscribed to the Papermashup inbox message, and be the first to find out about tutorial, competitions and giveaways.