Saturday, May 1, 2010

XPages: Dynamically binding and unbinding server side events

Back in my early XPages career, I asked the readers if it was possible to Dynamically bind server side events.

The only answer I got was this:
The short answer: NO.
The long: it is somewhere on the list.

I don't like those kinds of answers.

After todays experiment, I can firmly say: Yes, it's possible!
This is what you'll be able to do with the simple framework provided in the demo:

  • Dynamically bind/unbind custom events

  • Bind multiple event handlers to one event

  • Run the event in a specified scope

  • Use regular HTML elements as event triggers

This started out as an experiment into Server Side Event Delegation. A couple of nights later, I further improved on the functionality.

In the slumbering stage this morning, I discovered that I was on the path for something, but not what I initially thought I had started out for. The two first experiments lead to what would have been a complex unusable blob of functionality.

Today, I did some cleanup. I removed all the class attributes, and rewrote the framework code to be more flexible. The previous two version relied on an eventHandler node in the top of the XPage, which results in a generated script tag. This implementation doesn't add any script tags to the generated html.

The server side part of the code lets you specify what to do for certain events. The client side part of the code specifies what server side event to run, what data to send to the event handler (optional), and which part of the page should be updated after the event has run.

I did a little screen capture of the demoapp in action (not visible in Google Reader):

Simple Server Side Event Delegation:
The two first buttons toggles (when active) visibility of a couple of computed fields. The third button binds/unbinds the event handler for the two preceding buttons.

Multiple Event Handlers:
The first button triggers a custom event on the server. The second button adds an event handler to the event. As you can see from the demo, for each event handler added, the addition increases by 1.

Event handler running in a specified scope:
The event handler for the event runs in the scope of an object on the server. Then the event is triggered, a viewScope variable is created from a property fetched from the object ( viewScope.put( 'theAnswer', this.theAnswer ) )

In View Edit:
When the name of the person is clicked, an "edit" event is triggered. When the ok button is clicked, a "save" event is triggered.

If you add the event handlers afterRestoreView or before-/afterRendreResponse, an event handler is added for every partial refresh. Adding them in an event handler or in the afterPageLoad event should be safe.

>> Download Demoapp

If you don't like a lot of generated server side script tags for events/embedding the event code in control after control, this is definitely worth looking at.

If you find any bugs/want more info about something, leave me a comment.

Share and enjoy!


Anonymous said...

Hi Tommy,

I have a question which is not at all related to this post. But I think you are one of the very few people out there who can guide me through this.

The image in the XPage that displays just fine on IE & Firefox doesn't show up when previewed on notes client.

The image that I am referring is coming from another database. I have the ReplicaID of that source database. So how do I construct the "src" attribute of the image to render this image correct when previewed in notes client.

The syntax "/xsp/server!!dbpath/xsp/image.gif" is not what I am looking for. Because I refer the source db with its replica id.

Also, the html of the image is given as a computed field (For your info)


Tommy Valand said...

I haven't worked on any XPages-applications in the Client, but I would think something like this would work as the src (standard html).

'/' + db.getFilePath().replace( /\\/g, '/' ) + '/image.gif'.

'/xsp/image.gif' if you have a folder structure for your image resources and the image is under xsp.

Anonymous said...

This is what I heard from Jeremy Hodge too. Thanks Tommy.

Kathy said...

Hi Tommy
I am trying to implement the in-view edit - it is exactly what I need.
I have the field editing and the update happening but
I am struggling with the refresh - no matter what I pass it.
Can you tell me what the peopleName.refresh should be refreshing - the wrapper or the view name - although I have tried these so maybe something else (another partial refresh request)that is causing the issue.

Tommy Valand said...

@Katy: Thanks for the comment. I have written a new and more flexible EventDelegator implementation (I just needed someone to nudge me to publish it). I'll write a blogpost about it with a demoapp as soon as it's done (hopefully today).

If you still have questions after you've taken a look at the new demoapp/blogpost, please leave a comment there. :)