Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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?

share|improve this question

2 Answers 2

up vote 5 down vote accepted

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).

share|improve this answer
    
You really should enqueue scripts. Also, use wp_localize_script to add javascript global variables to a page. –  Stephen Harris Jun 5 '12 at 7:44
    
@StephenHarris Awesome! Thanks for the edit! –  its_me Jun 5 '12 at 9:51

Yes, there is a lot of solutions, check it here: http://wordpress.org/extend/plugins/search.php?q=ajax+comments

share|improve this answer
    
(1) I did not want to use a plugin. (2) I just wanted one feature — the page shouldn't reload when user submits a comment. (3) I had the solution which I wanted to share. Hence the question :) –  its_me Jun 4 '12 at 19:05
    
@AahanKrish download a plugin and take a look how it is implemented there ;) –  Eugene Manuilov Jun 4 '12 at 19:06
    
Exactly. That's what I did! –  its_me Jun 4 '12 at 19:08
2  
@AahanKrish then my answer is correct :D –  Eugene Manuilov Jun 4 '12 at 19:09

protected by Community Oct 8 '12 at 10:38

Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.