Subscribe via Feed

Reusable Javascript Class to Publish Global and Element Specific Partial Refresh Events (init, onStart, onComplete, onError)

Jeremy Hodge, Mar 24, 2010 3:56:17 PM

Quite a while back I posted a script snippet that showed how to watch, hijack and inject your own custom events into the XSP._partialRefresh function so you can watch for and execute custom code.  As I have delved further into dojo, and the use of classes, and the construction of UI elements, it has become more important for me to be able to watch for the partial refreshes that can trigger the need to unsubscribe or disconnect from event handlers, destroy classes or UI widgets, or trigger a myriad of other tasks that I may need to execute for UI purposes, or prevent lingering effects such as multiple event handlers or memory leaks.

To help with this task, I have created a full fledged class (download link at the end of the post) that allows you to watch the partial refreshes globally by subscribing 1 event handler for each partial refresh event [init, onStart, onComplete, onError] for all elements on a page and/or another event handler for each partial refresh event [init, onStart, onComplete, onError] for a specifically named element on a page.

The object also allows you to turn the pubications on or off at anytime with a simple call to the object, and also allows you to set the XSPSubmitLatency for partial refreshes when you initialize the object.

To use it, you just need to dojo.requireFromNsf it (see previous posts on this blog about reusable javascript objects and creating a NSF based repository):

dojo.requireFromNsf('com.ZetaOne.api.XSP', '/zojs.nsf/');

Then initialize the object somewhere (preferrably in your controller if you are using one ;D ) - or if not an XSP.addOnLoad() will do, like this:

XSP.addOnLoad(function() {
   window.xspHook = new com.ZetaOne.api.XSP({
          enableHooks: true,
          xspLatency: 10000
   });
});

Then whenever you want to subscribe to an event, use code similar to the following:

For Global Partial Refresh Notifications:

dojo.subscribe('/xsp/partialRefresh/init', function(method,form,refreshId,options) {
    alert('GLOBAL partial refresh INIT for "' + refreshId + '" has been called')
});

or for Partial Refresh notifications for specific elements:

dojo.subscribe('/view:_id1:myPanel/partialRefresh/init', function(method,form,refreshId,options) {
     alert('LOCAL partial refresh INIT for "' + refreshId + '" has been called')
});

Note that the previous two examples only show subscribing to the partial refresh in general. You can also susbscribe specifically to the onStart, onComplete, and onError events as well.

From the code:

/**                                                                            |
 * com.ZetaOne.api.XSP.js :: Object that can hook/unhook from the XSP
 * Object's partial refresh function to publish init/onStart/onComplete/
 * onError events globally (via /xsp/partialRefresh/onXxxx) and for every
 * individual object (via /#{id:ElementName}/partialRefresh/onXxxx).
 *
 * NOTE: This class creates its own options object, and passes to your
 * event handlers the original options object that you can modify mid
 * stream to prevent or inject additional events from the subscribed
 * events.  The subscribed events will always fire, regardless of
 * whether or not you have specified an onStart, onComplete, or onError in
 * your partial refresh call.
 *
 *    @author Jeremy G Hodge, ZetaOne Solutions Group, LLC
 *    @version 0.9
 *    @class Manages Local Events for XSP Partial Refreshes at a global and element specific level
 */

And the example also from the code:

/**
 *@example
 *dojo.requireFromNsf('com.ZetaOne.api.XSP', '/zojs.nsf/');
 *XSP.addOnLoad(function() {
 *
 *  window.xspHook = new com.ZetaOne.api.XSP({
 *         enableHooks: true,
 *         xspLatency: 10000
 *  });
 *
 *  // For GLOBAL partial refresh watching
 *  dojo.subscribe('/xsp/partialRefresh/init', function(method,form,refreshId,options) { alert('GLOBAL partial refresh INIT for "' + refreshId + '" has been called') });
 *  dojo.subscribe('/xsp/partialRefresh/start', function(method,form,refreshId,options) { alert('GLOBAL partial refresh START for "' + refreshId + '" has been called') });
 *  dojo.subscribe('/xsp/partialRefresh/complete', function(method,form,refreshId,options) { alert('GLOBAL partial refresh COMPLETE for "' + refreshId + '" event has been called') });
 *  dojo.subscribe('/xsp/partialRefresh/error', function(method,form,refreshId,options) { alert('GLOBAL partial refresh ERROR for "' + refreshId + '" has been called') });
 *
 *  // For element specific watching
 *  // assumes we have a page with an in the root
 *  dojo.subscribe('/view:_id1:myPanel/partialRefresh/init', function(method,form,refreshId,options) { alert('LOCAL partial refresh INIT for "' + refreshId + '" has been called') });
 *  dojo.subscribe('/view:_id1:myPanel/partialRefresh/start', function(method,form,refreshId,options) { alert('LOCAL partial refresh START event for "' + refreshId + '" has been called') });
 *  dojo.subscribe('/view:_id1:myPanel/partialRefresh/complete', function(method,form,refreshId,options) { alert('LOCAL partial refresh COMPLETE event for "' + refreshId + '" has been called') });
 *  dojo.subscribe('/view:_id1:myPanel/partialRefresh/error', function(method,form,refreshId,options) { alert('LOCAL partial refresh ERROR event for "' + refreshId + '" has been called') });
 *
 *  //... do some refreshing ... see the alerts...
 *
 *  // Temporarily Disable the hook
 *  window.xspHook.disableXSPHooks();
 *
 *  // ... do some refreshing ... see no alerts ...
 *
 *  // Re-eanble the hook
 *    window.xspHook.enableXSPHooks()
 *
 *  // ... do some refreshing ... alerts are back ...
 *
 *  // Destroy the object, and disable the hook
 *    xspHooks.destroy()
 *
 *  // ... do some refreshing ... see no alerts ...
 *
 *});
 */

You can download the full source code from my blog.



1 responses to Reusable Javascript Class to Publish Global and Element Specific Partial Refresh Events (init, onStart, onComplete, onError)

Russell Maher, May 7, 2010 10:19 PM

Incredibly useful piece of code! Thanks for taking the time to share it and describe how this was put together.