Search

What the Quote?

"So it's a little like 'E.T.', if E.T. was eating people."

Chris Toohey

"Spain used to be all powerful. Now they just nap all the time."

Laura Tripcony

"Yeah, fight the power... be an exponent opponent."

Tim Tripcony

« refactoring | Main| yet another reason 8.5.2 will rock »

refreshing more than one target ID in a single partial refresh event

Category xpages
 Since several folks have now asked me the same question, I'll go ahead and ask it here... and then answer it:

Q: Is it possible to refresh more than one target ID during the same server-side event?

A: Yes. Yes it is.

Assuming you're now running version 8.5.1 of Domino or above (such as a DP code drop or managed beta of 8.5.2), there are three properties available to every server-side event that were not originally available in 8.5.0:
  • onStart
  • onComplete
  • onError
Each of these properties is a String, and represents the body of a client-side JavaScript function that will be executed (respectively) before the beginning of, upon successful completion of, or when an error occurs during, the Ajax call associated with the event to which they are bound. In other words, they allow you to specify what should occur before or after the primary event, and what should happen if it fails.

In addition, a client-side script file that always loads with every rendered XPage (as opposed to an agent-style XPage) defines the following method:

XSP.partialRefreshPost

This method accepts two arguments: the first is the client-side ID of the element to be refreshed - not the element itself, the value of the element's ID attribute in the rendered HTML; the second argument is optional, and I'll discuss it more in a moment. First, let's take a look at a "real world" scenario where you might actually want to refresh multiple target elements during the same event.

Suppose your application contains an outline comprised of several links, each of which alters what displays in the main content pane via a server-side onClick event handler. Assuming you want this to be a partial refresh event, naturally you'll need to specify the main content pane as the refresh ID for the event. Suppose, however, that you also want the link the user clicked to visually indicate which portion of the interface they're now viewing (perhaps the text of the link will be bold, or its background color will change)... naturally you'll need to specify the outline pane as the refresh ID... except the content pane is already the refresh target. Not to worry... simply trigger a client-side initiation of a partial refresh for the outline pane in the onComplete of the event targeting the content pane:

XSP.partialRefreshPost("#{id:outlinePane}");

Hence, the event itself updates the main content pane, but the moment it's finished, a second Ajax call is sent to the server to retrieve an updated version of the outline pane: two birds, one stone.

And yes, before you ask, the XSP object also has a partialRefreshGet method. It takes the same arguments and behaves identically to the post method, except that it does not send the current client-side page state to the server; it simply asks that the contents of the specified component be recalculated and sent back to the browser. Ergo, it will typically be faster than a post, but may not take into account any changes to field values since the last time that component was rendered. In this scenario, however, the event to which the secondary refresh is bound will have posted the page state anyway, so a get will often achieve the same result as a post but with slightly less network traffic.

Speaking of taking the same arguments, I mentioned earlier that each of these methods accepts a second optional argument; this argument is a JavaScript object that can contain one or more of the following properties:
  • onStart
  • onComplete
  • onError
Yes, this is where you can again define what happens before or after the refresh event, or respond to an error condition. So, if refreshing two target components at once isn't enough to satisfy you, you could always do something thoroughly wacky... for example:
  1. XSP.partialRefreshGet("#{id:div1}", {
  2.     onComplete: function() {
  3.         XSP.partialRefreshGet("#{id:div2}", {
  4.             onComplete: function() {
  5.                 XSP.partialRefreshGet("#{id:div3}", {
  6.                     onComplete: function() {
  7.                         XSP.partialRefreshGet("#{id:div4}");
  8.                     }
  9.                 });
  10.             }
  11.         });
  12.     }
  13. });

But that's starting to get a bit silly... at that point you might as well just make it a "No Update" event - which is a total misnomer, by the way: a "No Update" event is actually the exact opposite of what it looks like; it updates everything. So it's basically a partial refresh without a specific target component: it still loads via Ajax, so it's not a full page reload, but it updates the entire page.

Comments

Gravatar Image1 - Most excellent. Thanks for sharing!

Gravatar Image2 - Thanks Tim. I am using 8.5.1 and cannot find these properties. I could write them directly into the XML source however I would expect to see them in the Designer. They are not in the Help. Am I missing something under my nose? This would be no surprise to my wife. Emoticon

Gravatar Image3 - I was aware of the XSP.partialrefreshPost, but didn't know about the second parameter yet. Cool stuff.

What I really like about XPages is that there are so many digged possibilities, I feel I can dive into XPages for years and I will always find something new.

Gravatar Image4 - BTW I added an article about this stuff to xpageswiki.com and set a link to your blog post. Emoticon

Gravatar Image5 - Thanks, Julian... and you've hit on my favorite aspect of XPages: the framework itself is huge, offering so much functionality we never had access to before, but it's also a window into a whole world of possibility - literally anything that is possible in server-side Java can now happen on Domino.

@Bruce, once you've defined the event handler for the control, expand that control's node in the Outline (lower left) and you'll see "Event handler" appear as a child node of the control. Select that node and the properties pane will include the on* properties. That's perhaps one unfortunate corollary to the abundance of possibility in XPages: there's just so much available that most of it is a bit tucked away, so the only way to know it's there is to go spelunking through everything looking for these hidden gems, or find out about it from others who already have.

Gravatar Image6 - Hi Tim, I have been out of Notes development for awhile and was looking to get back into it again with Xpages. Your article was of interest in regards to multiple targets as it was one of the first things I was running up against thinking about the design etc.

However it looks to me like the partial refresh is broken on even basic controls for a SINGLE refresh target. Appreciate your input as a sanity check because my initial xp is the partial refresh isn't usable at this point for keyboard entry etc. I'm was thinking maybe I have a virus/spyware or something but the problems only start manifesting after partial refreshing so that seems unlikely at this point.

I have just installed the free designer for 8.5.1. Is it possible that I need a full domino server to test partial refreshes and the local preview is causing the problem? Any insight in this area based on your xp would be appreciated?

I'm evaluating so buying the full server wasn't really an option at this point.Unfortunately If I can't find some reasonable explanation/solution it will pretty well end Domino as an option.

The Problem. Controls like combo boxes stop responding properly to the keyboard if they are the target element in a partial refresh. I can't select items with down arrow etc, tab in and out reliably. Makes things like cascading lookups for data entry pretty much useless. If I don't make them a target then I don't see any problems.

It's different behaviour under FF 3.6 and IE 7. FF 3.6.2 is really broken while IE7 isn't as bad but still not acceptable.

In short it looks like the user needs to "reset" the target control by selecting with the mouse before the keyboard kicks back in and the control operates as expected.

Anyone else feel free to jump in with thoughts.

Post A Comment

:-D:-o:-p:-x:-(:-):-\:angry::cool::cry::emb::grin::huh::laugh::lips::rolleyes:;-)