Event handling
Event propagation
XBL promotes a strong encapsulation of data and behavior. In particular events which target elements within the component typically are invisible to the component user:
Events flow along XBL scopes:
An event flowing inside the component is not visible from outside the component.
An event flowing outside the component, including within content copied with
xbl:content
is not visible from inside the component.
For special use cases like
fr:error-summary
, phantom handlers are introduced.DOMFocusIn
andDOMFocusOut
follow the behavior outlined in XForms - Focus.
Component user: attaching event handlers to the bound node
By default, you get the same behavior you have with built-in controls, like xf:input
.
Event handlers can directly observe elements with XBL bindings:
The action handler above observes events going through element <foo:bar>
, assuming <foo:bar>
has an XBL binding.
Similarly, the following observes events targeted directly to <foo:bar>
:
Note that to achieve this the XBL engine does some special work here:
it recognizes those nested handlers
it attaches them to the bound node
it hides them from the component's
xbl:content
processing
NOTE: However these handlers are still visible from XSLT processing when using xxbl:transform
You can disable this automatic processing of nested event handlers, although you should only need this for very special components:
It is also possible to attach handlers by id, like with any XForms control:
NOTE: Only standard XForms controls and elements which have an XML binding can be used as event observers. Other elements, such as an HTML <div>
, cannot be event observers.
Component user: nested content under the bound node
Some components, such as a tabview, in effect behave like XForms grouping controls (like xf:group
, xf:switch/case
, xf:repeat
). With such components, a lot of content is typically nested under the bound node:
It is up to the component author to handle nested content properly. When using xbl:content
, the XBL engine does the work for you:
the nested content is automatically visible from the "outside" of the component
ids and variables are visible across the bound node (here
fr:tab
)
events flow nicely as the form author would expect when using a regular XForms grouping control
Component author: hooking-up creation and destruction event handlers
You can use the xforms-model-construct-done
event on local models. This event is dispatched when the component is being initialized. This event can be dispatched multiple times to a given component during a form's lifecycle, as the component is initialized each time it becomes relevant.
As is the case for top-level models, when xforms-model-construct-done
is dispatched, UI controls are not present yet. So you cannot reach controls from action handlers responding to that event.
[UNTIL Orbeon Forms 4.9 included]
xforms-ready
is not dispatched to local models. Here is how you can register handlers to perform initializations when the component is created and destroyed:
Note the ev:target
attributes, which ensure that only events actually targeting this particular group are handled. If you omit that attribute, you might observe more than one event for creation or destruction, which is in general not desired.
[SINCE Orbeon Forms 4.10]
xforms-ready
is dispatched to XForms models nested within the component. Specifically, xforms-ready
is dispatched when the component receives the xforms-enabled
event during a refresh. This event can be dispatched multiple times to a given component during a form's lifecycle, as the component is initialized each time it becomes relevant.
As is the case for top-level models, when xforms-ready
is dispatched, UI controls are present.
Component author: dispatching events from within the component
This allows a component to send information to the outside world.
A component can dispatch events to its bound element by using xf:dispatch
and using the id of the xbl:binding
element as target.
Example:
The component user can listen to this event as expected, for example:
The use of the my:
prefix in the event context information is not mandatory, but if a prefixed is used a namespace mapping must be in scope. It is good practice to use a prefix so as to prevent name conflicts with standard XForms event context information.
Component author: listening for events dispatched to the component
This allows a component to receive information from the outside world.
You can register event handler attached to the bound node inside your component with the xbl:handlers/xbl:handler
elements:
The xbl:handler
element looks very much like an xf:action
element. In particular, it supports the following attributes:
event
: specifies which event(s) to listen to.NOTE: Like for
ev:event
, Orbeon Forms supports as an extension a list of space-separated event names.phase
: whether to call the handler upon thecapture
,target
, orbubble
phase.
The xbl:handler
element can contain one or more XForms actions.
Component user: dispatching events to the component
The following example responds to a button being activated and dispatches an event with custom context information to an fr:bar
component:
When the event my-event
reaches the component, it activates the event handler registered with xbl:handler
. That handler has access to the custom context information using the event()
function.
Event handlers are attached to the bound node but they execute within the context of the component, which means that they have access to XForms elements declared within the component. This includes:
xf:model
elements declared withinxbl:implementation
xf:model
elements declared withinxbl:template
controls declared within
xbl:template