Intro

Some types of widgets can emit events. For example, the action widget produces ActionEvents and the field widget produces ValueChangedEvents. Next to these events, there are also ProcessingPhaseEvents, fired in between the various phases of the processing of a request.

Handling events can be done in three ways:

When are events processed? (Request processing phases)

To answer the question "When are events processed?", we have to look a bit deeper into how a form request is handled. This is separated in a couple of phases, more specifically the following ones:

Recursive event loops

Event listeners themselves might call methods on widgets which cause new events to be generated. You have to be careful not to cause recursive event loops by doing this.

For example, calling setValue on a widget in a ValueChangedEvent caused by that widget will schedule a new ValueChangedEvent, which will then again cause the execution of the event listener which will then again call setValue and thus again cause a new event to be generated, and so on.

Defining event handlers in the form definition

Event handlers can be specified as part of the form definition, as child of the various wd:on-xxx elements, such as wd:on-action for the action widget.

Event handlers can be written in either javascript or java. The form definition syntax is as follows:

<fd:on-xxxx>
  <javascript>
    ... some inline javascript code ...
  </javascript>
  <java class="..."/>
</fd:on-xxxx>

You can specify as many <javascript> and/or <java> event listeners as you want.

Javascript event listeners

Objects available in the Javascript snippet:

It does not make sense to create continuations from the Javascript event handler. In other words, do not call cocoon.sendPageAndWait or form.showForm from there.

Java event listeners

The Java class specified in the class attribute on the java element should implement a certain event listener interface. Which interface depends on the type of widget. See the documentation of the individual widgets for more information.

Adding event listeners on widget instances

Adding event listeners on widgets instances allows to dynamically add event listeners at runtime. This is often convenient: as you control the creation of the event listeners yourself, you can pass them any information you need.

To add an event listener on a widget instance, simply call the appropriate method on the widget (e.g. addValueChangedListener) with an appropriate listener object as argument. You can of course also remove the event listener afterwards (e.g. removeValueChangedListener).

When using flowscript, it is possible to simply assign Javascript functions as event listeners. This is a very easy and powerful way to create event listeners. See the flowscript API section for more information.

Handling events using the FormHandler

To handle events using a FormHandler, write a class implementing the following interface:

org.apache.cocoon.woody.event.FormHandler

Alternatively you can extend from the following abstract class:

org.apache.cocoon.woody.event.AbstractFormHandler

which will split ActionEvents and ValueChangedEvents to two different methods. See the javadocs of these interfaces and classes for more details.

Once you created the FormHandler, register it on a form instance by calling the method setFormHandler(FormHandler formHandler) on it.

Overview of supported events

The figure below shows the 3 types of events we currently support, each extending from the common WidgetEvent class.

Overview of event types

The full types of the event listeners and event objects are:

org.apache.cocoon.forms.event.ValueChangedListener
org.apache.cocoon.forms.event.ValueChangedEvent

org.apache.cocoon.forms.event.ActionListener
org.apache.cocoon.forms.event.ActionEvent

org.apache.cocoon.forms.event.ProcessingPhaseListener
org.apache.cocoon.forms.event.ProcessingPhaseEvent

The table below gives an overview of what events are supported on what widgets.

Widget Supports ValueChangedEvents Supports ActionEvents
field yes
multivaluefield TODO
booleanfield yes
repeater
output
submit yes
action yes
repeater-action yes
row-action yes
aggregatefield TODO
upload
messages