Sunday, June 08, 2008

Auto refresh div using jQuery and Drupal

Recently I had to figure out how to automatically refresh a Drupal block every 5 minutes. The concept is simple enough but since I am new to jQuery (javascript in general really) and Drupal it was difficult for me to find a straight forward example. What follows is step-by-step example of how I solved the problem...


  1. Wrap the content you want to refresh in a <div> tag and give it a meaningful class name or ID (e.g., auto--refresh). The class name (or ID) is arbitrary as you will see in later steps. For example:

    <div class="autorefresh">
    Put something here. It will get updated at a set interval.
    <div>


  2. Create a menu function in Drupal to map the AJAX calback:

    function blockupdate_menu() {
      $items = array();
      $items[] = array(
        'path' => 'blockupdate/update',
        'callback' => 'block_update',
        'type' => MENU_CALLBACK,
        'access' => TRUE,
      );
      return $items;
    }


  3. Implement the function that assembles the data to get sent back to the browser:

    function block_update() {
      //The get_data() function is generic here
      //Use this function to get the updated data for display
      $html = get_data();
      print drupal_to_js(array('html' => $html));
      // The exit() call is critical!
      exit();
    }


  4. Implement the client side callback function in jQuery:

    function autoupdate() {
      $.ajax(
      {
        type: "POST",
        url: "blockupdate/update",
        cache: false,
        success: function(data) {
          var result = Drupal.parseJson(data);
          $("div.autorefresh").fadeIn("slow").html(result['html']);
        }
      });
    }


  5. Use the setInterval Javascript function to perform the auto refresh:

    if( Drupal.jsEnabled ) {
      $(document).ready(function() {
        setInterval("autoupdate()", 5 * 60000);
      });
    }

    Note that the first parameter is the jQuery callback function and the second parameter is the time that will elapse in between a refresh, in milliseconds.



That's all there is to it really! To debug the new functionality make sure you have Firebug extension installed in Firefox and watch the traffic do a full roundtrip with updated content. It's also a good idea to set your interval to no more than a few seconds at first to ensure everything is working properly. Don't forget to read my last post on some of the lessons I learned while exploring jQuery inside of Drupal.

Monday, June 02, 2008

Things you should know about jQuery and Drupal

So in my last post I told you how much I love drupal. Although I had been using drupal to build a web app I hadn't been making use of jQuery at that point. jQuery is almost necessary if you want to add visual effects (client-side) and/or use AJAX within drupal. It was somewhat painful for me to get motivated enough to learn jQuery as I felt there was not a good starting point so in this post I'd like to establish some really basic guidelines for new Drupal developers who wish to use jQuery and do not wish to dig through the Drupal forums or sit through long, sleep-inducing screencasts.

Here's what I learned so far:

  • Don't bother with "inline" jQuery via the drupal_add_js function...inline Javascript isn't cacheable and you WILL get bitten when trying to escape quotes. Create a separate .js file and put all of your jquery in it instead - then use drupal_add_js to link to your Javascript.

  • Spend some time browsing visualjquery.com and don't move past it until you are comfortable with jQuery's syntax...you really will like it once you get going

  • Watch out for relative vs. absolute paths when including external Javascript (jQuery) files within a Drupal module. Use drupal_get_path to build your paths for you.

  • Firebug is your friend



Is this advice simple and perhaps somewhat contrived? You bet. Finding this advice all in one place isn't all that easy so I felt it was my duty to post it! And finally, for the love of god, if you are trying to create a sweet lightbox effect inside your web app, steer clear of Facebox and try your luck with ThickBox instead. :-)

Stay tuned as I raise the bar further and use jQuery inside of Drupal to bring my first AJAX module to life.