Apache » Cocoon »

  Cocoon Forms
      1.0
   homepage

Cocoon Forms 1.0

Form Libraries

With this feature, it is now possible to define libraries of form definitions and bindings. Specific support for templates was intentionally left out because of the frequently changing and unstructured nature of it. Other tools, such as the JX Template Generator's import feature or a combination of the Include Transformer and XSLT will do a better job dealing with any template formatting needs.

One important feature of the library subsystem is inheritance. Form widgets and bindings can inherit their contents and parameters from others. All such parent bindings/widgets will be referenced by IDs like so:

<fd:field id="myFieldID" extends="myOtherFieldID"/>

The attribute "extends" specifies the widget or binding to inherit from. The following is a simple example which shows how this works conceptually:

<fd:field id="parentField">
  <fd:label>Parent Field</fd:label>
  <fd:datatype base="string"/>
</fd:field>

<fd:field id="childField" extends="parentField">
  <fd:selection-list>
    <fd:item value="1"/>
    <fd:item value="2">
      <fd:label>two</fd:label>
    </fd:item>
    <fd:item value="3"/>
  </fd:selection-list>
</fd:field>

The above snippet will result in the following situation:

<fd:field id="parentField">
  <fd:label>Parent Field</fd:label>
  <fd:datatype base="string"/>
</fd:field>

<fd:field id="childField">
  <fd:label>Parent Field</fd:label>
  <fd:datatype base="string"/>
  <fd:selection-list>
    <fd:item value="1"/>
    <fd:item value="2">
      <fd:label>two</fd:label>
    </fd:item>
    <fd:item value="3"/>
  </fd:selection-list>
</fd:field>
Note: Note that "extends" does not have to reference widgets in a library, widgets in the same context are also usable (e.g. widgets in the same group or two top-level widgets can inherit from another).

Form Library Inclusion

A sample library sample.xml might look like this:

<fd:library>
  <fd:widgets>

    <fd:group id="account">
      <fd:widgets>
        <fd:field id="owner">
          <fd:label>Account Holder</fd:label>
          <fd:datatype base="string"/>
        </fd:field>
        <fd:field id="balance">
          <fd:label>Current Balance</fd:label>
          <fd:datatype base="float"/>
        </fd:field>
      </fd:widgets>
    </fd:group>

  </fd:widgets>
</fd:library>

This library can be easily be imported into another library or form model by using the <fd:import/> statement.

<fd:form>
  <fd:widgets>

    <fd:import prefix="lib" uri="sample.xml"/>    

    <fd:group id="accountWithNumber" extends="lib:account">
      <fd:widgets>
        <fd:field id="accountNo">
          <fd:label>Account Number</fd:label>
          <fd:datatype base="integer"/>
        </fd:field>
      </fd:widgets>
    </fd:group>

    <fd:group id="accountWithDifferentId" extends="lib:account"/>

    <fd:expand id="lib:account"/>

  </fd:widgets>
</fd:form>

You can see how the value of "extends" now has a prefix which identifies the library to use while resolving the name. The seperator is ":" and such prefixes can also be deep, meaning reference a path in the inclusion tree if many libraries also import other libraries. In a situation where library "common" is imported by libary "lib", then widgets in the "common" library are also accessible with the prefix "lib:common:" from a form importing only "lib".

The above example shows the four usecases implemented in the current library system:

  1. Library import: Imports a specific library into the scope of a form or another library under a certain key.
  2. Full widget inheritance with overriding and extending information (in the example, the "id" is overridden and a selection-list is added).
  3. The simple case of inheritance where only the "id" should change, say because of name clashes. While usually, the "fd:widgets" element is required in a "fd:group", it is not if you inherit the widgets from an already existing group, so changing the "id" is really simple.
  4. Simply using a widget defined in a library in the current library or form. This is achieved by the use of "fd:expand". Any occurance of "fd:expand" will be replaced by the referenced widget.
Note: The described statements "fd:import" and "fd:expand" are also available for bindings with exactly the same syntax and semantics, only within the binding namespace: "fb:import" and "fb:expand".
Be advised that some restrictions to inheritance remain: Currently, it is not possible to inherit selection-lists, meaning that they can be copied to the inheriting widget, but adding/replacing items inside the lists is not possible. Similarly, single validators can not be replaced or changed, only new validators can be added.

Also note that the Tree widget does not support inheritance up to now. It is only possible to define it in a library and use "fd:expand" to re-use the preconfigured Tree widget.
Errors and Improvements? If you see any errors or potential improvements in this document please help us: View, Edit or comment on the latest development version (registration required).