How To AJAX-ify Your WordPress Comments

ajax wordpress commentsBy default, the WordPress commenting system is woefully inadequate – one my biggest objections being that to post a comment, the page needs to refresh. You could switch to a third party system like Livefyre or Disqus, but if you’d prefer to keep everything in house or do some other kind of customization, then posting comments by AJAX is the least you should do.

You can see an example of this working here on MakeUseOf – when you post a comment, you won’t leave the page – instead we’ll send it through an AJAX call, and then send a quick “thank you” note back. Read on for a full tutorial.

For using non-WordPress functions as AJAX, please read my previous tutorial, and be sure to check out all the WordPress related articles.

Introduction

There are a two separate parts needed to get AJAX WordPress comments working, so lets explain those first to give you an overview of the whole process.

  • Some Javascript on the page that intercepts the user clicking the Add Comment submit button, that also makes it an AJAX call and also handles the response.
  • A PHP handler that hooks into the comment_post action

Javascript

First off, this is going to need jQuery, as does anything remotely exciting in web development nowadays. If you’re not sure if it’s already being loaded, go ahead and skip down to the Javascript code and try it anyway – if you have Firebug and the console log says “jQuery is undefined” when you refresh the page, then add this line to your functions.php file to ensure it’s being loaded.

function google_jquery() {
if ( !is_admin() ) { wp_deregister_script('jquery'); wp_register_script('jquery', ("http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"), false);
wp_enqueue_script('jquery'); } } 
 
add_action('wp_print_scripts ', 'google_jquery');

Note, that’s an elaborate way of loading jQuery because we’ll be using the latest version from Google CDNs, which is faster and more up to date than the one included by default with WordPress – so it might be a good idea to add that anyway even if jQuery is already loaded elsewhere.

Now, for the actual Javascript that will handle the comment form, we have a few options. The easiest is to just paste the code into your single.php template – assuming you don’t have commenting enabled for pages as well.

Alternatively, you could paste into an existing .js file used by your theme, or create a new .js file in your theme directory. If you choose to put it into your own separate .js file and not paste it directly into your theme template, be sure to add the following lines to your functions.php, and note the filename is assumed to be ajaxcomments.js in the root of your theme folder.

add_action('init', 'ajaxcomments_load_js', 10);
function ajaxcomments_load_js(){
		wp_enqueue_script('ajaxcomments', get_stylesheet_directory_uri().'/ajaxcomments.js');
}

Here is the Javascript to handle the comment form (or you can view it on pastebin):

<script type="text/javascript">
// AJAXified commenting system
jQuery('document').ready(function($){
var commentform=$('#commentform'); // find the comment form
commentform.prepend('<div id="comment-status" ></div>'); // add info panel before the form to provide feedback or errors
var statusdiv=$('#comment-status'); // define the infopanel
 
commentform.submit(function(){
//serialize and store form data in a variable
var formdata=commentform.serialize();
//Add a status message
statusdiv.html('<p>Processing...</p>');
//Extract action URL from commentform
var formurl=commentform.attr('action');
//Post Form with data
$.ajax({
type: 'post',
url: formurl,
data: formdata,
error: function(XMLHttpRequest, textStatus, errorThrown){
statusdiv.html('<p class="wdpajax-error" >You might have left one of the fields blank, or be posting too quickly</p>');
},
success: function(data, textStatus){
if(data=="success")
statusdiv.html('<p class="ajax-success" >Thanks for your comment. We appreciate your response.</p>');
else
statusdiv.html('<p class="ajax-error" >Please wait a while before posting your next comment</p>');
commentform.find('textarea[name=comment]').val('');
}
});
return false;
 
});
});</script>

To break the code down, we’re first creating jQuery objects of the comment form (which assumes your comment form has the default css ID of “commentform”), and adding an empty info panel above it which we’ll later use to display messages to the user about the progress of posting their comment.

commentform.submit is used to ‘hijack’ the submit button. We then serialize the form data (turn it into one long line of data), give a “Processing” message to the user in that info panel, and go ahead with an AJAX request. The AJAX request is a standard format, but not really in the scope of this tutorial today – suffice to say it reacts to either a success or error, and blanks out the form if successful to prevent the same comment being accidentally posted twice. Adjust the messages and errors as appropriate, or add some suitable styling to your theme’s stylesheet if you’d like the error messages to stand out somehow. The last line – return false - prevents the form from completing it’s default action.

PHP Handler

Lastly, we need something to prevent the page refresh and send the appropriate response back to the user as well as notifying the admin if the comment needs moderating, or notifying the author of a new comment. For this, we hook into the comment_post action which occurs just after it’s added to the database, and detect if it was an AJAX request. Add this to your functions.php file:

(Also available at this pastebin)

add_action('comment_post', 'ajaxify_comments',20, 2);
function ajaxify_comments($comment_ID, $comment_status){
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) &amp;&amp; strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'){
//If AJAX Request Then
switch($comment_status){
case '0':
//notify moderator of unapproved comment
wp_notify_moderator($comment_ID);
case '1': //Approved comment
echo "success";
$commentdata=&amp;get_comment($comment_ID, ARRAY_A);
$post=&amp;get_post($commentdata['comment_post_ID']);
wp_notify_postauthor($comment_ID, $commentdata['comment_type']);
break;
default:
echo "error";
}
exit;
}
}

Spot Problems

If the page is still refreshing instead of posting through AJAX, it’s likely to be one of two problems. One – you might not have jQuery loaded. Install Firebug, or enable Chrome developer tools, and check the console log for errors. If jQuery isn’t found, go back up to the JavaScript section and read the first bit on adding jQuery to your theme. The second possibility is that your theme does something special to the comment form and it’s ID is no longer “commentform”. Check the source code, then adjust the var commentform=$(‘#commentform’) line in the JavaScript to be the correct ID – that might work.

As ever, I’m around to help out further as much as I can, but please post links to an example URL where I can take a quick look, or post in the MakeUseOf Answers forum if this post’s comments are closed. Enjoy AJAXified the comments!


MakeUseOf Recommends

James Bruce

James is a keen gamer with a passion for the iPad, and records Technophilia - an awesome but somewhat NSFW technology podcast - weekly with Justin and Dave.

The comments were closed because the article is more than 180 days old.

If you have any questions related to stuff mentioned in the article or need help with any computer issue, just ask it on MakeUseOf Answers.

Hide 48 Comments

  • mike April 27, 2012
    0 likes

    nice tutorial, most of the plugins done work for this

    | Like
    • Nasir Awan July 19, 2012
      0 likes

      Yeah there are many plugins I see. But still didn’t found a reliable one. Planning to code my own soon!

      | Like
  • LD Jackson April 28, 2012
    0 likes

    Thanks for the tutorial. I am in the process of working this into my blog now.

    | Like
  • some1 April 30, 2012
    0 likes

    Having problemes with the code…

    | Like
    • Tina May 3, 2012
      0 likes

      What’s the problem?

      | Like
  • Felipe Veiga May 27, 2012
    0 likes

    The only part that really amazes me is the fact that Makeuseof is not currently using any of this on the WordPress install. 
    I would recommend for the less knowledgeable of PHP the plugin called Social.

    | Like
  • Felipe Veiga May 27, 2012
    0 likes

    Never mind, delete my old comment, as when trying to just hit the spam and post the comment I was sent to the default WordPress comment error page, but when actually writing the comment the upload was ajaxified.

    Still, I would recommend for the less knowledgeable of PHP the plugin called Social

    | Like
  • Oskar Karlin May 29, 2012
    0 likes

    I’m using this script with the latest version of wordpress 3.3.2 and for some strange reason WordPress starts sending notification emails to the authors of the articles when using this ajax posting. If I disable the function and post “normal” by loading the page again, no email is sent to the authors.

    Do you have any clue of what’s going on? Could it be a bug in WordPress or this script?

    | Like
    • muotechguy May 30, 2012
      0 likes

      Not sure what you mean Oskar; this code does notify the post authors, certainly. As far as I’m aware, it’s supposed to. I mean, notifying is default behaviour. Do you *not* want them notified?

      It could be that you have notifications *disabled* in post admin. This code forces it though, regardless of what you have set. Just comment out the wp_notify_postauthor function call if you don’t want that behaviour.

      Does that help?

      | Like
      • Oskar May 30, 2012
        0 likes

        Oh! OK! I forgot to look in the php part, I thought there was some bug in wordpress but all it was wast the wp_notify_postauthor function. And no, I don’t want authors to be notified.

        Thanks for your help!

        | Like
  • Rhys Davies June 14, 2012
    0 likes

    very useful tutorial just added this to my blog

    | Like
  • Ray June 18, 2012
    0 likes

    Posts nicely the comment, but doesn`t refrehes the comments

    | Like
  • Ray June 18, 2012
    0 likes

    ps that is in my case (just checking here if its just in my case)

    | Like
  • Mike June 24, 2012
    0 likes

    just wanted to see this in action

    | Like
  • Pollux July 1, 2012
    0 likes

    Is this suppose to post the comment with ajax as in the comment actually appears when it’s submitted because I’m just getting the confirmation. I actually have to refresh the page to see the comments I posted.

    | Like
    • ernestortiz July 7, 2012
      0 likes

      As Pollux and Ray notticed, the page should be refresh in order to show the new comments (seem not so “ajaxed”, isn’t?).

      What I did today (for the site http://elbarcoebrio.com) was to append

      .done(function() {
      location.reload();
      });

      to $.ajax(), in the javascript. Nice enought.

      | Like
      • muotechguy July 9, 2012
        0 likes

        Good hack, though that maybe ruins the whole point of it being AJAX. Here, I made a few changes to the JS now on this site, so it at least posts back what their comment is: http://pastebin.com/UHnPgf4J

        You may need a few changes to the CSS classes on the page too, please check out the source code of the comment area here for any differences.

        | Like
  • Jim July 3, 2012
    0 likes

    Totally

    | Like
  • Fem July 5, 2012
    0 likes

    Nice Tutorial

    | Like
  • Ryan July 7, 2012
    0 likes

    Is the PHP code really necessary? since you are already hijacking the the form and submitting all required data to wp-comments-post.php

    | Like
    • muotechguy July 7, 2012
      0 likes

      Yes, that’s what makes the AJAX part work and enables us to react on the front end.

      | Like
  • Ashok July 9, 2012
    0 likes

    Thanks. Used it on my blog

    | Like
  • Jesse Gardner July 18, 2012
    0 likes

    Wish there were a plugin that did this…

    | Like
  • omer August 14, 2012
    0 likes

    Nice tutorial .. i am gonna use it in my website .. can you please give me a hint on how did you make this easy to register through facebook twitter etc .. ?

    | Like
    • James Bruce August 14, 2012
      0 likes

      Ours is through a third party provider that costs, but http://Janrain.com also do a free version you can use. I would suggest using LiveFyre for comments though, much better than this!

      | Like
      • omer August 14, 2012
        0 likes

        Thanks .. can you please specify more i don’t want to host my comments somewhere else .. so that i can show comment count on each post .. is it possible with LiveFyre ?

        | Like
        • Alexia August 14, 2012
          0 likes

          LiveFyre does host your comments elsewhere, as well as locally in the WP DB. But yes, it shows comment count throughout your blog assuming your theme doesnt do anything weird.

          | Like
  • Simon August 15, 2012
    0 likes

    Hi there!
    Having problems with this workaround.

    At first, the form is submitted by ajax and I see the message “processing”, but then it always turns into “please fill in all needed data” (ok, the message does not only have to do with the needed data, it simply means there has been an error during the process). The debug console of safari says that the directory the form is submitted to can’t be found, though it IS the path to the current site. I tried any “permalink”-options, but still it doesn’t work.

    Any ideas?

    | Like
    • muotechguy August 15, 2012
      0 likes

      Hi Simon – can you paste a link to your site here so I can take a look?

      | Like
  • Jafar August 16, 2012
    0 likes

    Woah nice tutorial.

    | Like
  • jeton August 23, 2012
    0 likes

    Testing the ajaxified comments

    | Like
  • Mike August 28, 2012
    0 likes

    I couldn’t see my first comment I don’t know why?!

    | Like
    • Tina August 29, 2012
      0 likes

      Mike,

      It’s possible that it went into moderation. If it has not been published in the meantime, it probably didn’t survive that step. Unfortunately, I can’t tell you whether or not we deleted it or why.

      | Like
  • Farzad Mohsenvand September 2, 2012
    0 likes

    Its The Best Tutorial. Thank You

    | Like
  • omer September 9, 2012
    0 likes

    I am getting this
    Parse error: syntax error, unexpected T_STRING in D:\wamp\www\wordpress\wp-content\themes\avada\functions.php on line 42

    That means

    if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == ‘xmlhttprequest’){

    | Like
    • omer September 10, 2012
      0 likes

      I have fixed that error replace (&&) with (&) without brackets…
      but now i have another error to face …

      Jquery is not loading .. when going to inspect element > console in chrome i get this error
      Uncaught ReferenceError: jQuery is not defined
      I have done every thing which is stated in this article ..
      P.S i am using it on localhost … does this effect ?

      | Like
      • muotechguy September 10, 2012
        0 likes

        Sounds like you haven’t loaded jQuery correctly. Can you check out the source and verify jquery is being loaded?

        | Like
    • James Bruce September 10, 2012
      0 likes

      Don’t run on a local WAMP server; put it on an actual website.

      | Like
    • omer September 10, 2012
      0 likes

      All ok now .. errors were when i was using it on localhost.. i tried on live website now its working there too ..
      See the example at http://www.zemtv.com

      | Like
  • varts.us September 12, 2012
    0 likes

    Please take a time for my questions:

    1. After I added this, the comment form is shown above the commentlist. So how to move the comment form to below commentlist?

    2. There are any way to AJAX-ify the reply comment part?

    Thanks for great tut!

    | Like
  • John September 13, 2012
    0 likes

    Is it working on this page?

    | Like
    • James Bruce September 13, 2012
      0 likes

      An older version of it is, yes. Since then I have implement the user comment being sent back to the browser to give a better indication oof it being posted correctly.

      | Like
  • Eric Schulzke September 20, 2012
    0 likes

    I expect this can be done, but does this code lend itself to two parallel installations? I want to have one comment section where coauthors respond only to each other, and another where anyone can comment. How hard would this be to pull off?

    | Like
    • James Bruce September 21, 2012
      0 likes

      This code can certainly be adapted, but the core WordPress comment posting won’t allow that – there’s no way to separate a comment stream by author. The most you can do is highlight authors and users, as we do here. You’re talking about creating a custom database to store special author comments I think.

      | Like
  • Shahrul September 22, 2012
    0 likes

    would you make a plugin for this? thanks

    | Like
  • Arch!tect September 22, 2012
    0 likes

    very useful. Thanks

    | Like
  • Sumaiya September 29, 2012
    0 likes

    thanks for the great tutorial :)

    | Like