Making sense of Form Runner Actions

Types of actions and processes

Orbeon Forms comes with a few powerful options to perform complex operations on or with forms. These fall into two main categories:

  • Actions: They run within a form while the user is working with the form.
  • Simple Processes: They typically run in association with a form button, such as a “Submit” button.
Actions and processes
Actions and processes

Actions themselves fall into two main categories:

  • Simple Actions: You define these using a user interface in Form Builder.
  • Action Syntax: You can do everything simple actions can do and more, but use a special syntax.1

Simple Actions

Simple Actions are defined using a user interface in Form Builder. They are easy to use and cover many common use cases. They support:

  • reacting to form load, activation, or value changes
  • running the action or not depending on a condition
  • calling a service and passing values to it
  • setting values and choices in form controls as a result of the service call
  • writing to a dataset
The Simple Actions Editor
The Simple Actions Editor

The Action Syntax

With the Action Syntax, you write sequences of actions, conditions, iterations, and more using an XML-based syntax.2 They support:

  • calling an action in response to multiple events
  • conditionally running parts of an action
  • repeatedly running parts of an action while iterating on data
  • calling an arbitrary number of services, or none at all
  • calling asynchronous services
  • adding, removing, or clearing repetitions in a repeated grid or section
  • setting or clearing form control values, including attachment control
  • setting focus on or visit form controls
  • copying form control content
  • writing and clearing datasets
  • calling processes

As you can see, the list is longer than the list of features supported by simple actions!

We recently wrote a full working example of the action syntax, which you can find here. This example, “List of Nobel Prize winners”, shows how to:

  • call a service with a list of Nobel Prize winners in JSON
  • iterate over the list of results
  • set values in a repeated grid

Here is a preview of the action documented in the example:

<fr:listener version="2018.2" events="form-load-after-controls" actions="my-action"/>

<fr:action name="my-action" version="2018.2">
    <fr:service-call service="get-nobel-prizes"/>
    <fr:repeat-clear repeat="prizes"/>
    <fr:data-iterate ref="/*/nobelPrizes/_">
        <fr:repeat-add-iteration repeat="prizes" at="end"/>
        <fr:control-setvalue value="awardYear" control="year" at="end"/>
        <fr:control-setvalue value="category/en" control="category" at="end"/>
        <fr:repeat-clear repeat="laureates"/>
        <fr:data-iterate ref="laureates/_">
            <fr:repeat-add-iteration repeat="laureates"/>
            <fr:control-setvalue value="knownName" control="known-name" at="end"/>
            <fr:control-setvalue value="motivation/en" control="motivation" at="end"/>
        </fr:data-iterate>
    </fr:data-iterate>
</fr:action>

Simple Processes

Simple processes were introduced to control what happens when a user activates a button at the bottom of the page. For example, a “Submit” button can do a number of things: validate the data, make sure errors are shown to the user, and then submit the data to a service or the database. Processes make all of this very configurable.

You configure simple processes in configuration properties. The expectation is that those are more likely to be shared amongst many or all forms.

Parts of a simple process are called process actions, and they included operations such as save(), send(), email(), validate(), and more. Simple processes also support conditions and recovery actions.

Here is an example of a simple process:

<property as="xs:string" name="oxf.fr.detail.process.send.acme.hr">
    require-valid
    then email
    then send("https://example.org/")
    then navigate("/success")
    recover navigate("/failure")
</property>

More

We hope that this overview clarifies the types of actions you have in Orbeon Forms!3 For more, see the documentation:


  1. For completeness, let’s mention that Orbeon Forms also supports lower-level XForms actions. XForms actions are much lower-level than Form Runner actions. They can iterate and have conditions, and set values, but they work at the level of XML data, not at the higher level of form controls, grid, sections, or services. Because they work at a much lower level than Form Runner actions, and that means that there are compatibility risks when upgrading to newer version of Orbeon Forms. Only when an action is not supported by the Form Runner action syntax should you consider using XForms actions. 

  2. In Orbeon Forms, we always prefer descriptive or declarative ways to describe content and behavior: this approach allows fixing bugs, migrating formats, and more, without programmer intervention. If actions were, say, JavaScript code, this would not be possible (or would be very hard). 

  3. In the future, we hope to make both types of actions and, possibly, simple processes, converge.