XPages Developer
Interests: Developing web and mobile apps
Skills: JavaScript, HTML, CSS, Java, Dojo, jQuery, IBM Lotus Notes and Domino, iWidgets, OpenSocial, Activity Streams
Location: Everywhere
Hobbies: Writing great code that helps people and businesses get stuff done. Love pizza, good music, good friends and beach combing.
Subscribe via FeedTommy Valand, Mar 18, 2010 3:52:14 PM
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.
In beforePageLoad:
var application = facesContext.getApplication();
var methodBinding = application.createMethodBinding( '#{javascript:yourCode}', null);
// get(0) -> The first data source in the page
view.getData().get(0).setQuerySaveDocument( methodBinding );
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
- Execute all the actions in the queue
Example usage (beforePageLoad):
Events.addToDocumentEvent( 'querySaveDocument', 'xspTestDoc.setValue( "description", "Overridden" )' );
Add the events in the beforePageLoad on the page.
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.
2 responses to Dynamically binding multiple querySave/postSave actions
Tommy Valand, May 8, 2011 4:12 PM
Fixed. Thanks for letting me know.
Dominik Myszkowski, May 8, 2011 9:48 AM
You have a syntax error in script. Parameter "dataSourceId" is written as "datasourceId" in the body of function "addToDocumentEvent".