Triggering an EventHandler from Another Button

Home » Triggering an EventHandler from Another Button

Today there was a question on StackOverflow about how to trigger an eventHandler of control A from control B. I knew I’d done it before, but couldn’t remember where and couldn’t find where I’d blogged on it. So here is the way I originally did it and the better way.

The Padawan’s Way

Once you start going to the source pane, you see much more than you do in the Design pane. One of those things you see is that you can click on an xp:eventHandler component and you see a completely different set of properties. One thing you see is that you can add an id to an eventHandler. You can also see you can copy and paste the eventHandler as a child of the xp:view tag, so adding events where you can’t normally (i.e. through Design pane and Events tab) add events. None of this is usually relevant. But think: an eventHandler is for a specific event, e.g. onclick, onchange etc.; if you could get a handle on the eventHandler, maybe you could programmatically trigger it!

So the way I’ve done it before is to have an eventHandler at the top of my page. You can use getComponent() in the normal way to access that eventHandler. Then you call myEventHandler.getAction().invoke(facesContext, null) to trigger it. And the eventHandler can be run from a completely different component.

The second parameter there is the component to invoke the eventHandler against. You shouldn’t ever  need to do that because if you listened to Tim Tripcony, you always go to the data model, not the component for values.

The other point to bear in mind is that if you use parameters for your eventHandler, it uses the parameters of the event that initially triggers the partial refresh, not the parameters set on the eventHandler being invoked. (Event parameters are outside the scope of this blog post.)

The Master’s Way

That’s how I’d advised to do it originally. But that was before Tim made me understand about component binding. With component binding, we have a way to access the component without needing to resort to setting the id and without needing to use getComponent. That means it’s going to be easy to use from Java as well as being quicker if you’re using it from SSJS.

The slightly challenging part (thanks, Jesse Gallagher, for educating me) is that components are not serializable. So you can’t store them in something like viewScope or in a bean property unless that property is set to transient. The good thing is you don’t need to: they’re loaded before the beforePageLoad event runs and reloaded, on a partial refresh, during the Restore View phase (so before youo ever need them).

So, you can use binding and trigger the component from absolutely anywhere on the page. As an example that should be understandable by all XPages developers, you can look at the attached standalone XPage. I set the binding to #{requestScope.setYes} on the first button’s eventHandler. Then in the eventHandler for the third button I access that first eventHandler via requestScope.get("setYes"); and trigger it. Quicker, easier, more flexible!

eventHandler_bindings

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top