Comments with jQuery and JSON

Asynchronous Comments with PHP, jQuery, and JSON

In this article, we’re going to look at how we create a simple but effective means of capturing and displaying visitor comments using a blend of jQuery, PHP and JSON. In the public forum that is the blogosphere, the ability to capture and display visitor comments on your blogs can give you instant feedback and opinions from the people that matter most – those that read your blog.

Outline

We’ve several tasks that need to be accomplished in order to complete this example; when the page on which the comments are displayed is initially loaded, we need to display all of the existing comments. Additionally, when a new comment is made, we’ll need to display this on the page after the existing comments, as well as sending the new comment to the server for storage with the existing comments.

Tools Required

We’ll be using jQuery (version 1.3.1), obviously, because it rocks, and we’ll be using JSON because it’s a light-weight and efficient format for transporting data across networks. We’ll also be using a little simple PHP to interact with a MySQL database. You’ll need to have access to an installation of MySQL server and should prepare a new database called comments that contains a table, also called comments, which has a name column and a comment column. Running a select all query to your database should produce a result similar to that shown below:

demonstration

Getting Started – The Stored Comments

Let’s make a start by creating the PHP file that reads the comments from the database and returns them to the page; this way, when we come to code the page, the data will already be available for us to use. In a new file in your text editor add the following code:

<?php

  //db connection detils
  $host = "localhost";
  $user = "root";
  $password = "your_password_here";
  $database = "comments";
	
  //make connection
  $server = mysql_connect($host, $user, $password);
  $connection = mysql_select_db($database, $server);
	
  //query the database
  $query = mysql_query("SELECT * FROM comments");
	
    //loop through and return results
  for ($x = 0, $numrows = mysql_num_rows($query); $x < $numrows; $x++) {
    $row = mysql_fetch_assoc($query);
    
    $comments[$x] = array("name" => $row["name"], "comment" => $row["comment"]);		
  }
	
  //echo JSON to page
  $response = $_GET["jsoncallback"] . "(" . json_encode($comments) . ")";
  echo $response;  

?>

Save this as comments.php. Let’s briefly walk through what we do with this code. We store the access credentials for our server in the first four variables and following this, we connect to the database. We then query the database and select all of the data from it.

For Loop

In the next section of code we use a for loop to cycle through each row of data. On each iteration of the loop we add a new item to an array ($comments). The array is a multidimensional associate array and each item will have two sub items which are given the keys name and comment, matching the columns in our table. The value of each item will be the data from each respective field in the current row.

JSON Encode

Finally we package up the completed JSON object in a GET request and then use the native PHP json_encode function to convert our array into a properly formatted JSON object. We’ll be using a JSONP callback in the JavaScript, which is why we need to use a get response and also why we wrap the JSON encoded array in brackets. To clarify the structure of the data that we’re returning, if we were writing it out manually we would do something like this:

([
  {name:"a name", comment:"a comment"},
  {name:"a name", comment:"a comment"},
  { etc }
])

This consists of a simple array, where each item in the array is an object. These inner objects each have two properties – author and comment, where the values of these properties are the data extracted from the text file. Nesting the inner objects in an array makes it extremely easy for us process the data with jQuery. The following screenshot shows how the JSON object will be interpreted by Firebug:

demonstration

Displaying the Stored Comments

Now that we have an object to work with, we can create the HTML page that will display the comments. In a new file in your text editor add the following mark-up:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <link rel="stylesheet" type="text/css" href="comments.css">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Asynchronous Comments</title>
  </head>
  <body>
    <div id="content">
      <h2>Some Content</h2>
      <p>Lorem ipsum dolor...</p>
    </div>
    <div id="comments">
      <h2>Reader Comments</h2>
    </div>
    <div id="leaveComment">
      <h2>Leave a Comment</h2>
      <div class="row"><label>Your Name:</label><input type="text"></div>
      <div class="row"><label>Comment:</label><textarea cols="10" rows="5"></textarea></div>
      <button id="add">Add</button>
    </div>
    <script type="text/javascript" src="jquery-1.3.1.min.js"></script>
  </body>
</html>

Save this file as comments.html. Most of the mark-up is non-essential and is used to give the example some substance. On the page we have some dummy content, a container which the existing comments can be rendered into and some basic form elements used to leave a new comment. In the head of the page we link to a stylesheet and at the end of the body we link to the jQuery library.

CSS

The stylesheet used in this example is non-essential and is used simply to present the example neatly. It consists of the following CSS:

body { font-family:verdana; font-size:11px; color:#ffffff; }
#content {
  width:400px; height:195px; border:3px solid #000000; margin:0 auto 10px;
  font-size:13px; background-color:#575454;
}
#content p { padding:0 10px; }
#comments {
  width:400px; border:3px solid #000000; margin:0 auto 10px;
  padding-top:5px; background-color:#575454;
}
.comment {
  background-color:#d4d7d6; border:1px solid #000000;
  padding:5px 0 5px 5px; color:#000000;
}
#leaveComment {
  width:400px; border:3px solid #000000; margin:0 auto;
  overflow:hidden; position:relative; background-color:#575454;
}
h2 { text-align:center; margin:5px 0 10px; }
.row { padding-left:5px; margin-bottom:5px; clear:both; overflow:hidden; }
.row label {
  width:100px; text-align:right; margin-right:5px; display:block;
  float:left; font-weight:bold; padding-top:5px;
}
.row input, .row textarea, .row div {
  width:280px; display:block; float:left;
}
#add {
  position:absolute; bottom:5px; left:60px; font-weight:bold;
  font-size:10px;
}

Save this as comments.css in the same directory as the HTML page. I won’t cover exactly what this code does as it’s pretty trivial and is used purely for display purposes. It should cause the page to be displayed as follows:

demonstration

Javascript

Now we can add the JavaScript that will request the JSON object from the server, process it and display the comments. Directly after the link to jQuery add the following script block:

<script type="text/javascript">
  $(function() {
			
    //retrieve comments to display on page
    $.getJSON("comments.php?jsoncallback=?", function(data) {
				
      //loop through all items in the JSON array
      for (var x = 0; x < data.length; x++) {
					
        //create a container for each comment
        var div = $("<div>").addClass("row").appendTo("#comments");
						
        //add author name and comment to container			    
        $("<label>").text(data[x].name).appendTo(div);		   
        $("<div>").addClass("comment").text(data[x].comment).appendTo(div);
      }
    });			
  });			
</script>

Again this code is fairly trivial; when the page has loaded, we use the getJSON method to request the JSON object from the PHP file, specifying the path to the file as the first argument. We add the JSONP callback – ?jsoncallback=? – to the end of the URL and then specify an anonymous callback function as the second argument, which will be executed if and when the request returns successfully.

Within our callback we have a simple for loop which is used to loop through each item in the JSON array. For each item we create a container div which is given a class of row and is then appended to the main comments container div.

We then specify a label and set the text of the label to the value of the name property of the object in the current array item. After the label has been appended to the current container div, we create another div which is used to hold the value of the comment property. The comment is then appended to the current container div.

Now when we run the page, we should find that the comments from the database are displayed within the specified container div:

demonstration

Adding New Comments Asynchronously

For the final part of this tutorial we can see how easy it is to automatically insert a new comment after the existing comments, while at the same time sending the new comment to the server to be added to the database so that it can be displayed automatically when the page is next loaded. Add the following new code directly after the getJSON method:

//add click handler for button
$("#add").click(function() {
				
  //define ajax config object
  var ajaxOpts = {
    type: "post",
    url: "addComment.php",
    data: "&author=" + $("#leaveComment").find("input").val() + "&comment=" + $("#leaveComment").find("textarea").val(),
    success: function(data) {
							
      //create a container for the new comment
      var div = $("<div>").addClass("row").appendTo("#comments");
						
      //add author name and comment to container
      $("<label>").text($("#leaveComment").find("input").val()).appendTo(div);
      $("<div>").addClass("comment").text($("#leaveComment").find("textarea").val()).appendTo(div);
    }
  };
					
  $.ajax(ajaxOpts);
});

Again, this is very straight-forward code – what we’re doing is quite complex, but jQuery abstracts away all the difficulty and cross-browser trickiness, leaving us to write just a few lines of code. We first set a click handler for the add comment button. This will execute the anonymous function specified as an argument to the click method whenever the button is clicked.

Within this function we first create a new literal object which is used to configure the new AJAX request. We specify the type of request, the URL of the resource we’re requesting, some data and a success callback function. Within our success function all we do is get the contents of the input and textarea and add them to the comments div in the same way that we did with the original comment data received when the page loads.

Database Connection

We’ll need one more PHP file in order to write the new comment to the database:

<?php

  //db connection detils
  $host = "localhost";
  $user = "root";
  $password = "your_password_here";
  $database = "comments";
	
  //make connection
  $server = mysql_connect($host, $user, $password);
  $connection = mysql_select_db($database, $server);
	
  //get POST data
  $name = mysql_real_escape_string($_POST["author"]);
  $comment = mysql_real_escape_string($_POST["comment"]);

  //add new comment to database
  mysql_query("INSERT INTO comments VALUES(' $name ',' $comment ')");

?>

Save this file as addComment.php. We specify our connection information once more and connect to the database. We then get the data sent by our JavaScript from the $_POST superglobal variables and then use the mysql_query function to insert the new data into the table. Notice that we use the mysql_real_escape_string function to prevent any misuse of our database; although it’s unlikely that any harm could come from an attacker gaining access to this particular database, it’s always wise to sanitize any data before it is added.

Now we should find that when we add a comment, the new comment is displayed on the page, and subsequent reloads of the page will show the new comment:

demonstration

Summary

Asynchronous comments are made easy with a combination of jQuery, simple scripts and the lightweight and highly effective JSON format. Although this is just a basic example, to which we could do so much more, I think you’ll agree when I say that it’s easy to implement a basic, but robust solution to the capture and display of comments from your visitors.

To learn more from Dan Wellman, be sure to sign up for our Net Plus program, where you can read, among others, his in depth tutorial/screencast “Build an Advanced “Poll” jQuery Plugin”. Sign up now!

  • Subscribe to the NETTUTS RSS Feed for more daily web development tuts and articles.


Tags: jQuery
Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.danwellman.co.uk Dan Wellman

    Hi,

    This article is meant to show the machanics of making the AJAX requests and processing the results. Security should be paramount in any public facing application of course, although as this wasn’t the main focus of the tutorial it was only touched upon lightly. However, while I wouldn’t claim the code was bullet-proof, you can see from the comments on the demo page that people have tried various script and XSS insertions, all of which certainly appear to have failed and don’t cause any issues on page load.

    Adding the comment to the page before making the AJAX request is a very good suggestion, however, there may be occasions when for some reason the AJAX request fails. In this situation the visitor may think their comment has been saved as it has appeared on the page, when in fact it may not have been saved. Could be misleading.

    The comment page has been completely spammed and there are hundreds of comments. This is to be expected in a comment example page. However, if the page was about something else entirely would there have been that many comments? I doubt it.

    We could do everything using PHP, sure. But there would inevitably be a page reload somewhere along the line. Also, we use JSON and JSONP in this example, so, without having PHP installed and configured on your own computer, you can still run the example page and load the comments from my domain. Asynchronously. Without xdomain exclusion. While you wouldn’t need to do this in this type of comments system, it is nevertheless an interesting and valuable technique which isn’t possible using PHP alone.

    It isn’t unobtrusive, but again, as with the security aspect, this wasn’t central to the discussion at hand.

    @Merxhan: the same thing (although without the JSONP callback) is possible with other data exchange formats such as XML. Although I vastly prefer working with JSON than XML this is just my own opinion.

    Thanks again for reading and for everyone’s comments and suggestions, they are all very much appreciated :D

    • http://test.com test

      test

  • http://www.duzodesign.com Timothy

    Command line SQL? Why not phpMyAdmin, or some other GUI?

  • Eduardo

    pretty amazing!

  • http://yoosuf.awardspace.com M.A.Yoosuf

    @Timothy: using command line will make you to remember, if u do with phpmyadmin or mysql Query browser yes its easy, but its not a big project only one table so its always better to go with the Command line Rather than the GUI.

    BTW, nowadays Programming becoming so easy, hope all know about Pega and Windows Work flow foundation. all these uses for Big scale projects.

    so my very last conclusion is always better to go up with what will make us remember for some time.

    Cheers.
    Yoosuf
    Comment added By using Safari Beta 4

  • Amr

    Actually, its not bad.. but too slow.. and no limitation for the comments in the page..
    I’ve done sth like “Twitter Election which is over”.. with Rails and jQuery..
    I hope to find time to send the tut to nettuts…

    Cheers…

  • http://www.smple.com John McMullen

    I’ve got a script similar to this I’m working on for a website, but instead of directly accessing the .val() of the form elements, I’m setting up a variable first. Problem is, any time there’s a single quote it messes things up. I’m going to give the direct access a gander.

    Also, instead of just pushing the posts out, I use (‘yourdiv’).load(‘mysqlcall.php’) inside of a function and call that upon success of writing to the db.

    Any thoughts on that vs. your way?

    Great tut though! jQuery is the greatest.

  • http://www.smple.com John McMullen

    ^ As far as the single quotes issue, I wasn’t writing to the db as an escape string. Got that from your tut though;) Guess I need to start looking at that kind of stuff.

  • Pingback: NETTUTS.com: Asynchronous Comments with PHP, jQuery, and JSON | pcsourcenetwork.com

  • http://yeqing.woxihuanni.com little

    really nice!!!!!!

  • http://www.indie-preneur.com @indie_preneur

    Does the name of the database have to be ‘comments’ as well as the table name? Or can I change the name of the db to be whatever I want and just need to change the instance of $database = and to the new name?

  • http://smple.com/ John McMullen

    ^ The name of the db or table can be whatever you want. Just be sure to reference it correctly.

  • Jam

    A CAPTCHA and/or time delay would be an ideal implementation; this is WAY too easy to spam. Nice tutorial otherwise, though. :D

    • http://www.danwellman.co.uk Dan Wellman

      lol, I noticed (the spamming) ;)

      Agreed on the captcha, infact I saw a very, very niec jQuery powered visual cpatcha recently somewhere, integrating that would be both easy and fun :D

      thanks for reading

  • mac sucks

    Nice, your using vista… The way the world should be ran, through Windows! Nice tutorial, I have been searching for one of these.

  • ninad

    this is nice but how can i view my old comments after this page refresh

  • rootboy

    thanks for this tutorial… i was already cursing you for not explaining how to create the tables (using whatever method, i don’t know what matters in MySQL), because it wasn’t working…

    1) then i discovered i scrolled over the bit where you add the onclick handler to the html… (maybe keep the code bits in one piece would be better).
    2) after that the comments DID show, but they weren’t apparently stored in the database, because the disappeared on reload. That was due to a spelling error in the database name in one of the php files. :P

    When i cleaned up the traces of my own sloppiness, it works like a charm. Cheers.

    Any more on the security problems would be appreciated though! Is it safe to use these scripts in the real world?

  • Bhavin

    Hi,

    I was searching like the same thing since long… thanks…well i m upgrading it to some extent…….u have done gr8 job by starting it up….

    my next plannings with this ,, are…

    1. put Captcha for security
    2. disbaling till comments / Captacha has been entered.
    3. Put Multiple Comments component in just same page (need suggestion in it…)

    im using php for server side scripting…. so please provide me suggestion if i have any idea to do that…….

    Thanks again its good development,
    Bhavin Shah

  • http://www.criminal-state.com Rocky

    Umm

    if(!isset($this) !isset($that)){
    echo ‘Fill out required stuff’;
    };

  • thom

    Is there anyway this tutorial could be adapted to make use of mootools instead of jquery. I am having conflicts on the page I am implementing it to and don’t seem to be able to fix it with the jquery noconflict

    Any advice is greatly appreciated
    Thom

  • test

    abc

  • Dorin

    Great job! I appreciate your good explanation.

    • Ryan

      Ye I Agree

  • Bob

    is there an easy way to add pagination?

  • http://www.cakesns.cn/ ylcz

    good! easy to learn!

  • Pingback: 20 Useful PHP + jQuery Components & Tuts for Everyday Project | Noupe

  • http://twitter.com/saurabhshah saurabh shah

    very nice

  • http://www.rad-dudes.com Justin G

    Any chance of getting a version with threaded comments similar to DIGG or Youtube comments?

    • http://www.massbase.com/enatom enatom

      I Really want that too.

  • Duron

    Thanks

  • Pingback: 克兰印象 » 20款PHP+JQuery应用

  • iooi

    жопа

  • http://blog.smileylover.com ghprod

    Great …. the function like updater in prototype :D

    Thnx for this tutz :D

    regards

  • dan

    testing

  • Shoolioms

    emm… luv it )

  • Michael

    Good. But when I press the button, nothing happens.. Why?

  • http://www.syltluwe.nl luwe

    Great tutorial, just what i was looking for !

  • Occuquan

    Hello fellow coders, I see that some people are complaining that this script is not working. Well the first time I tested to make sure that it’s working, it didn’t! There are 3 important thing that you have to do when you want to use this script.

    1. You have to change the MYSQL information (host, user name, pwd, db name) in the “addComments.php” and “comments.php” files!

    2. Don’t forget to make the SQL table “comments” in your database with the fields “name” & “comment”

    3. Then the most important thing, the jQuery plug in is not included in the source file, so make sure that you have a copy of the plug in near these files!

    So good luck. Great script. Used it, Loved it! Thank!

  • Pingback: Asynchronous Comments with PHP, jQuery and JSON - Tutorial Collection

  • Harshad

    awesome, i’m trying to do it using ASP.NET and jQuery

  • http://www.webtrafficroi.com ZK@Web Marketing Blog

    i finally experimented until i got the css selector right. the preview is now right below the comment textarea and above the filter tips. This is still not ideal. Perhaps side by side is ideal (for wide screen monitors) but even then it would be very hard to line up the changing parts in the textarea and in the Preview once you get a few paragraphs into your comment. This is a really interesting problem that someone should solve :)

  • Tony

    Thank You

  • Frank

    Great tutorial! How would I go about adding this to another page on the same site? Obviously I would need a second table, but how could I script it so that I wouldn’t have to rewrite everything just to access the second table for another page?

    Thanks.

    • http://www.FreeAgentDesigns.com Eric

      Just looking at the code in quick glance, I think that the easiest way via a plug n play of this script would be to duplicate the COMMENTS database and rename each database to WHATEVER, then inside the php files and the scripting, just change COMMENTS as in the dbserver to each name.

      Thats just a quick look though… i am sure there are other options

  • Pingback: Asynchronous Comments with PHP and jQuery - Tutorial Pro

  • http://www.FreeAgentDesigns.com Eric

    OCCUQUAN!!! GREAT CALL!!!!
    I WAS GETTING TICKED! LOL
    Then i read number 3…..

    This is sweet

    3. Then the most important thing, the jQuery plug in is not included in the source file, so make sure that you have a copy of the plug in near these files!

    So good luck. Great script. Used it, Loved it! Thank!

  • http://www.FreeAgentDesigns.com Eric

    Is there a quick way to keep the comments up posted?

  • Sarah

    Where can I get the jquery plug-in from ? Sorry but I am new at this and can’t manage to set up the jquery…

  • Sarah

    http://jquery.com/ – I managed :)

  • Sarah

    Hi Sorry again.. though I’m having problems as the comments aren’t appearing well! When a user writes a long comment its not going to the next line just stays writting out the text in a long straight line! Any idea how to fix this??

  • Mike

    Is there a way to limit comments being shown? for exmpl. I want just 5 last comments to be displayed.

    Is it possible to create a box where comments will be displayed, again only 5 last comm. would be visible. and you could go to 2nd,3rd page, but of that box. Can this be done? maybe with jquery?

  • http://www.zangproductions.co.uk Rob

    Is there a way to use the data from json more like php?

    Im pulling news items from the database they are listed in a table where the user can delete or open a page to edit.

    Im hoping to use in place editing on those but am not sure with the way the data is passed over I can do that.

    Also, my news items have formatting (from FCKeditor), when the data comes back from json, it isnt displaying is as html, but giving all the formatting tags

  • Jan

    great post, and what i need to do if I have 24 items and would to display this table of comments, but I want that in each item will only display the comment for that item and not for all in one…what I would need to do? please help :(

    congratulations for the web site

  • Jan

    Just forgot to ask, how Can i delate some comments on it?

  • Jan

    have trouble now….when I post a comment and then refresh the page, the comment disappear…why this hapens?