Advertisement

Asynchronous Comments with PHP, jQuery, and JSON

by

This Cyber Monday Tuts+ courses will be reduced to just $3 (usually $15). Don't miss out.

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.


Advertisement