Events in XForms
The event model of XForms is based on the
Document Object Model (DOM) Level 2 Events specification. This is the same specification that defines how your web browser handles events in HTML documents. This is good news because it means that his knowledge is reusable between XForms and HTML/JavaScript development!
What's new with XForms is that it allows users to declaratively register event handlers following the
XML Events specification. If you write HTML and JavaScript code running directly in your browser, you would typically register event handlers using JavaScript APIs. In XForms, which does not mandate JavaScript, XML Events provide a declarative alternative to using JavaScript. This usually makes it clearer how listeners are attached to XForms objects.
Status of the specifications
The XML Events specification dates from 2003 and was based on DOM Level 2 Events, which itself dates back to 2000.
Since then, refinements have taken place in the DOM Level 3 Events specification (
currently a working draft). The
XBL 2 specification also proposes a syntax for declarative event handlers.
There are differences between these specifications, in particular with regard to how events phases are defined hand how handlers can specify event phases.
- DOM Level 3 Events nicely clarifies the different event phases (capture, target, and bubbling).
- XML Events 1
phase="default" attribute means a listener is activated on the target or bubbling phase.
- XML Events 1 does not support activating an event strictly on the
target or bubbling phase.
- XBL 2 adds a default action phase separate from the
target or bubbling phases.
- XBL 2 proposes
capture, target, bubble, default-action, and unspecified values for the phase attribute. If unspecified, this means the target or bubbling phase.
- XML Events 2 is being developed but is still a working draft
Orbeon Forms support
Registering event handlers
[TODO: basic placement and ev:event support]
Using the ev:observer and ev:target attributes
The ev:observer attribute
allows you to register
event handlers by specifying an element identifier, instead of embedding
the event handler
within that element. This is particularly useful to register event
handlers on
<xforms:instance> elements, which do not allow you to
directly embed XML event
handlers.
<xforms:model id="main-model">
<!--
Child instance -->
<xforms:instance id="child-instance" src="my-instance.xml"/>
<!--
Register the event handler on the child instance -->
<xforms:dispatch ev:observer="child-instance" ev:event="xforms-insert" targetid="main-model" name="update-after-insert"/>
</xforms:model>
Note that you still need to use the ev:event attribute to
specify to what event the
handler responds. The following example shows how you can define event
handlers for XForms
elements anywhere in an XForms document:
<xhtml:html>
<xhtml:head>
<xforms:model id="my-model">
<!-- A small instance -->
<xforms:instance id="my-instance">
<instance>initial</instance>
</xforms:instance>
<!-- Event handler located in the model but observing an element in the view -->
<xforms:action ev:observer="my-group" ev:target="my-input" ev:event="DOMFocusIn">
<xforms:setvalue ref=".">new</xforms:setvalue>
</xforms:action>
</xforms:model>
</xhtml:head>
<xhtml:body>
<xforms:group id="my-group">
<!-- A simple XForms input control -->
<xforms:input id="my-input" ref=".">
<xforms:label>My Data</xforms:label>
</xforms:input>
<!-- Event handler located in the view but observing an element in the model -->
<xforms:action ev:observer="my-model" ev:event="xforms-ready">
<xforms:dispatch name="DOMFocusIn" targetid="my-input"/>
</xforms:action>
</xforms:group>
</xhtml:body>
</xhtml:html>
The above example also shows how you can constrain an event handler to
respond to an event
dispatched to a particular target element using the ev:target
attribute. here, the
event handler responds to DOMFocusIn events, but only those
dispatched to the
my-input control.
The ev:propagate attribute
[TODO: describe]
The ev:defaultAction attribute
[TODO: describe]
Top-level event handlers
Since late January 2010 builds, you can place event handlers at the top-level under the
<xhtml:body> element:
<xhtml:body>
<xxforms:variable name="answer" select="42"/>
<xforms:setvalue ev:event="my-event" ref="value" value="$answer"/>
...
</xhtml:body>
Previously, you had to use a top-level
<xforms:group> for this to work:
<xhtml:body>
<xforms:group>
<xxforms:variable name="answer" select="42"/>
<xforms:setvalue ev:event="my-event" ref="value" value="$answer"/>
...
</xforms:group>
</xhtml:body>
You can also explicitly register top-level handlers using the
#document observer id:
<xforms:setvalue ev:observer="#document" ev:event="my-event" ref="value" value="$answer"/>
NOTE: Events from top-level models do not bubble to handlers observing on #document. Arguably, they should!
Event handlers on XBL bound nodes
When using an XBL component, you can register handlers in the same way you register handlers on built-in XForms controls.
In this case, the handler is placed directly under the bound node (<fr:foo>):
<fr:foo id="my-foo">
<xforms:setvalue ev:event="my-event" ref="my-value">43</xforms:setvalue>
</fr:foo>
Event handlers with the ev:observer attribute are also recognized as long as the handler is directly under the bound node:
<fr:foo id="my-foo">
<xforms:setvalue ev:event="my-event" ev:observer="my-input" ref="my-value">43</xforms:setvalue>
</fr:foo>
<xforms:input id="my-input" ref="my-value"/>
NOTE: For event handlers nested further within the bound node, the behavior is up to the XBL component. Typically, components that are containing controls, such as <fr:tabview>, manage event handlers as you expect!
Event handlers within XBL bindings
Event handlers on XBL bindings are very similar to regular XML Events handlers, except:
- they use the
<xbl:handler> containing element placed within the <xbl:handlers> section of an XBL
binding
- attributes do not use the XML Events namespace (typically with the
ev: prefix)
- the XBL 2
default-action attribute is not supported but instead the XML Events 1 defaultAction is supported (both support the value cancel and perform values)
Example:
<xbl:handlers>
<xbl:handler event="xforms-focus" phase="target" defaultAction="cancel">
<xxforms:script id="xf-sf">YAHOO.xbl.fr.Currency.instance(this).setfocus();</xxforms:script>
</xbl:handler>
</xbl:handlers>
The ev:handler attribute
[TODO: not supported by Orbeon Forms as of 2010-01]
The <ev:listener> element
[TODO: not supported by Orbeon Forms as of 2010-01]
The keypress event
You can, by listening to the keypress event, run actions as users type a certain key combination. Your listener can be registered on:
- The whole document, in which case it will run whenever users press the key combination you specified. You can register a listener on the whole document either by declaring you listener directly under the
xhtml:body as in:
<xforms:action ev:event="keypress" xxforms:modifiers="Control" xxforms:text="y">
...
</xforms:action>
Or you can declare it anywhere in your form with an observer set to #document, as in:
<xforms:action ev:event="keypress" ev:observer="#document"
xxforms:modifiers="Control" xxforms:text="y">
...
</xforms:action>
- Part of the document, in which case you set your actions to listen on a XForms control such as a
xforms:group or an xforms:input. Note that in this case, your listener will be called only if a form control (either the one you have specified, or form control inside the one you have specified for container form controls) has the focus when users press the key combination.
- A dialog, in which case your listener will be called only when users press the key combination while the dialog is open. In this case, the only requirement for the listener to be called is for the dialog to be open; the focus does not necessarily need to be on a form control inside the dialog.
You specify what key stroke you want to listen to with the following two attributes:
xxforms:text specifies the key you want to listen to. This attribute is mandatory: if you have a ev:event="keypress" on an action, then you need to specify an xxforms:text.
xxforms:modifier specifies what key modifier needs to be pressed in addition to the key. This is a space separated list of values, where the values can be Control, Shift, and Alt. This attribute is optional: leave it out to listener to a key press with no modifier.
Orbeon Forms extensions
Creating keyboard shortcuts
In some cases, you want your form to react to users pressing certain key
combination by running XForms actions. Typically, this allows you to define keyboard shortcuts for operations that would otherwise
require using the mouse or require many keystrokes.
You declare a listener on a certain key combination with:
<xforms:group id="my-group">
<xforms:action ev:event="keypress"
xxforms:modifiers="control"
xxforms:text="y">
<!-- Runs when an element inside my-group has the focus, and ctrl-y
is pressed -->
</xforms:action>
</xforms:group>
- The
attributes
modifiers and text are borrowed
from XBL where they are defined on the xbl:handler
element. In time they could become part of XML Events. The supported
values of modifier are shift, alt, and control
(from the DOM Level 3 events specification but in lowercase,
to follow XBL 2).
- When you declare a listener on
keypress, you must specify
the key with xxforms:text and can optionally indicate a
modifier with xxforms:modifiers.
A
keypress listener can be active:
- For the whole document, if it has
ev:observer="#document" on the listener.
- For a given dialog, if your listener is declared directly under the
<xxforms:dialog> or has an ev:observer pointing to that dialog.
- For only a section of the document. For instance, in the above example
the listener is active only if the key is pressed while a form element
inside that group has the focus. In most cases, you'll rather want the listener to be active for the whole document or for a specific dialog.
Filtering on the event phase
XML Events 1 only supports filtering event handlers on a subset of the DOM Level 2 Events phases. Orbeon Forms extends that behavior and supports registering handlers that match on one of the 3 main event phases specified by DOM Level 2 Events:
capture,
target, and
bubbling.
As of January 2010, Orbeon Forms supports the following values for the
ev:phase attribute:
capture: only activate the handler during the capture phase (this is compatible with all the specifications)
default or unspecified: only activate the
handler during the target or bubbling phase (this is compatible with XML
Events 1 but not included in the current XBL 2 proposal)
target: only activate the handler during the target phase (this is not present in XML Events 1)
bubbling: only activate the handler during the bubbling
phase (this is not present in XML Events 1)
NOTE: In the future, the XBL 2 default action phase could be integrated if considered desirable. It is hoped that the target and bubbling values will be supported in XML Events 2.
NOTE: In most cases, the ev:phase attribute can be omitted, in which case
the target or bubbling phase is matched.
This allows placing a handler directly within a target element, or any
of its ancestors, which are the most common use cases in XForms.
Enhanced event() function support
Orbeon Forms enhances the XML Events event() function to
take a qualified name as
parameter:
event($attribute-name as QName)
item()*
This allows namespacing attribute names, therefore better allowing for
extension attributes.
The following standard event attributes are implemented:
[TODO: describe standard Orbeon Forms support for event() function]
On all events, the following extension attributes are supported:
-
event('xxforms:type') as xs:string
Return the event type (also known as event name), for example "DOMActivate".
-
event('xxforms:targetid') as xs:string
Return the static id of the event target (event('xxforms:target')
is supported for backward compatibility).
-
event('xxforms:absolute-targetid') as xs:string
[SINCE 2012-07-10]
Return the absolute id of the event target.
-
event('xxforms:observerid') as xs:string
[SINCE 2012-05-18]
Return the static id of the event observer.
-
event('xxforms:absolute-observerid') as xs:string
[SINCE 2012-07-10]
Return the absolute id of the event observer.
-
event('xxforms:bubbles') as xs:boolean
Return whether the event is allowed to bubble or not.
-
event('xxforms:cancelable') as xs:boolean
Return whether the event is cancelable or not.
-
event('xxforms:phase') as xs:string
The current event phase: capture, target, or bubbling.
-
event('xxforms:repeat-indexes') as xs:string*
Return the event target's current repeat indexes, if any, starting from
the ancestor
repeat.
-
event('xxforms:repeat-ancestors') as xs:string*
Return the event target's ancestor repeat ids, if any.
-
event('xxforms:target-prefixes') as xs:string*
Return the event target's id prefixes, if any, starting from the
ancestor components. This
will be empty unless the target is within an XBL component.
On all UI events (DOMActivate, DOMFocusIn, DOMFocusOut,
xforms-select, xforms-deselect, xforms-enabled,
xforms-disabled, xforms-help, xforms-hint,
xforms-valid, xforms-invalid, xforms-required,
xforms-optional, xforms-readonly, xforms-readwrite,
xforms-value-changed), the following extension attributes
are supported:
-
event('xxforms:control-position') as xs:integer
Return the event target's position in the user interface. This is the
control's static position,
i.e. this does not reflect possible repeat iterations.
-
event('xxforms:binding') as node()?
Return the event target's single-node binding if any.
-
event('xxforms:label') as xs:string?
Return the event target's label value if any.
-
event('xxforms:hint') as xs:string?
Return the event target's hint value if any.
-
event('xxforms:help') as xs:string?
Return the event target's help value if any.
-
event('xxforms:alert') as xs:string?
Return the event target's alert value if any.
On xforms-select, the following extension attributes are
supported:
On xforms-submit-serialize, the following extension
attributes are supported:
-
event('xxforms:binding') as node()?
Return the submission's single-node binding if any.
-
event('xxforms:serialization') as xs:string
Return the submission's requested serialization, e.g. application/xml,
application/x-www-form-urlencoded, etc..
Enhanced <xforms:dispatch> support
Orbeon Forms supports passing event context attributes with the <xxforms:context>
child element. The actions supported are actions which directly cause an
event to be dispatched:
-
<xforms:dispatch>
-
<xforms:send>
-
<xxforms:show>
-
<xxforms:hide>
Here is how you pass context attributes when executing an action:
<xforms:dispatch name="rename-control"
target="my-model">
<xxforms:context name="control" select="my/control"/>
<xxforms:context name="control-name" select="'beverage-selection'"/>
</xforms:dispatch>
<xxforms:context> supports the following two
attributes:
name |
Mandatory |
Name of the context attribute.
Note that the context attribute name cannot be a qualified name (QName),
because this would
not be compatible with DOM 2
Events. However, a QName can be used as custom event name.
In order to avoid confusion with standard XForms names, we recommend you
use prefixed names
if you use custom context information with standard event names (when
supported). However,
with custom event names, prefixing is not necessary.
|
select |
Mandatory |
XPath 2.0 expression determining the value of the context attribute.
|
Context attribute passed this way can be retrieved using the event()
function:
<xforms:action ev:event="rename-control">
<xforms:setvalue ref="event('control')/@name" value="event('control-name')"/>
</xforms:action>
NOTE: At the moment, with, <xforms:dispatch>, only custom
events support passing
context attributes this way. Built-in events, such as xforms-value-changed,
or
DOMActivate, ignore nested <xxforms:context>
elements.
Enhanced support for xforms-select and xforms-deselect
[TODO: describe support for these events on xforms:upload]
Targeting effective controls within repeat iterations
The following actions all support attributes resolving to a particular
control:
-
<xforms:dispatch> (target attribute)
-
<xforms:setfocus> (control attribute)
-
<xforms:toggle> (case attribute)
-
<xxforms:show> (neighbor attribute)
When that control is within a repeat iteration, the actual control
targetted is chosen based on the
current set of repeat indexes. However, in some cases, it is useful to
be able to target the control
within a particular iteration. This is achieved with the xxforms:repeat-indexes
extension attribute on these actions. This attribute takes a
space-separated list of repeat
indexes, starting with the outermost repeat. Example:
<!--
Repeat hierarchy -->
<xforms:repeat nodeset="todo-list">
<xforms:repeat nodeset="todo-item">
<xforms:switch>
<xforms:case id="edit-case">...</xforms:case>
<xforms:case id="view-case">...</xforms:case>
</xforms:switch>
</xforms:repeat>
</xforms:repeat>
<xforms:trigger>
<xforms:label>Toggle Me!</xforms:label>
<!-- Toggle the case
within the 5th todo item of the 3rd todo list -->
<xforms:toggle ev:event="DOMActivate" case="edit-case" xxforms:repeat-indexes="3 5"/>
</xforms:trigger>
Multiple event names, observers and targets on event handlers
The ev:event, ev:observer and ev:target
attributes,
defined by the XML Events
specification, only
support one event name, observer, or target respectively. Orbeon Forms
supports as an extension
a list of space-separated values. The behavior is as follows:
-
For ev:event: the handler is called if any of the specified
events matches.
<xforms:action ev:event="DOMFocusIn DOMFocusOut">
<!-- Reacting to either the "DOMFocusIn" and
"DOMFocusOut" events -->
...
</xforms:action>
-
For ev:observer: the event handler is attached to all the
observers
specified.
<xforms:action ev:event="DOMActivate"
ev:observer="my-input my-trigger">
<!-- Observing both the "my-input" and
"my-trigger" controls -->
...
</xforms:action>
-
For ev:target: the handler is called if any of the
specified targets
matches.
<xforms:action ev:event="xforms-submit-done"
ev:target="create-submission update-submission">
<!-- Checking that either the
"create-submission" and "update-submission" controls is a target -->
...
</xforms:action>
The extensions above have been requested
for inclusion in XML Events 2.
Catching all events
The special #all event name on ev:event can be used to
catch all events:
<xforms:group>
<!--
Stop propagation of all events -->
<xforms:action ev:event="#all" ev:propagate="stop"/>
...
</xforms:group>
Specifying the current observer as target restriction
The special #observer target name on ev:target can be
used to specify that the listener must be activated only if the event target is the listener's observer:
<xforms:group>
<!-- Restrict activation to events dispatched to the group -->
<xforms:action
ev:event="my-event"
ev:target="#observer"/>
...
</xforms:group>
In this example, this is identical to:
<xforms:group>
<!-- Restrict activation to events dispatched to the group -->
<xforms:action
ev:event="my-event"
ev:phase="target"/>
...
</xforms:group>
Observing the preceding sibling element
[SINCE 2012-05-18]
The ev:observer attribute can be set to the value #preceding-sibling:
<xforms:repeat ref="...">
...
</xforms:repeat
<xforms:action
ev:event="xforms-enabled xforms-disabled xxforms-index-changed xxforms-nodeset-changed"
ev:observer="#preceding-sibling"
ev:target="#observer">
</xforms:action>
In this example, we observe events targeted to the repeat element just before the event handler.
This is useful in situations where it is not possible to explicitly set an id on a control, for example when doing complex things with XBL.
Phantom handlers
[SINCE 2012-06-08]
Event handler support the xxforms:phantom="true" attribute to specify that the event handler is listening to events flowing across XBL scopes.
Starting Orbeon Forms 4 and builds since 2012-06-08, XForms events flow along XBL boundaries and are fully encapsulated. This attribute allows special consumers of events to have a global view of events flowing in the XForms page. Example:
<xforms:action
ev:observer="my-observer"
ev:event="xforms-enabled"
xxforms:phantom="true">
In this example, the handler will catch events that happen not only in the current XBL scope, but also those in nested XBL scopes.
This is an advanced feature and should be used wisely. As of 2012-06-08, it is used in Orbeon Forms by the error summary (fr:error-summary) and by Form Builder.
Orbeon Forms extension events
xxforms-nodeset-changed
Dispatched in response to: node-set changed on
<xforms:repeat>
Target:
<xforms:repeat> element
Bubbles: Yes
Cancelable: Yes
Context Info:
event('xxforms:from-positions')
as xs:integer*: previous positions of all the iterations that
moved
event('xxforms:to-positions')
as xs:integer*: new positions of all the iterations that moved,
in an order matching event('xxforms:from-positions')
event('xxforms:new-positions')
as xs:integer*: positions of all newly created iterations
The xxforms-nodeset-changed event allows you to
detect changes to a repeat node-set:
- Nodes
added to the nodeset, unless the nodeset was empty
- Nodes removed from the nodeset, unless the nodeset becomes empty after the removal
- Nodes
reordered
This event is not dispatched when the repeat control becomes relevant or non-relevant. (A repeat control is considered non-relevant if its node-set is empty.)
Example:
<xforms:group>
<xxforms:script ev:target="my-repeat" ev:event="xxforms-nodeset-changed xforms-enabled xforms-disabled">
alert("Nodeset
changed!");
</xxforms:script>
<xforms:repeat nodeset="record" id="my-repeat">
...
</xforms:repeat>
</xforms:group>
In
this example:
- The
ev:target
attribute ensures that this particular handler only catches events for my-repeat, in case
there are some nested repeats or some other repeats within the group.
- The
ev:event attribute lists not only xxforms-nodeset-changed event, but also the xforms-enabled and xforms-disabled event so the event runs when the nodeset goes from empty to non-empty or from non-empty to empty.
We recommend that you put the handler for xxforms-nodeset-changed outside the <xforms:repeat> element, as shown in the example above. This ensures that, in case the repeat node-set becomes empty, actions associated with your event handler will still execute within a non-empty XPath context.
If nodes related to a repeat are inserted with xforms:insert or xforms:delete
(including instance replacement upon submission), you could detect changes to the repeat node-set with XForms 1.1 using xforms-insert and xforms-delete events
on instances. However these events are harder to use in this scenario,
and will not catch situations where the repeat nodeset changes without
insertions / deletions.
Currently, we interpret handlers placed directly within <xforms:repeat> as being attached to a particular repeat iteration, not to the repeat element itself. This means you can write things like:
<xforms:repeat nodeset="value"
id="my-repeat">
<xforms:action ev:event="my-event">
<xxforms:variable name="position" select="position()"/>
<xforms:setvalue ref="."
value="$position"/>
</xforms:action>
...
</xforms:repeat>
The context size is the size of the repeat nodeset, and the context position that of the current iteration. Things work as if within the repeat you had an implicit group, which is in fact now how XForms 1.1 specifies repeat.
Now the question is: what happens if you dispatch an event to <xforms:repeat> itself?
We propose the current solution:
- if an event targets
<xforms:repeat>, then instead we dispatch it to the current repeat iteration, setting the appropriate XPath context for handlers associated with the iteration
- in the case where there is no repeat iteration (empty repeat nodeset), the XPath context becomes empty
As of 2010-01 this is implemented but there is a remaining
bug associated with placing an event handler directly within
<xforms:repeat>. So we recommend putting the event handler outside the
<xforms:repeat> element as shown in the example above.
xxforms-index-changed
Dispatched in response to: index changed on <xforms:repeat>
Target: <xforms:repeat>
element
Bubbles: Yes
Cancelable: Yes
Context Info:
event('xxforms:old-index')
as xs:integer: previous index
event('xxforms:new-index')
as xs:integer: new index
The
xxforms-index-changed
event allows you to
detect changes to a repeat index.
<xforms:group>
<xforms:repeat nodeset="item" id="my-repeat">
<!-- Test handler with ev:target="#observer" -->
<xforms:action ev:event="xxforms-index-changed" ev:target="#observer">
...
</xforms:action>
</xforms:repeat>
<!--
Test handler with ev:target -->
<xforms:action
ev:event="xxforms-index-changed" ev:target="my-repeat">
...
</xforms:action>
</xforms:group>
The
xxforms-index-changed
event is not dispatched during control creation, only when the index changes. In order to obtain the index during creation, you can attach a listener for
xforms-enabled to the
<xforms:repeat>
element and use the
index() or
xxforms:index() function to obtain that repeat's initial index:
<xforms:group>
<xforms:repeat nodeset="item" id="my-repeat">
<!-- Test handler with ev:target="#observer" -->
<xforms:action ev:event="xforms-enabled" ev:target="#observer">
... use index('my-repeat') or xxforms:index() here ...
</xforms:action>
</xforms:repeat>
<!-- Test handler with ev:target -->
<xforms:action ev:event="xforms-enabled" ev:target="my-repeat">
... use index('my-repeat') here ...
</xforms:action>
</xforms:group>
xxforms-iteration-moved
Dispatched in response to: iteration containing the control has changed since the last refresh or the time the iteration was first created
Target: control element
Bubbles: No
Cancelable: Yes
Context Info: none
The
xxforms-iteration-moved event is dispatched during refresh, just after
xforms-value-changed (if dispatched).
This event is not dispatched when the repeat control becomes relevant or non-relevant.
NOTE: A repeat control is considered non-relevant if its node-set is empty.
The iteration in which a control is present can change when repeat node-sets change as a consequence of inserted nodes, for example.
This event is useful for example to run <xxforms:script> actions to update client-side data in response to moved iterations. Here is an example from the <fr:currency> implementation:
<xforms:input ref="$result">
<xxforms:script id="xf-ch" ev:event="xforms-value-changed xxforms-iteration-moved">
YAHOO.xbl.fr.Currency.instance(this).update();
</xxforms:script>
<xxforms:script id="xf-ro" ev:event="xforms-readonly">YAHOO.xbl.fr.Currency.instance(this).readonly();</xxforms:script>
<xxforms:script id="xf-rw" ev:event="xforms-readwrite">YAHOO.xbl.fr.Currency.instance(this).readwrite();</xxforms:script>
</xforms:input>
NOTE: This event doesn't bubble, so event listeners must directly observe the controls receiving the event.
xxforms-value-changed
Dispatched in response to: value changed in an instance
Target: instance
Bubbles: Yes
Cancelable: Yes
Context Info [SINCE 2012-01-05]:
event('node') as node(): element or attribute node whose value has changed
event('old-value') as xs:string: previous value
event('new-value') as xs:string: new value
The
xxforms-value-changed event is dispatched to an instance when an element or attribute value is changed in that instance, namely through the following mechanisms:
calculate or xxforms:default MIP
<xforms:setvalue> action
- value of a bound control changed by the user
- submission result with
replace="text"
Example (
also on gist.github):
<html xmlns:xforms="http://www.w3.org/2002/xforms"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns="http://www.w3.org/1999/xhtml">
<xforms:instance id="table">
<xforms:message ev:event="xxforms-value-changed" ev:observer="table">Changed!</xforms:message>
<xforms:input ref="instance()">
<xforms:label>Change me:</xforms:label>
xxforms-valid
Dispatched in response to: instance being valid after validation
Target: instance
Bubbles: Yes
Cancelable: Yes
Context Info: none
The
xxforms-valid event is dispatched to an instance after validation if it is valid.
xxforms-invalid
Dispatched in response to: instance being invalid after validation
Target: instance
Bubbles: Yes
Cancelable: Yes
Context Info: none
The
xxforms-invalid event is dispatched to an instance after validation if it is invalid.
xxforms-dialog-open
Dispatched in response to: <xxforms:show> action
Target: dialog
Bubbles: Yes
Cancelable: Yes
Context Info: none
The
xxforms-dialog-open event is dispatched to an dialog in response to running the
<xxforms:show> action targeting that dialog.
xxforms-dialog-close
Dispatched in response to: <xxforms:hide> action
Target: dialog
Bubbles: Yes
Cancelable: Yes
Context Info: none
The
xxforms-dialog-close event is dispatched to an dialog in response to:
- running the <xxforms:hide> action targeting that dialog
- the user closing the dialog with the dialog close box, if present