4.7. Form Modeler

Red Hat JBoss BPM Suite provides a custom editor for defining forms called Form Modeler.
Form Modeler includes the following key features:
  • Form Modeling WYSIWYG UI for forms
  • Form autogeneration from data model / Java objects
  • Data binding for Java objects
  • Formula and expressions
  • Customized forms layouts
  • Forms embedding
Form Modeler comes with predefined field types, such as Short Text, Long Text, or Integer, which you place onto the canvas to create a form. In addition to that, Form Modeler also allows you to create custom types based on data modeler classes, Java classes (must be on the classpath), or primitive Java data types. For this purpose, the Form data origin tab contains three options: From Data Model, From Java Class, and From basic type.
Use the Add fields by origin tab visible in the following figure to select fields based on their source.
Adding fields by origin

Figure 4.8. Adding fields by origin

To view and add Java classes created in Data Modeler in Form Modeler, go to section Form data origin and select the From Data Model option shown in the following figure.
Adding classes from data model

Figure 4.9. Adding classes from data model

You can adjust the form layout using the Form Properties tab that contains a Predefined layout selected by default, as well as a Custom option.
When a task or process calls a form, it sends the form a map of objects, which include local variables of the process or task. Also, when the form is completed, a map is sent back to the process or task with the data acquired in the form. The form assigns this output data to the local variables of the task or process, and the output data can therefore be further processed.

4.7.1. Creating a Form in Form Modeler

To create a new form in Form Modeler, do the following:
  1. In Business Central, go to AuthoringProject Authoring.
  2. On the perspective menu, select New ItemForm.
  3. In the Create New Form dialog that opens, fill out the name of your form in Resource Name and click OK.
The newly created form will open up. You can add various fields to it when you select the Add fields by type option on the Form Modeler tab. Use the button to place the field types onto the canvas, where you can modify them. To modify the field types, use the icons that display when you place the cursor over a field: First, Move field, Last, Group with previous, Edit, or Clear. The icons enable you to change the order of the fields in the form, group the fields, or clear and edit their content.
The following figure shows a new form created in Form Modeler.
New form

Figure 4.10. New form

4.7.2. Opening an Existing Form in Form Modeler

To open an existing form in a project that already has a form defined, go to Form Definitions in Project Explorer and select the form you want to work with from the displayed list.
Opening an Existing Form

Figure 4.11. Opening an Existing Form

4.7.3. Setting Properties of a Form Field in Form Modeler

To set the properties of a form field, do the following:
  1. In Form Modeler, select the Add fields by type tab and click the arrow button to the right of a field type. The field type is added to the canvas.
  2. On the canvas, place the cursor on the field and click the edit icon.
  3. In the Properties dialog that opens on the right, set the form field properties and click Apply at the bottom of the dialog for HTML Labels. For other form field properties, the properties change once you have removed focus from the property that you are modifying.

4.7.4. Configuring a Process in Form Modeler

You can generate forms automatically from process variables and task definitions and later modify the forms using the form editor. In runtime, forms receive data from process variables, display it to the user, capture user input, and update the process variables with the new values. To configure a process in Form Modeler, do the following:
  1. Create process variables to hold values entered into forms. Variables can be simple (e.g. 'string') or complex. You can define complex variables using Data Modeler, or create them in any Java integrated development environment (Java IDE) as regular plain Java objects.
  2. Declare the process variables in the 'variables definition' property.
  3. Determine which variables you want to set as input parameters for the task, which shall receive response from the form, and establish mappings by setting the 'DataInputSet', 'DataOutputSet', and 'Assignments' properties for any human task. To do so, use the Editor for Data Input, Editor for Data Output, and Editor for Data Assignment.

Example 4.1. Defining a Variable using Data Modeler

4.7.5. Generating Forms from Task Definitions

In the Process Designer module, you can generate forms automatically from task and variable definitions, and easily open concrete forms from Form Modeler by using the following menu option:
Generating Forms Automatically

Figure 4.12. Generating Forms Automatically

To open and edit a form directly, click the Edit Task Form icon ( ) located above a user task.

Figure 4.13. 

Forms follow a naming convention that relates them to tasks. If you define a form named formName-taskform in the same package as the process, the human task engine will use the form to display and capture information entered by the user. If you create a form named ProcessId-task, the application will use it as the initial form when starting the process.

4.7.6. Editing Forms

After you generate a form, you can start editing it. If the form has been generated automatically, the Form data origin tab contains the process variables as the origin of the data, which allows you to bind form fields with them and create data bindings. Data bindings determine the way task input is mapped to form variables, and when the form is validated and submitted, the way values update output of the task. You can have as many data origins as required, and use different colors to differentiate them in the Render color drop down menu. If the form has been generated automatically, the application creates a data origin for each process variable. For each data origin bindable item, there is a field in the form, and these automatically generated fields also have defined bindings. When you display the fields in the editor, the color of the data origin is displayed over the field to give you quick information on correct binding and implied data origin. To customize a form, you can for example move fields, add new fields, configure fields, or set values for object properties.

4.7.7. Moving a Field in Form Modeler

You can place fields in different areas of the form. To move a field, access the field's contextual menu and select the Move field option shown on the following screenshot. This option displays the different regions of the form where you can place the field.
Moving a Form Field in Form Modeler

Figure 4.14. Moving a Form Field in Form Modeler

After you click the Move field option, a set of rectangular contextual icons appears. To move a field, select one of them according to the desired new position of the field.
Destination Areas to Move a Field

Figure 4.15. Destination Areas to Move a Field

4.7.8. Adding New Fields to a Form

You can add fields to a form by their origin or by selecting the type of the form field. The Add fields by origin tab allows you to add fields to the form based on defined data origins.
Adding Fields by Origin

Figure 4.16. Adding Fields by Origin

The fields then have correct configuration of the Input binding expression and Output binding expression properties, so when the form is submitted, the values in the fields are stored in the corresponding data origin. The Add fields by type tab allows you to add fields to the form from the fields type palette of the Form Modeler. The fields do not store their value for any data origin until they have correct configuration of the Input binding expression and Output binding expression properties.
Adding a field by type screen for BRMS/BPMS User Guide 6.1 DR1

Figure 4.17. Adding Fields by Type

There are three kinds of field types you can use to model your form: simple types, complex types, and decorators. The simple types are used to represent simple properties like texts, numeric values, or dates. The following table presents a complete list of supported simple field types:

Table 4.1. Simple Field Types

Name Description Java Type Default on generated forms
Short Text Simple input to enter short texts. java.lang.String yes
Long Text Text area to enter long text. java.lang.String no
Rich Text HTML Editor to enter formatted texts. java.lang.Srowing no
Email Simple input to enter short text with email pattern. java.lang.String no
Float Input to enter short decimals. java.lang.Float yes
Decimal Input to enter number with decimals. java.lang.Double yes
BigDecimal Input to enter big decimal numbers. java.math.BigDecimal yes
BigInteger Input to enter big integers. java.math.BigInteger yes
Short Input to enter short integers. java.lang.Short yes
Integer Input to enter integers. java.lang.Integer yes
Long Integer Input to enter long integers. java.lang.Long yes
Checkbox Checkbox to enter true/false values. java.lang.Boolean yes
Timestamp Input to enter date and time values. java.util.Date yes
Short Date Input to enter date values. java.util.Date no
Document Allows the user to upload documents to the form. org.jbpm.document.Document No
Complex field types are designed for work with properties that are not basic types but Java objects. To use these field types, it is necessary to create extra forms in order to display and write values to the specified Java objects.

Table 4.2. Complex Field Types

Name Description Java Type Default on generated forms
Simple subform Renders the form; it is used to deal with 1:1 relationships. java.lang.Object yes
Multiple subform This field type is used for 1:N relationships. It allows the user to create, edit, and delete a set child Objects.Text area to enter long text. java.util.List yes
Decorators are a kind of field types that does not store data in the object displayed in the form. You can use them for decorative purposes.

Table 4.3. Decorators

Name Description
HTML label Allows the user to create HTML code that will be rendered in the form.
Separator Renders an HTML separator.

4.7.9. Configuring Fields of a Form

Each field can be configured to enhance performance of the form. There is a group of common properties called generic field properties and a group of specific properties that differs by field type.
Generic field properties:
  • Field Type - can change the field type to other compatible field types.
  • Field Name - is used as an identifier in calculating of formulas.
  • Label - the text that is displayed as a field label.
  • Error Message - a message displayed when there is a problem with a field, for example in validation.
  • Label CCS Class - allows you to enter a class css to apply in label visualization.
  • Label CCS Style - allows you to directly enter the style to be applied to the label.
  • Help Text - introduced text displayed as an alternative attribute to help the user in data introduction.
  • Style Class - allows you to enter a class CSS to be applied in field visualization.
  • CSS Style - allows you to directly enter the style to be applied to the label.
  • Read Only - a field with this property allows reading only, no write access.
  • Input Binding Expression - defines the link between the field and the process task input variable. In runtime, it is used to set the field value to the task input variable data.
  • Output Binding Expression - defines the link between the field and the process task output variable. In runtime, it is used to set the task output variable.

4.7.10. Creating Subforms with Simple and Complex Field Types

Complex Field types is a category of fields in a form. You can use the complex field types to model form properties that are Java Objects. Simple subform and Multiple subform are the two types of complex field types. A simple subform represents a single object and a multiple subform represents an object array inside a parent form. Once you add one of these fields into a form, you must configure the form with information on how it must display these objects during execution. For example, if your form has fields representing an object array, you can define a tabular display of these fields in the form. You cannot represent them as simple inputs such as text box, checkbox, text area, and date selector.

Procedure 4.2. To create and insert a subform containing a single object inside a parent form:

  1. In Business Central, go to AuthoringProject Authoring.
  2. On the perspective menu, select New Item Form.
    A new form opens in the Form Modeler. You must now configure the new form with information of the object it must contain.
  3. Enter the values for the required fields in the Form data origin tab and click Add data holder.
    Creating Subform

    Figure 4.18. Create Subform

  4. Click Add fields by origin tab and add the listed fields to the form.
    Adding fields by origin

    Figure 4.19. Add fields by origin

  5. Click the Edit icon on the field in the form to open the Properties tab.
  6. In the Properties tab, configure the form by providing required values to the fields and click Save to save the subform.
  7. Open the parent form to configure the properties of the object.
  8. In the parent form, click the Add fields by type tab. Select the object on the form and configure it in the Properties tab.
  9. In the Properties tab, select Simple subform for the Field type property. Then select the newly created subform for the Default form field property.
    Parent Form

    Figure 4.20. Configure the Parent Form

  10. Click Save to save the parent form.
    This inserts your subform containing a single Java object inside the parent form.

Procedure 4.3. To insert a subform with multiple objects inside a parent form:

  1. In Business Central, go to AuthoringProject Authoring.
  2. On the perspective menu, select New Item Form.
    A new form opens in the Form Modeler. You must now configure the new form with information on the object array it must contain.
  3. Enter the values for the required fields in the Form data origin tab and click Add data holder.
  4. Click Add fields by origin tab and add the listed fields to the form.
  5. Click the Edit icon on the field in the form to open the Properties tab.
  6. In the Properties tab, configure the form by providing required values to the fields. You can use the Formula Engine to automatically calculate field values.
  7. Click Save to save the subform.
  8. Open the parent form to configure the properties of each of the objects.
  9. In the parent form, click the Add fields by type tab. Select each object on the form one by one and configure them in the Properties tab.
  10. In the Properties tab, select Multiple subform for the Field type property. Then select the newly created subform for the Default form field property.
    Parent Form

    Figure 4.21. Configure the Parent Form

  11. Click Save to save the parent form.
    This inserts your subform containing an array of Java objects inside the parent form.

4.7.11. Attaching Documents to a Form

The 6.1 release of Red Hat JBoss BPM Suite has introduced the concept of attaching documents to a form by using a Document form field. This field can be attached to any form, process or task based.
To attach a Document field to a form, click on it while creating or editing an existing form (in the Add fields by type section).
Alternatively, you can let the system automatically generate the Document form fields based on the presence of a org.jbpm.document.Document variable type in your process.
When the end user uploads a document using this form, the uploaded document is available in a list in the task list (task details) and process instance details (Document tab). The uploaded documents are shown as links and the users can click to view them.
The Process Engine generates an instance of org.jbpm.document.Document to be stored in a process variable, which you can pass through your persistence strategy to decide where and how to store that document.

Pluggable Variable Persistence

New with this release is also the ability for you to store your document in a location of your choice. This is defined as Pluggable Variable Persistence and this allows you to store these documents automatically in a centralized content management system (CMS) of choice, behind the scenes.
To implement your custom persistence strategy, start by defining your Marshaling Strategy. This strategy is declared to the Process Engine by the use of deployment descriptors (see Red Hat JBoss BPM Suite Administration and Configuration Guide) using the <marshalling-strategy> element. This element should name a type that provides an implementation of the org.kie.api.marshalling interface.
The following methods in this interface help you create your strategy.
  • public boolean accept(Object object): Determines if the given object can be marshalled by the strategy.
  • byte[] marshal( Context context, ObjectOutputStream os, Object object ): Marshals the given object and returns the marshalled object as byte[].
  • Object unmarshal( Context context, ObjectInputStream is, byte[] object, ClassLoader classloader ): Reads the object received as byte[] and returns the unmarshalled object
  • void write(ObjectOutputStream os, Object object): same as marshal method, provided for backwards compatibility.
  • Object read(ObjectInputStream os): same as unmarshal, provided for backwards compatibility.
For example, if you create a custom strategy that stores your uploaded documents in Google Drive, your implementation class should not only implement the methods of the org.kie.api.marshalling package, but this implementation should also be made available to the Process Engine, by putting the classes in its classpath (and declaring the type in the deployment descriptors).
There is a default marshalling strategy that simply saves the uploaded documents in the file system under a folder called docs. This default implementation is defined by the DocumentStorageService class and is implemented through the DocumentStorageServiceImpl class.

4.7.12. Rendering Forms for External Use

Forms generated by the Form Builder can be reused in other client applications with the help of the REST API and a JavaScript library. The REST API defines the end points for the external client applications to call and the JavaScript library makes it easy to interact with these endpoints and to render these forms.
To use this API you will need to integrate the Forms REST JavaScript library in your client application. The details of the library and the methods that it provides are given in the following section, along with a simple example. Details of the REST API are present in the Red Hat JBoss BPM Suite Developers Guide, although you should probably only use the REST API via the JavaScript library described here.

4.7.12.1. JavaScript Library for Form Reuse

The JavaScript API for Form Reuse makes it easy to use forms created in one Business Central application to be used in remote applications and allows loading of these forms from different Business Central instances, submitting them, launching processes or task instances, and executing callback functions when the actions are completed.
Blueprint for using the JavaScript Library
A simple example of using this API would involve the following steps:
  1. Integrate the JavaScript library in the codebase for the external client application so that its functions are available.
  2. Create a new instance of the jBPMFormsAPI class in your own JavaScript code. This is the starting point for all interactions with this library.
    var jbpmRestAPI = new jBPMFormsAPI();
  3. Call your desired methods on this instance. For example, if you want to show a form, you would use the following method:
    jbpmRestAPI.showStartProcessForm(hostUrl, deploymentId, processId, divId, onsuccess, onerror);
    and provide the relevant details (hostUrl, deploymentId, processId and so on. A full list of the methods and parameters follows after this section).
  4. Do post processing with the optional onsuccess and onerror methods.
  5. Work with the form, starting processes (startProcess()), claiming tasks (claimTask()) starting tasks (startTask()) or completing tasks (completeTask). Full list of available methods follows after this section.
  6. Once you're finished with the form, clear the container that displayed it using clearContainer() method.
Full list of available methods in the JavaScript Library
The JavaScript library is pretty comprehensive and provides several methods to render and process forms.
  1. showStartProcessForm(hostUrl, deploymentId, processId, divId, onsuccessCallback, onerrorCallback): Makes a call to the REST endpoint to obtain the form URL. If it receives a valid response, it embeds the process start form in the stated div. You need these parameters:
    • hostURL: The URL of the Business Central instance that holds the deployments.
    • deploymentId: The deployment identifier that contains the process to run.
    • processId: The identifier of the process to run.
    • divId: The identifier of the div that has to contain the form.
    • onsuccessCallback (optional): A JavaScript function executed if the form is going to be rendered. This function will receive the server response as a parameter.
    • onerrorCallback (optional): A JavaScript function executed if any error occurs and it is impossible to render the form. This function will receive the server response as a parameter.
  2. startProcess(divId, onsuccessCallback, onerrorCallback): Submits the form loaded on the stated div and starts the process. You need these parameters:
    • divId: The identifier of the div that contains the form.
    • onsuccessCallback(optional): A JavaScript function executed after the process is started. This function receives the server response as a parameter.
    • onerrorCallback (optional): A JavaScript function executed if any error occurs and it is impossible to start the process. This function receives the server response as a parameter.
  3. showTaskForm(hostUrl, taskId, divId, onsuccessCallback, onerrorCallback): Makes a call to the REST endpoint to obtain the form URL. If it receives a valid response, it embeds the task form in the stated div. You need these parameters:
    • hostURL: The URL of the Business Central instance that holds the deployments.
    • taskId: The identifier of the task to show the form.
    • divId: The identifier of the div that has to contain the form.
    • onsuccessCallback (optional): A JavaScript function executed if the form is going to be rendered. This function receives the server response as a parameter.
    • onerrorCallback (optional): A JavaScript function executed if any error occurs and it is impossible to render the form. This function receives the server response as a parameter.
  4. claimTask(divId, onsuccessCallback, onerrorCallback): Claims the task whose form is being rendered. You need these parameters:
    • divId: The identifier of the div that contains the form.
    • onsuccessCallback (optional): A JavaScript function executed after the task is claimed. This function receives the server response as a parameter.
    • onerrorCallback (optional): A JavaScript function executed if any error occurs and it is impossible to claim the task. This function receives the server response as a parameter.
  5. startTask(divId, onsuccessCallback, onerrorCallback): Starts the task whose form is being rendered. You need these parameters:
    • divId: The identifier of the div that contains the form.
    • onsuccessCallback (optional): A JavaScript function executed after the task is claimed. This function receives the server response as a parameter.
    • onerrorCallback (optional): A JavaScript function executed if any error occurs and it is impossible to claim the task. This function receives the server response as a parameter.
  6. releaseTask(divId, onsuccessCallback, onerrorCallback): Releases the task whose form is being rendered. You need these parameters:
    • divId: The identifier of the div that contains the form.
    • onsuccessCallback (optional): A JavaScript function executed after the task is claimed. This function receives the server response as a parameter.
    • onerrorCallback (optional): A JavaScript function executed if any error occurs and it is impossible to claim the task. This function receives the server response as a parameter.
  7. saveTask(divId, onsuccessCallback, onerrorCallback): Submits the form and saves the state of the task whose form is being rendered. You need these parameters:
    • divId: The identifier of the div that contains the form.
    • onsuccessCallback (optional): A JavaScript function executed after the task is claimed. This function receives the server response as a parameter.
    • onerrorCallback (optional): A JavaScript function executed if any error occurs and it is impossible to claim the task. This function receives the server response as a parameter.
  8. completeTask(divId, onsuccessCallback, onerrorCallback): Submits the form and completes task whose form is being rendered. You need these parameters:
    • divId: The identifier of the div that contains the form.
    • onsuccessCallback (optional): A JavaScript function executed after the task is claimed. This function receives the server response as a parameter.
    • onerrorCallback (optional): A JavaScript function executed if any error occurs and it is impossible to claim the task. This function receives the server response as a parameter.
  9. clearContainer(divId): Cleans the div content and the related data stored on the component. You need these parameters:
    • divId: The identifier of the div that contains the form.