In Ajax comments in Drupal 5: How I made it parts I and II we saw the code needed on the back-end. Now, let’s see what goes on the client side: the Javascript.
Submitting the comment with an ajax request
Basically, to add a comment we need the node id (nid) and the comment text. The code in the back-end will handle the user info and permissions. The first thing we do is find the comment form and the submit button. Then we hook the click event on the submit button.
-
var commentForm = jQuery('form#comment-form');
-
if (!commentForm.length) return;
-
var submitBtn = jQuery('#edit-submit');
-
if (!submitBtn.length) return;
-
-
submitBtn.click(function(ev)
-
{
-
// …
-
}
When the user clicks the submit button, we get the node id (we could have done on domready) and the comment text. If the comment is empty, we don’t do anything, so the comment will be submitted the standard way and Drupal will fail the comment form validation.
-
// Get Node Id
-
var nid = jQuery('#node-nid').text();
-
if (!nid) return true; // Do nothing…
-
if (parseInt(nid) <= 0) return true;
-
-
// Get Comment Text
-
var text = jQuery('#edit-comment').val();
-
if (!text) return true; // Let Drupal validate the form
Since we don’t want to get back just the comment added but all the new comments added by any user on this node, we want to pass the last comment id on screen.
-
// Get last comment Id
-
var lastComment = jQuery('div.comment:last');
-
var lastCommentId = (lastComment.length)? lastComment.id().split('-')[1] : 0;
Due to my limited knowledge of jQuery at the time, I used the load function for the ajax request. The problem with this function is that, from what I know, it only works on elements already included in the DOM. So before the request, I had to create a container for the new comments. The point of insertion will differ if the page already has comments or not:
-
// We got both nid and text. Let's create the comment holder
-
var comment = jQuery(document.createElement('div'));
-
comment.hide();
-
if (lastComment.length) {
-
lastComment.after(comment);
-
} else {
-
comment.insertBefore(jQuery('div.box'));
-
}
Finally, the load request:
-
// Ajax submit/load
-
comment.load('/add/comment',
-
{ 'nid': nid,
-
'text': text,
-
'lastcid': lastCommentId
-
},
-
function(responseText, textStatus, XMLHttpRequest) {
-
if (textStatus == 'success' && responseText) {
-
ajax_insert_comment(comment);
-
} else {
-
comment.remove();
-
alert("Error: No se pudo enviar el comentario");
-
}
-
}
-
);
If the request failed, the container was removed. If the request succeeded, the new comments were added to the page:
-
ajax_insert_comment = function(comment) {
-
// Insert new comments
-
comment.show();
-
};
And that was it! Ajax comments in Drupal working like a charm.
Adding/removing the “new” indicator
Now that I had my Ajax comments working I wanted them to look better. For example, I wanted the new added comments to have the “new” indicator, while at the same time I wanted to remove the indicator from the comments already on the screen. On ajax_insert_comment:
-
// Clear 'new' from previous comments
-
jQuery('div.comment').find('span.new').remove();
-
// Add 'new' indicator
-
var newcomment = jQuery(document.createElement('span'));
-
newcomment.addClass('new').html('new');
-
newcomment.insertBefore(comment.find('div.comment-author'));
And many other tweaks like that.
The code
Here is the whole code for ajax comment submission I currently use:
-
ajax_comments = function() {
-
var commentForm = jQuery('form#comment-form');
-
if (!commentForm.length) return;
-
var submitBtn = jQuery('#edit-submit');
-
if (!submitBtn.length) return;
-
-
submitBtn.val('Enviar comentario');
-
submitBtn.click(function(ev)
-
{
-
// Disable submit button
-
submitBtn.val('Enviando…').attr("disabled","disabled");
-
-
// Clear the 'edit' link from previous comments
-
jQuery('li.edit-comment-link').remove();
-
-
// Get Node Id
-
var nid = jQuery('#node-nid').text();
-
if (!nid) return true; // Do nothing…
-
if (parseInt(nid) <= 0) return true;
-
-
// Get Comment Text
-
var text = jQuery('#edit-comment').val();
-
if (!text) return true; // Let Drupal validate the form
-
-
// Get last comment Id
-
var lastComment = jQuery('div.comment:last');
-
var lastCommentId = (lastComment.length)? lastComment.id().split('-')[1] : 0;
-
-
// // We got both nid and text. Let's create the comment holder
-
var comment = jQuery(document.createElement('div'));
-
comment.hide();
-
if (lastComment.length) {
-
lastComment.after(comment);
-
} else {
-
comment.insertBefore(jQuery('div.box'));
-
}
-
-
// Ajax submit/load
-
comment.load('/add/comment',
-
{ 'nid': nid,
-
'text': text,
-
'lastcid': lastCommentId
-
},
-
function(responseText, textStatus, XMLHttpRequest) {
-
if (textStatus == 'success' && responseText) {
-
ajax_insert_comment(comment);
-
jQuery('#edit-comment').val('');
-
} else {
-
comment.remove();
-
alert("Error: No se pudo enviar el comentario");
-
}
-
// Reenable submit button
-
submitBtn.val('Enviar comentario').removeAttr("disabled");
-
}
-
);
-
-
return false;
-
});
-
};
-
-
ajax_insert_comment = function(comment) {
-
// Clear 'new' from previous comments
-
jQuery('div.comment').find('span.new').remove();
-
// Add 'new' indicator
-
var newcomment = jQuery(document.createElement('span'));
-
newcomment.addClass('new').html('new');
-
newcomment.insertBefore(comment.find('div.comment-author'));
-
// Remove comment count
-
comment.find('span.commentcount').empty();
-
// Insert new comments
-
comment.show();
-
jQuery('#edit-comment').focus();
-
};
-
-
jQuery(document).ready(function() {
-
ajax_comments();
-
});
As you can see, when I wrote this code back in July, I have just started using jQuery and I didn’t know much about event handling. So I used the old return true/false to stop the submit event if needed. Also, now that I see the code again I can think on better ways to do parts of it. Well, that’s a good sign: it means I’m getting better :)
Series:
Ajax comments in Drupal 5: How I made it – Part I
Ajax comments in Drupal 5: How I made it – Part II
Ajax comments in Drupal 5: How I made it – Part III
See the ajax comments in action
Please, note this is a WordPress based blog. The Drupal website where I have implemented the ajax comments is www.spaniards.es

Hi Eneko,
thanks for the example! As a Drupal-Newbie, your site is a good point to start looking under the hood of Drupal.
My question: Would it work in Drupal 6 too?
Thanks,
Fritz
I don’t see why it shouldn’t work on Drupal 6, although I haven’t tested it.
Let me know if you do :)
I will give it a try. My next question is a newbie-question too:
I basically know how to create simple modules with PHP, but:
How does the JavaScript-code fit in the module? In which file is it?
Thanks,
Fritz
What I did is put the js code on a separate javascript file inside the misc folder (ajax_comments.js in my case). Then, I included the js file on my page.tpl.php template.
There are better ways to do it, specially if you want to encapsulate the js code inside a module, but I didn’t have time for that.
Let me know if you have any other questions :)
I tried it. It did not work yet. Probably some little mistake. I guess, I have to learn how the comments-module, the new module and the javascript-part play together to make it run – if it does work in Drupal 6. And I’m waiting for a Drupal-pro to try it too…
AJAX-comments seem to be an important module in wordpress. Funny, that Drupal-people don’t show much interest.
Thanks for your answers! :-)
Well, finally I have upgraded Spaniards.es to Drupal 6 and so I have done with my ajax comment solution.
It works fine after a few teaks. The major changes are on the menu module, since the way to register new entry points (URL paths) has changed. Then I did one minor fix on the javascript code and voilá… ajax comments working again :)
Let’s see if I can find some time to republish the code, better explained. Maybe I should put this on a module, although I have seen some new ajax comments recently.
Hello webmaster
I would like to share with you a link to your site
write me here preonrelt@mail.ru
nice
having a problem with this:
-I’ve got the module enabled and am including your .js file in the page. But when I submit a comment as an authenticated user, the comment is created…but without the author information being saved in the DB.
How do I get the author info to be saved in the DB?:
i want to add a comments section to my site the files are all html, and i would like to know if anyone has seen a ajax comment script?
iv tried google but no luck