One of many things I miss in XPages is the possibility to dynamically bind multiple event listeners per document event (e.g. querySaveDocument). You can dynamically bind a single document event quite easy.

The problem with the above code, is that if someone puts querySaveDocument code in the XPage you're setting the above event, that code is overwritten/ignored.

I've written some Server Side JavaScript that lets you queue multiple SSJS actions on querySaveDocument and on postSaveDocument. The other document-events seem to be initiated before beforePageLoad, so you can't add additional code to those dynamically.

Adding an action works like this:

Check to see if the page has an embedded event handler

If yes, store the method binding for the event in a viewScope-variable

Add action to an ArrayList inside a scoped variable

Overwrite the event handler so that it calls a method that runs the embedded event handler + the queued actions

When the event runs:

If there was an embedded event handler for the event in the page, run this

Test the result of the event handler. If result === false -> don't run the queued actions, as they may interfere with the intended flow of events

Why would you want to bind events dynamically?

In an XPages application I'm working on, I've made a custom control that's similar to a "prevent save conflicts" custom control I wrote about a in my blog a little while back.

The difference between the one I posted, and the one in the application is that it uses a custom field on the document. The field is used to test if the document has been modified by a user. When a user saves a document, the field value is set to @Now().

The custom control I wrote about earlier uses the "@Modified-value" that's set whenever a document is modified.

The custom control in the application I'm working on dynamically adds a little querySaveDocument code so that the modified-by-user field is set when the document is saved. This code has to work alongside existing code in the querySaveDocument-event.