Refreshing a Web Part Without a Postback Using jQuery’s AJAX Function

I’ve been working on several projects with good old SharePoint 2007 (MOSS). jQuery and jQueryUI sure can spice it up nicely. Recently, I decided I wanted to refresh the contents of a Data View Web Part (DVWP) based on a user selection – a simple click on one of a big set of links – but I wanted to avoid that clunky postback.

SharePoint 2010 has the ManualRefresh capability baked right into DVWPs, but not SharePoint 2007. Besides, I wanted both the trigger for the refresh and the UX to work differently than the rather utilitarian (and never used in my experience) out of the box feel that 2010 gives you.

This is the script I came up with. In this case, I decided to show a nice message in a modal dialog using jQueryUI while I waited for the .ajax() call to complete, as I’m using an AggregateDataSource that is querying several pretty large lists. This means it takes a few seconds to come back, and the dialog saying what’s going on – not just a spinner – makes the UX more palatable.

/*
Refreshes an element's contents on a user action, showing a modal dialog during the refresh
elementId  The id of the container element
qs         The Query String to append to the current URL
title      The title to show for the dialog
msg        The message to show in the dialog
*/

function refreshElement(elementId, qs, title, msg) {

  var elementObj = $("#" + elementId);
  var infoDialog = $("<div><div>" + msg + "</div><div class='aaa-please-wait'></div></div>").dialog({
    open: function(event, ui) {
      $(".ui-dialog-titlebar-close").hide();  // Hide the close X
      $(this).css("overflow-y", "visible");   // Fix for the scrollbar in IE
    },
    autoOpen: false,
    title: title,
    modal: true
  });
  infoDialog.dialog("open");

  elementObj.fadeOut("slow", function() {
    $.ajax({
      async: false,
      url: window.location.pathname + qs,
      complete: function (xData) {
        newHtml = $(xData.responseText).find("#" + elementId).html();
        elementObj.html(newHtml);
      }
    });
  }).fadeIn("slow", function() {
    infoDialog.dialog("close");
  });
}

I made the function pretty generic so that I could pass in the four arguments and use it in multiple locations if I needed to. You could really pass in the id of any element in the page. In the instance I built it for, I was passing a new value on the Query String based on what link the user clicked on, but fetching the same page with AJAX. The DVWP was set up to return different data based on the Query String parameter value.

Keep in mind that both jQuery and jQueryUI must be loaded for this to work.

The CSS for the body of the dialog is pretty simple, but here it is. The sizing worked well for me based on the image I decided to display.

.aaa-please-wait {
  height:150px;
  width:auto;
  background-image:url('/SiteCollectionImages/ajax-loader.gif');
  background-repeat:no-repeat;
  background-position:center center;
}

What do you think? Would this make a good addition to SPServices? If so, what other options would you like me to include? If I did add it to SPServices, I’d remove the dependency on jQueryUI, as I don’t want any outside dependencies other than jQuery itself.

Enhanced by Zemanta