Enable Submit Comment Without Page Reload (Using Ajax)?

When user writes a comment and hits the submit button, WordPress reloads the page, before the comment is shown to the user.

Is there an Ajax-based solution that allows users to submit questions dynamically, without refreshing the whole page?

Related posts

Leave a Reply

2 comments

  1. Save the following javascrip file wpse54189-ajax-comments.js inside your plug-in folder – say plugins/plug-in-name/js (or if this must go your theme, in your theme folder).

    /*
     * jQuery autoResize (textarea auto-resizer)
     * @copyright James Padolsey http://james.padolsey.com
     * @version 1.04
     */
    
    (function(a){a.fn.autoResize=function(j){var b=a.extend({onResize:function(){},animate:true,animateDuration:150,animateCallback:function(){},extraSpace:20,limit:1000},j);this.filter('textarea').each(function(){var c=a(this).css({resize:'none','overflow-y':'hidden'}),k=c.height(),f=(function(){var l=['height','width','lineHeight','textDecoration','letterSpacing'],h={};a.each(l,function(d,e){h[e]=c.css(e)});return c.clone().removeAttr('id').removeAttr('name').css({position:'absolute',top:0,left:-9999}).css(h).attr('tabIndex','-1').insertBefore(c)})(),i=null,g=function(){f.height(0).val(a(this).val()).scrollTop(10000);var d=Math.max(f.scrollTop(),k)+b.extraSpace,e=a(this).add(f);if(i===d){return}i=d;if(d>=b.limit){a(this).css('overflow-y','');return}b.onResize.call(this);b.animate&&c.css('display')==='block'?e.stop().animate({height:d},b.animateDuration,b.animateCallback):e.height(d)};c.unbind('.dynSiz').bind('keyup.dynSiz',g).bind('keydown.dynSiz',g).bind('change.dynSiz',g)});return this}})(jQuery);
    
    
    /*
     * Source: wp-comment-master WordPress Plugin
     * URL: http://wordpress.org/extend/plugins/wp-comment-master/
     * Author URI: http://yjlblog.com
     * Version: 1.7
     * Last Updated: 2011-6-6
     */
    
       var $commentlist=jQuery('.commentlist');
       var $respond=jQuery('#respond');
       var $message=jQuery('<span class="yjl-mes"></span>').appendTo("#commentform");;
       var $list=$commentlist.children();
       var totalCom=$list.length;
       var $textarea=$respond.find('#comment').attr('rows','8');
    
       var currentPage=0,$number,numPerPage,totalPage,$reply;
    
       //track a reply comment
       jQuery('.comment-reply-link').live('click',function(){
           $reply=true;
       });
       var $cancel=jQuery('#cancel-comment-reply-link').click(function(){
           $reply=false;
       });
    
       /*
        *if Ajax comment posting is enabled
        */
       jQuery('#commentform').submit(function(){
           jQuery.ajax({
             beforeSend:function(xhr){
                xhr.setRequestHeader("If-Modified-Since","0");
                $message.empty().append('<img src="'+yjlSettings.gifUrl+'" alt="processing...">');
             },
             type:'post',
             url:jQuery(this).attr('action'),
             data:jQuery(this).serialize(),
             dataType:'html',
             error:function(xhr){
                 if(xhr.status==500){
                   $message.empty().append(xhr.responseText.split('<p>')[1].split('</p>')[0]);
                 }
                 else if(xhr.status=='timeout'){
                   $message.empty().append((yjlSettings.timeOut!=''?yjlSettings.timeOut:'Error:Server time out,try again!'));
                 }
                 else{
                   $message.empty().append((yjlSettings.fast!=''?yjlSettings.fast:'Please slow down,you are posting to fast!'));
                 }
             },
             success:function(data){
                $message.empty().append((yjlSettings.thank!=''?yjlSettings.thank:'Thank you for your comment!'));
                $newComList=jQuery(data).find('.commentlist');
                if(totalCom>0){
                   if($reply)$cancel.trigger('click');
                   else {
                       if(yjlSettings.order=='desc')currentPage=0;
                       else { getTotal($newComList);currentPage=totalPage-1;}
                   }
                   if(yjlSettings.pagination=='disable' || yjlSettings.pagerPos=='after')
                            $commentlist.prev().replaceWith($newComList.prev());
                   else $commentlist.prev().prev().replaceWith($newComList.prev());                     
                   $commentlist.replaceWith($newComList);                            
                }else{
                   if(yjlSettings.repForm=='disable')$newComList.prev().andSelf().insertBefore($respond);
                   else $newComList.prev().andSelf().insertAfter($respond);
                }
                $commentlist=$newComList;
                if(yjlSettings.pagination!='disable')pagination();
                $textarea.val(''); 
             }
           });//end of ajax
          return false;
       });//end of submit function
    
       if(yjlSettings.autoGrow!='disable'){
          $textarea.autoResize({
           // On resize:
           onResize : function() {
            jQuery(this).css({opacity:0.8});
          },
          // After resize:
          animateCallback : function() {
            jQuery(this).css({opacity:1});
          },
          // Quite slow animation:
          animateDuration : 300,
          // More extra space:
          extraSpace : 20
          });
       }
    

    The above code uses a variable which stores the location of an ‘ajax’ loading image (see below). We need to give this variable the location of the image, which should be your plug-in folder, say plugins/plug-in-name/img, (or, again, if you must, your theme’s folder). We will use use wp_localise_script.

    First though, we need register this script with WordPress, listing jquery as a dependency:

    add_action('init','wpse54189_register_script');
    function wpse54189_register_script(){
        //Register script
        wp_register_script( 'wpse54189_ajax_comment', plugin_dir_path(__FILE__ ).'js/wpse54189-ajax-comments.js',array('jquery'));
    
        //Add global variable storing ajax image
        wp_localize_script( 'wpse54189_ajax_comment', 'yjlSettings', array(
             'gifUrl'=> plugin_dir_path(__FILE__ ).'img/ajax-loader.gif',
    
             /* remove this line if you don't want the comment textbox's height
             to increase with the size of comment. */
             'autoGrow'=> 'enable'
        ));
    
    }
    

    Then when you wish to enqueue the file: wp_enqueue_script('wpse54189_ajax_comment') – this will automatically print the variables and ensure jquery is loaded before hand.

    This can be placed inside template files, or for plug-ins, you can enqueue the script on a hook (for instance the comment_form_before hook):

    add_action('comment_form_before','wpse54189_register_script'){
         wp_enqueue_script('wpse54189_ajax_comment')
    }
    

    You can get a nice Ajax loading gif from here. Or simply use this:

    Loading gif

    All the JavaScript code was grabbed from wp-comment-master plugin (of course, I removed the unnecessary snippets — just kept what’s needed).