
Revenge of the node comments: a pure jQuery comment pager
A previous post described how to reposition node comments with Drupal's hook_menu_alter()
, to facilitate a tabbed interface. One side effect that popped up was pagers – when a pager link was clicked, the tab state got reset. The solution was to refresh the #comments div with AJAX. As an interesting twist, it uses the ability of jQuery's $()
to construct a new DOM object from HTML. This means that no new menu callback is needed in Drupal; it fetches the comments directly from the href
in the pager link. While a little inefficient, this technique has the cool benefit of being able to grab any content from anywhere on your site, with merely a URL and a selector. It also degrades gracefully for non-javascript users; since without JS the tabs appear as sequential blocks the pager will function normally.
(The following code is based on the AJAX Comments project).
/** * Attaches the ahah behavior to each ahah form element. */ Drupal.behaviors.ajax_comments_pager = function(context) { $('#comments .pager:not(.pager-processed)', context).addClass('pager-processed').each( function() { $target = $(this); $target .find('li > a') .click(function () { $(this).animate({paddingRight:16}, 'fast').addClass('throbber').removeAttr('style'); Drupal.turn_over_page($target, $(this).attr('href'), true, function(){}, function(){ $(this).removeClass('throbber'); }); return false; }); }); } /** * Turn over a single page. * * @param target * The .pager element. * @param url * New page URL. * @param scroll * Is scroll to comments header needed. * @param success_callback * Function which will be called after pagination * (or immediately if pager does not exists). * @param error_callback * Function which will be called on AJAX error. */ Drupal.turn_over_page = function(target, url, scroll, success_callback, error_callback) { if (target.length && url) { ajaxPath = url; $.ajax({ url: ajaxPath, type: 'GET', success: function(response) { $newComments = $(response).find('#comments'); $("#comments").replaceWith($newComments); Drupal.attachBehaviors($newComments.parent()); if (scroll) { offset = $('#product-tabs').offset(); $('html,body').animate({scrollTop: offset.top}); } }, error: function() { error_callback(); alert(Drupal.t("An error occurred at @path.", {'@path': ajaxPath})); }, dataType: 'html' }); } else { success_callback(); } }
Comments
I got this working with only very small mods to the css selectors. Now I am trying to figure out how to make it work with out doing a full page load, ie. just grab the comments without loading the whole page
Fri, 12/03/2010 - 18:07
Great work! Thanks for posting this :)
Mon, 11/01/2010 - 16:38