An event, as far as XForms is concerned, is a data structure that gets passed around to certain interfaces, called event listeners. The Document Object Model (DOM) Level 2 Events specification spells out how events work. The latter part of this chapter describes specific events that are useful in XForms authoring. Each event has a target element, which represents the point where the main action is happening, from the viewpoint of a particular event. Each event also can have a default action that is effectively triggered by the event. For example, an xforms-focus event will have a form control element as a target and a default action of changing the active focus. DOM Level 2 includes a method to configure an observer, which can take a specific action in response to an event, possibly in lieu of the default action. The most common case is for the observer to attach directly to the target element. In some cases, however, an observer would like to have broader access to events, for instance to all xforms-focus events for all form controls. In this scenario, the observer is farther downstream from the event target. DOM Level 2 Events define how events "propagate" (or flow) through the DOM, as shown in Figure 7-1. Figure 7-1. Event propagationEvent propagation is divided into two phases: capture and bubbling. Capture occurs first, as the DOM root node is given the option to observe the event, then additional nodes following the path from the root to the target element. Any listener has the ability to end the propagation, or to prevent the default action of the event. After reaching the target (and giving observers there a change to handle the event), the event reverses course and makes its way back to the root, in a process called bubbling. If the event finishes this journey without being cancelled, the default action happens as long as no listeners have signaled to block the default action. 7.1.1 The Old WayIn the design of HTML forms, script is used whenever some specific action is needed. For example, a form might have a button that copies values from a "ship to" section onto a "bill to" section. In HTML forms plus script, the following code would accomplish this: <script type="text/javascript"> <!-- function copyAddresses( ) { var frm = document.forms[0]; frm.shipAddr.value = frm.billAddr.value; frm.shipCity.value = frm.billCity.value; frm.shipProv.value = frm.billProv.value; frm.shipPostCode.value = frm.billPostCode.value; } --> </script> This code simply copies form values from one control to another. It would then be activated by a button, with an event-specific attribute, specified like this: <input type="button" value="Copy values" onclick="copyAddresses( )"/> In terms of DOM Level 2 Events, this represents a registration of an observer on the input element, watching for the DOM click event at the target, and handling the event by calling a short script. As a result, the script in the onclick attribute will get called when the user clicks on the button. Note that a minor leap of faith is required by the browser to interpret the contents of the onclick attribute as JavaScript in principle, any scripting language could be used, and a special meta tag would be needed to specify which scripting language is truly in use in the event attributes. (In practice, nobody actually does this, and browsers just muddle through, making essentially an educated guess, almost always JavaScript.) To recap the disadvantages of this approach:
XML Events solves all of these problems by specifying a better way to observe and, ultimately, handle events. 7.1.2 Listeners, Observers, and HandlersXML Events provides an element-based syntax for DOM Level 2 events. It defines a listener element that, even though not directly used in XForms, is still worth examining. This element has eight attributes defined:
The specification also calls for an id attribute to be declared by the host language. If the listener element was used in XHTML, it might look like the following. <head> <listener event="click" observer="btn" handler="#id_of_handler"/> ... </head> While these attributes map directly to equivalent concepts in DOM Level 2 Events, it can be cumbersome to provide an extra element with extra attributes. To accommodate for this, the XML Events specification contains a few shortcuts, based on namespaced or global attributes. These attributes can be placed directly on the observer element: <body> ... <input type="button" ev:event="click" ev:handler="#id_of_handler"/> ... </body> Alternatively, the attributes can be placed on the handler element: <head> <script type="text/javascript" ev:event="click" ev:observer="btn">...</script> ... </head> This final technique is used extensively in XForms. 7.1.3 Declarative Actions, Displacing ScriptThe example in the previous section had a script element that was designated as a "handler." What is the source of such handlers? Handlers can come from two sources. XForms defines a number of handlers, called XForms Actions, discussed below. Additionally, the host language can define handlers, as is the case with script. With XForms Actions, the earlier example can be done without any script at all, like this: <trigger> <label>Copy values</label> <action ev:event="DOMActivate"> <setvalue ref="Shipping/Addr" value="../Billing/Addr"/> <setvalue ref="Shipping/City" value="../Billing/City"/> <setvalue ref="Shipping/Prov" value="../Billing/Prov"/> <setvalue ref="Shiping/PostCode" value="../Billing/PostCode"/> </action> </trigger> |