Comment and reply html code

You can use the following HTML code to create a comment box within your HTML document.

Show

Let’s apply some CSS to make things look a bit nicer by adding the following to main.css:

#respond {
  margin-top: 40px;
}

#respond input[type='text'],
#respond input[type='email'],
#respond textarea {
  margin-bottom: 10px;
  display: block;
  width: 100%;

  border: 1px solid rgba(0, 0, 0, 0.1);
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  -o-border-radius: 5px;
  -ms-border-radius: 5px;
  -khtml-border-radius: 5px;
  border-radius: 5px;

  line-height: 1.4em;
}

Once the HTML structure, the comment form and the CSS are in place our blogging system has started to look a bit more presentable.

Comment and reply html code

Handling Comment Submission

The next step is to write the PHP form submission handler which accepts the request and stores the comment, post_comment.php. You should create this file in the root of your application.

As I said earlier I’m keen to focus on the real-time functionality so a class exists within the template that you’ve downloaded which encapsulate some of the standard data checking and persistence functionality. This class is defined in Persistence.php (you can view the source here), is in no way production quality, and handles:

This also means that we don’t need to spend time setting up a database and all that goes with it and makes post_comment.php very simple an clean. If you wanted to use this functionality in a production environment you would need to re-write the contents of Persistence.php. Here’s the code for post_comment.php.

add_comment($_POST) ) {
  header( 'Location: index.php' );
}
else {
  header( 'Location: index.php?error=Your comment was not posted due to errors in your form submission' );
}
?>

The above code does the following:

  1. Includes the Persistence.php class which handles saving and fetching comments.
  2. Creates a new instances of the Persistence object and assigns it to the variable $db.
  3. Tries to add the comment to the $db. If the comment is successfully added it redirects back to the blog post. If it fails the redirection also occurs but some error text is appended to an error query parameter.

The final thing we need to do to have our Generic Blog Commenting System up and running is to update the blog page, index.php, to fetch and display the comments from the Persistence object.

get_comments($comment_post_ID);
$has_comments = (count($comments) > 0);
?>

Since we now have the $comment_post_ID accessible via PHP we should update the HTML for the comment form to use this value.

We now have all the comments related to the blog post referenced by the $comments variable we need to display them on the page. To do this we need to update the PHP in index.php to iterate through them and create the required HTML.

  1. Be the first to add a comment.

You’ll notice that if the value of $has_comments is true an additional CSS class is applied to the ordered list called has-comments. This is so we can hide the list item with the “Be the first to add a comment” message when comments are being displayed using CSS:

#posts-list.has-comments li.no-comments {
  display: none;
}

Now that all this is in place we have a functional blog commenting system. If you would like to start writing your code from this basic functioning blog commenting system you can also download the code completed up to here.

Comment and reply html code

Progressive Enhancement With jQuery

The first step in making our blog commenting system feel less like a Web page and more like an application is to stop page reloads when a user submits a comment. We can do this by submitting the comments to the server using an AJAX request. Since jQuery is probably the defacto standard for cross browser JavaScript functionality we’ll use it here. Although I’m using jQuery here, I’d also like to highlight that it’s a good idea to not always use jQuery. Instead, analyze your scenario and make a considered decision because there are some cases where you are best not to.

In an attempt to try and keep as much scripting (PHP and JavaScript) from the index.php file we’ll create a new folder for our JavaScript and in there a file for our application JavaScript. The path to this fill should be js/app.js. This file should be included after the jQuery include.


When the page is ready bind to the submit event of the form.

$(function() {
  $('#commentform').submit(handleSubmit);
});

When the form is submitted and the handleSubmit function is called the comment data we want to send to the server is extracted from the form. There are more elegant ways of fetching the data from the form but this approach clearly shows where we’re getting the values from and the data object we are creating.

function handleSubmit() {
  var form = $(this);
  var data = {
    "comment_author": form.find('#comment_author').val(),
    "email": form.find('#email').val(),
    "comment": form.find('#comment').val(),
    "comment_post_ID": form.find('#comment_post_ID').val()
  };

  postComment(data);

  return false;
}

function postComment(data) {
  // send the data to the server
}

Within the postComment function make a POST request to the server passing the data that we’ve retrieved from the form. When the request is made an additional HTTP header will be sent to identify the request as being an AJAX request. We want to do this so that we can return a JSON response if it is an AJAX request and maintain our basic functionality if it isn’t (for more information on this see Detected AJAX events on the Server). We also define two handlers; postSuccess for handling the comment being successfully stored and postError to handle any failures.

function postComment(data) {
  $.ajax({
    type: 'POST',
    url: 'post_comment.php',
    data: data,
    headers: {
      'X-Requested-With': 'XMLHttpRequest'
    },
    success: postSuccess,
    error: postError
  });
}

function postSuccess(data, textStatus, jqXHR) {
  // add comment to UI
}

function postError(jqXHR, textStatus, errorThrown) {
  // display error
}

At this point the comment data is being sent to the server and saved, but the AJAX response isn’t providing any meaningful response. Also, the comments section isn’t being updated to show the newly submitted comment so the user would have to refresh the page to see it. Let’s start by writing the code to update the UI and test that functionality.

If you are thinking “Hang on a minute! We don’t have all the data we need from the Web server to display the comment” then you are correct. However, this doesn’t stop us writing the code to update the UI and also testing that it works. Here’s how:

function postSuccess(data, textStatus, jqXHR) {
  $('#commentform').get(0).reset();
  displayComment(data);
}

function displayComment(data) {
  var commentHtml = createComment(data);
  var commentEl = $(commentHtml);
  commentEl.hide();
  var postsList = $('#posts-list');
  postsList.addClass('has-comments');
  postsList.prepend(commentEl);
  commentEl.slideDown();
}

function createComment(data) {
  var html = ’ +
  '
  • ' + '' + '
    ' + '

    ' + data.comment + '

    ' + '
    ' + '
  • '; return html; } function parseDisplayDate(date) { date = (date instanceof Date? date : new Date( Date.parse(date) ) ); var display = date.getDate() + ' ' + ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'][date.getMonth()] + ' ' + date.getFullYear(); return display; }

    The code above does the following:

    • Within the postSuccess function we clear the form values and call displayComment.
    • displayComment first calls the createComment function to create the list item (
    • ) HTML as a String.
    • We then convert the HTML to a jQuery object using $(commentHtml) and hide the element.
    • The comment list item is then prepended to the comments ordered list (
        ). The list also has a class called has-comments added to it so we can hide the first list item which contains the “Be the first to comment” statement.
      1. Finally, we call commentEl.slideDown() so that the comment is shown in what is becoming the standard “here’s a new item” way.

    The functionality is now implemented but we want to test it out. This can be achieved in two ways:

    • The displayComment is a global function so we can call it directly using the JavaScript console of the browser.
    • We can bind to an event on the page that triggers a fake update which calls the displayComment function

    Let’s go with the latter and bind to the “u” key being released by binding to the keyup event. When it is, we’ll create a fake data object containing all the information required to create a new comment and pass it to the displayComment function. That comment will then be displayed in the UI.

    Hit the “u” key a few times and see the comments appear.

    $(function() {
    
      $(document).keyup(function(e) {
        e = e || window.event;
        if(e.keyCode === 85){
          displayComment({
            "id": "comment_1",
            "comment_post_ID": 1,
            "date":"Tue, 21 Feb 2012 18:33:03 +0000",
            "comment": "The realtime Web rocks!",
            "comment_author": "Phil Leggetter"
          });
        }
      });
    
    });

    Great! We now know that our displayComment function works exactly as we expect it to. Remember to remove the test function before you go live or you’ll really confuse your user every time they press “u”.

    Comment and reply html code

    Detect and Responding to the AJAX request

    All that’s left to do is update the post_comment.php file to detect the AJAX call and return information about the newly created comment.

    Detecting the AJAX request is done by checking for the X-Requested-With header:

    $ajax = ($_SERVER[ 'HTTP_X_REQUESTED_WITH' ] === 'XMLHttpRequest');

    Once we know the request is an AJAX request we can update the code to respond with an appropriate status code and the data representing the comment. We also need to ensure that the original functionality is maintained. The post_comment.php code now looks as follows:

    add_comment($_POST);
    
    if($ajax) {
      sendAjaxResponse($added);
    }
    else {
      sendStandardResponse($added);
    }
    
    function sendAjaxResponse($added) {
      header("Content-Type: application/x-javascript");
      if($added) {
        header( 'Status: 201' );
        echo( json_encode($added) );
      }
      else {
        header( 'Status: 400' );
      }
    }
    
    function sendStandardResponse($added) {
      if($added) {
        header( 'Location: index.php' );
      }
      else {
        header( 'Location: index.php?error=Your comment was not posted due to errors in your form submission' );
      }
    }
    ?>

    Key points from the above code are:

    • The $db->add_comment($_POST) call returns the data from the added comment which is assigned to the $added variable.
    • By setting the response Content-Type to “application/json” we tell jQuery to convert the returned string into a JavaScript object. For more information on calling JSON Web services see A Beginner’s Guide To jQuery-Based JSON API Clients.
    • The 201 status code indicates a successful call and also that a resource (the comment) was created by the call.

    The blog commenting system now works in a much more dynamic way, instantly showing the user that their comment has been posted without refreshing the page. In addition, the way the we’ve added the JavaScript based functionality to the page means that if JavaScript is disabled or a JavaScript file fails to load that the system will fallback to the standard functionality we first implemented.

    Getting Real-Time—Finally!

    As with any “from scratch” tutorial it can take a bit of time to get to the really interesting part, but we’re finally here. However, all the work we’ve up in has been worth it. Because we’ve built our commenting system up in a progressively enhanced way, plugging Pusher into it is going to be really easy

    What is Pusher?

    At the start of the tutorial we said that we would use Pusher to add the realtime functionality to the application. But what is Pusher?

    Pusher is a hosted service for quickly and easily adding realtime features into Web and mobile applications. It offers a RESTful API that makes it really easy to publish events from any application that can make a HTTP request and a WebSocket API for realtime bi-directional communication. You don’t even need to use the APIs directly as there are server (PHP, Ruby, node.js, ASP.NET, Python and more) and client (JavaScript, iOS, Android, .NET, ActionScript, Arduino and more) libraries available in a host of technologies which means you can add realtime functionality to an app within minutes ‐ I’m confident you’ll be surprised just how easy!

    Sign up for Pusher and get your API Credentials

    In order to add Pusher-powered real-time functionality to a Web application you first need to sign up for a free Sandbox account. After you have signed up you’ll be taken to the Pusher dashboard where you’ll see that a “Main” application has been created for you. You’ll also see you are in the “API Access” section for that application where you can grab your API credentials.

    Comment and reply html code

    For ease of access create a pusher_config.php file and define the credentials in there so we can refer to them later:

    In your version of pusherconfig.php be sure to replace the values which being ‘YOUR with your actual credentials.

    You should also require this in your index.php file. We should also make the APP_KEY available to the JavaScript runtime as we are going to need it to connect to Pusher.

    
    
    

    Real-time JavaScript

    The first thing you need to do when adding Pusher to a Web application is include the Pusher JavaScript library and connect to Pusher. To connect you’ll need to use the key which you grabbed from the Pusher dashboard. Below you can see all that is required to hook up the front-end application to Pusher.

    Include the Pusher JavaScript library after the app.js include:

    
    
    

    Add the Pusher functionality to app.js:

    var pusher = new Pusher(APP_KEY);
    var channel = pusher.subscribe('comments-' + $('#comment_post_ID').val());
    channel.bind('new_comment', displayComment);

    This probably looks too easy to be true, so here are the details about what the above code does:

    • var pusher = new Pusher(APP_KEY); Creates a new instance of a Pusher object and in doing so connects you to Pusher. The application to use is defined by the APP_KEY value that you pass in and that we set up earlier.
    • var channel = pusher.subscribe('comments-' + $('#comment_post_ID').val()); Channels provide a great way of organizing streams of real-time data. Here we are subscribing to comments for the current blog post, uniquely identified by the value of the comment_post_ID hidden form input element.
    • channel.bind('new_comment', displayComment); Events are used to further filter data and are ideal for linking updates to changes in the UI. In this case we want to bind to an event which is triggered whenever a new comment is added and display it. Because we’ve already created the displayComment function we can just pass in a reference to the call to bind.

    Sending Real-Time Events using the Event Creator

    We can also test out this functionality without writing any server-side code by using the Event Creator for your app which can also be found in the Pusher dashboard. The Event Creator lets you publish events on a channel through a simple user interface. From the code above we can see that we want to publish an event named “new_comment” on the “comments-1” channel. From the earlier test function we also have an example of the test data we can publish.

    Comment and reply html code

    Real-time PHP

    Again, we’ve proven that our client-side functionality works without having to write any server-side code. Now lets add the PHP code we need to trigger the new comment event as soon as a comment is posted in our comment system.

    Pusher offers a number of server-side libraries which make it easy to publish events in addition to helping with functionality such as private channel authentication and providing user information for presence channels. We just want to use the basic event triggering functionality in the post_comment.php file so we need to download the Pusher PHP library.

    Once you’ve downloaded this zip file, unzip it into the directory along with your other files. Your file structure will now look something like this:

    • index.php
    • css (dir)
    • images (dir)
    • post_comment.php
    • pusher_config.php
    • Persistence.php
    • squeeks-Pusher-PHP (dir)
      • lib (dir)
        • Pusher.php

    An event can be triggering in just a few lines of code:

    trigger('comments-1', 'new_comment', array(
      "comment_post_ID" => 1,
      "date" => "Tue, 21 Feb 2012 18:33:03 +0000",
      "comment" => "The realtime Web rocks!",
      "comment_author" => "Phil Leggetter"
    ));
    ?>

    However, we need to apply a some additional logic before we trigger the event:

    • Check that the comment was added.
    • Extract the unique comment identifier from the $added array.
    • Build the text to identify a channel name for the submitted comment.
    • Trigger a _newcomment event on the channel with the $added data. Note: The library automatically converts the $added array variable to JSON to be sent through Pusher.

    Therefore the full post_comment.php file ends up looking as follows:

    add_comment($_POST);
    
    if($added) {
      $channel_name = 'comments-' . $added['comment_post_ID'];
      $event_name = 'new_comment';
    
      $pusher = new Pusher(APP_KEY, APP_SECRET, APP_ID);
      $pusher->trigger($channel_name, $event_name, $added);
    }
    
    if($ajax) {
      sendAjaxResponse($added);
    }
    else {
      sendStandardResponse($added);
    }
    
    function sendAjaxResponse($added) {
      header("Content-Type: application/json");
      if($added) {
        header( 'Status: 201' );
        echo( json_encode($added) );
      }
      else {
        header( 'Status: 400' );
      }
    }
    
    function sendStandardResponse($added) {
      if($added) {
        header( 'Location: index.php' );
      }
      else {
        header( 'Location: index.php?error=Your comment was not posted due to errors in your form submission' );
      }
    }
    ?>

    If you run the app now in two different browser windows you’ll see that as soon as you submit a comment in one window that comment will instantly (“magically”) appear in the second window. We now have a real-time commenting system!

    But…, we’re not done quite yet. You’ll also see that the comment is shown twice in the window of the user who submitted it. This is because the comment has been added by the AJAX callback, and by the Pusher event. Because this is a very common scenario, especially if you’ve built an application in a progressively enhanced way as we have, the Pusher server libraries expose a way of excluding a connection/user from receiving the event via Pusher.

    In order to do this you need to send a unique connection identifier called a socket_id from the client to the server. This identifier can then be used to define who will be excluded.

    function handleSubmit() {
      var form = $(this);
      var data = {
        "comment_author": form.find('#comment_author').val(),
        "email": form.find('#email').val(),
        "comment": form.find('#comment').val(),
        "comment_post_ID": form.find('#comment_post_ID').val()
      };
    
      var socketId = getSocketId();
      if(socketId !== null) {
        data.socket_id = socketId;
      }
    
      postComment(data);
    
      return false;
    }
    
    function getSocketId() {
      if(pusher && pusher.connection.state === 'connected') {
        return pusher.connection.socket_id;
      }
      return null;
    }

    The changes we’ve made are:

    • A new function called getSocketId has been added to get the socket_id. It wraps a check to ensure that the pusher variable has been set and also that the client is connected to Pusher.
    • The handleSubmit has been updated to check to see if a socket_id is available. If it is, this information is posted to the server along with the comment data.

    On the server we need to use the socket_id parameter if it is present and therefore exclude the connection and user who submitted the comment, or pass in null if it’s not:

    $channel_name = 'comments-' . $added['comment_post_ID'];
    $event_name = 'new_comment';
    $socket_id = (isset($_POST['socket_id'])?$_POST['socket_id']:null);
    
    $pusher = new Pusher(APP_KEY, APP_SECRET, APP_ID);
    $pusher->trigger($channel_name, $event_name, $added, $socket_id);

    And as simple as that we have a fully realtime enabled blog commenting system and we only send messages to users who really need to see them. As with the AJAX functionality the realtime functionality has been added in a progressively enhancing way, to ensure it doesn’t impact on any other functionality. You can find the a demo running here and the completed solution in the realtime commenting repository in github.

    Good Real-Time App Development Practices

    Real-time application development shares common good development practices with general Web development. However, I thought I would share a couple of tips that can come in particularly handy.

    Use Browser Developer Tools

    When you start doing a lot of JavaScript development the browser developer tools becomes your best friend. It’s the same when adding realtime functionality to your Web app, not only because you are using JavaScript, but also because the JavaScript library you are using is likely to be doing some reasonably complex things internally. So, the best way of understanding what is going on and if your code is using it as expect is to enable logging which usually goes to the developer console. All major browser vendors now offer good developer tools which include a console:

    • Firebug addon for Firefox
    • Internet Explorer F12 developer tools
    • Opera Dragonfly
    • Safari Developer Tools

    The Pusher JavaScript library provides a way to hook into the logging functionality. All you need to do is assign a function to the Pusher.log static property. This function will then receive all log messages. You can do what you like within the function but best practice is to log the messages to the developer console. You can do this as follow, ensuring the code it executed after the Pusher JavaScript library include:

    Pusher.log = function(msg) {
      if(window.console && window.console.log) {
        window.console.log(new Date().getTime() + ': ' + msg);
      }
    };

    The code above checks to make sure the console and log function is available - it’s not in older browsers - and then logs the messages along with a timestamp to the JavaScript console. This can be incredibly handy in tracking down problems.

    Comment and reply html code

    Check Connectivity

    Any good real-time technology will maintain a persistent connection between the client (web browser) and the Web server or service. Sometimes the client will lose connectivity and when the client isn’t connected to the Internet the real-time functionality won’t work. This can happen a lot with applications running on mobile devices which rely on mobile networks. So, if your application relies on that connectivity and functionality then it’s important to deal with scenarios where the client isn’t connected. This might be by displaying a message to tell the user they are offline or you might want to implement some alternative functionality.

    The Pusher JavaScript library exposes connectivity state via the pusher.connection object, which we briefly saw earlier when fetching the socket_id. Binding to state changes and implementing your required functionality is quite simple as it follows the same mechanism as binding to events on channels:

    var pusher = new Pusher(APP_KEY);
    
    pusher.connection.bind('state_change', function(states) {
      Pusher.log('Connection state changed from: ' + states.previous + ' to ' + states.current);
    });

    Conclusion

    We’re seeing real-time functionality appearing in a large number of high profile applications: some have it at the core of what they offer whilst others use it sparingly. No matter how it is used the end goal is generally the same; to enhance the user experience and keep users engaged with an application. By converting a basic blog commenting system into a more engaging communication platform I hope I’ve demonstrated that the functionality and experience can easily be layered on existing application.

    The ease of access to this technology is a relatively new thing and we’ve only just touched the potential uses for the technology. Real-time stats, instant news updates, activity streams, social interaction, collaboration and gaming are just a few common uses but as more developers become aware of, and comfortable with, the technology I’m confident that we’re going to see some truly amazing innovation. An “Internet of Real-Time Things?”?

    How do you code a comment in HTML?

    The HTML Comment Tag Comments in HTML start with -- and end with --> . Don't forget the exclamation mark at the start of the tag! But you don't need to add it at the end.

    How do I create a comment section in HTML and JavaScript?

    Adding // in front of a code line changes the code lines from an executable line to a comment.

    How do I add a comment box to my website in HTML?

    HTML Comment Box.
    First log in to your Google account. ... .
    Then go to the HTML Comment Box..
    In the blue box, click on Log in..
    You will be taken to your Google email account..
    Enter your login information..
    Once completed you will be taken back to the HTML Comment box site..

    How do you make a comment box?

    Comments.
    Click on a file's name to open it in preview..
    Type your comment in the comment box at the bottom of the right-hand sidebar..
    Click Post to add your comment..
    When you enter a comment, all collaborators who have notifications enabled will receive an email..