JSON Blog Archive Links Using jQuery and Drupal

One little project that I wanted to get done on this site was to have the monthly archive links (over there on the left) load a list of post titles via AJAX and list them underneath the month when clicked. For some reason, I thought this was how Blogger was set up, but I can’t seem to find any pages that work that way. This was a fairly straight forward project that took about 2 hours (or something like that—work, eating, and all that stuff makes me unable to time things correctly). It required writing a short jQuery plugin and a Drupal menu callback to handle the JSON request. Here’s the jQuery plugin (I don’t think it’s that complicated for comments, plus I don’t feel like commenting it):

Drupal.behaviors.blogArchive = function(context) {
  $("#block-tsukuda_blog-1 a.blog-archive-month:not('.processed')").archiveLinks().addClass("processed");
}

$.fn.extend({
  archiveLoading: function() {
    return this.each( function(){
      $(this).unbind('click').click( function() {
        return false;
      });
    });
  },
  archiveLinks: function() {
    return this.each( function() {
      var contents = $(this).next('div.item-list').html();

      if (contents) {
        $(this).archiveToggle();
      }
      else {
        $(this).click( function() {
        
          var elementa = $(this);
          var date = $(this).attr("href");
          var dates = date.split('/');
          var year = dates['2'];
          var month = dates['3'];
                
          $.ajax({
            type: 'POST',
            url: '/blog/json',
            data: 'year='+year+'&month='+month,
            dataType: "json",
            beforeSend: function() {
              $("#block-tsukuda_blog-1 a.blog-archive-month").archiveLoading();
              elementa.addClass("loading");
            },
            success: function(json){
              if (json['status'] == 1) {
                elementa.after('');
                $("#archive-links-loader").hide().html(json['data']).slideDown("fast", function() {
                  $(this).replaceWith(json['data']);
                  elementa.unbind('click').removeClass("loading");
                  $("#block-tsukuda_blog-1 a.blog-archive-month").archiveRebind();
                });
              }
              else {
                $("#block-tsukuda_blog-1 a.blog-archive-month").archiveRebind();
              }
              return false;
            },
            error: function (json) {
              $("#block-tsukuda_blog-1 a.blog-archive-month").archiveRebind();
            }
          });
          return false;
        });
      }
    });
  },
  archiveToggle: function() {
    return this.each( function() {
      $(this).toggle(
        function() {
          $(this).next().slideUp("fast");
        },
        function() {
          $(this).next().slideDown("fast");
        }
      );
    });
  },
  archiveRebind: function() {
    return this.each( function() {
      $(this).removeClass("loading processed").archiveLinks().addClass("processed");
    });
  } });

The Drupal menu callback is nothing special. It just takes the date sent by the link and builds a list of items in the range of that month. In any case, I think this the last “major” thing I’m doing on the site for now. I need to get some artwork started.