LSPS documentation logo
LSPS Documentation
Creating ui::Forms

When creating ui::forms, you typically do the following:

Creating ui::Form Definition

To create a UI form definition, do the following:

  1. In GO-BPMN Explorer, right-click a module.
  2. Go to New > Form Defining.
  3. In the popup, enter the name of the form.
  4. Unselect the Use FormComponent-based UI.
    uiformdefinitionpopup.png

    Note: If the Use FormComponent-based UI option is selected, a form based on the forms module will be created.

Defining ui::Form Parameters

Forms can require parameters.

To define form parameters, do the following:

  1. Open the form in the form editor: double-click it in the GO-BPMN Explorer.
  2. In the Outline view, right-click the form and select New > Parameter.

    Alternatively, you can open the form properties in the Properties view and click Add on the Parameters tab.

  3. In the Property view, define the parameter.

The parameters are required: when creating the form, the call must provide arguments for the parameters.

//example call that creates a parametric form:
applicationForm(user -> admin, requestedHardware -> Hardware.ssd)

Defining ui::Form Variables

Forms can define form variables, which are accessible from within the form. They allow you to separate presentation data and business data: You should prefer form variables over global variables whenever possible.

Form variables are initialized when the form is displayed along with the InitEvent being fired.

To define form variables do the following:

  1. Open the form definition.
  2. In the Outline view, right-click the form and go to New > Variable.
  3. In the displayed Properties view, define the variable properties.

Designing ui::Form Content

To create the content of your form, open the form definition file (double-click it in the GO-BPMN Explorer). Then either click the required component in the palette and then click into the canvas to insert it, or right-click the canvas, go to Insert Component and select the component from the context menu.

insertingComponent.png
Inserting a component into the form from the context menu

Note: You can create forms also with the dynamic-gui functions, such as createAndAdd(). However, these functions are not maintained and will not be enhanced.

Once you have created your form or while doing so, you can do the following:

Inserting a Parent Component in ui::Forms

You can select one or multiple form Components and wrap them with another components in the Form graphical editor.

To insert such a parent form component over another component, do the following:

  1. In the Form editor, right-click the component.
  2. In the context menu, go to Insert Parent and select the component to use as the wrapper component.
wrappingComponent.png
Wrapping component in a layout component

Deleting a Parent Component in ui::Forms

To delete a only a parent component and preserve its child components, right-click the parent component and click Shift Children Up.

Note that the option is only available if the children can be accommodated in the form after the deletion; for example, it is not possible to delete a Vertical Layout with multiple child components if it has a Panel component as its parent.

Previewing a ui::Form

While creating a form, you can display its preview in the browser.

Make sure, PDS is connected to an LSPS Server: When displaying a form preview, the server runs a persisted instance of the model that contains the form definition (global variables are initialized, the Form parameters are initialized, the form screen context is created). The model instance is persisted.

To display preview of your form in your web browser, do the following:

  1. In the GO-BPMN Explorer, right-click the form.
  2. Select Run As -> Form Preview and on the displayed application page in your browser, log in to the application.

For parametric forms, add the argument to the form preview configuration.

formPreviewWithParameter.png
Form preview configuration of a parametric form
In the Management perspective, you can delete any model instances that you triggered as form previews in the Model Instances view: right-click anywhere into the view and click Remove All Form Preview Model Instances.

Displaying the ui::Form Source Code

Since forms are defined as functions and their components as variables of the respective record type on the level of the Expression Language, you can display their source in the Expression editor:

  1. In the Form editor, right-click any form component.
  2. On the context menu, select Display Form Expression.

Searching for a ui::Form Component

If an error on a form component occurs during runtime, the server returns an error message with the modeling ID of the form component. To find the form component, do the following:

  1. Go to Search > Find Form Component.
  2. In the displayed search dialog, enter the modeling ID.

Defining a Context Menu in ui::Forms

Every form component can define its context menu. The menu and its content is defined as a component property. When the user right-clicks the component, the context menu with its items is displayed. The user can then click a context menu item. On click, a MenuEvent is produced. The MenuEvent has the id of the clicked menu item as its payload so the form can define the MenuListener that will trigger the respective actions.

The context menu can be defined as static or dynamic: A static context menu is calculated only once before the form is rendered, while a dynamic context menu is recalculated on every right-click. This might cause performance issues since it could require accesses to server on every right-click.

If you define both a static and a dynamic context menu on right-click, the displayed context menu will contain the static menu items on top and the dynamic menu items below.

To define a context menu on a component, do the following:

  1. Select the component in the form definition.
  2. In the Properties view, open the Context Menu tab.
  3. On the tab define either a static context menu or a dynamic context menu.
    [new MenuItem(
                caption -> "Open the Detail",
                htmlClass -> "contextmenu",
                id -> 0,
                submenu -> [new MenuItem(
                        caption -> "Open in a New Tab",
                        htmlClass -> "contextmenu",
                        id -> 1),
                        new MenuItem(
                        caption -> "Open in This Tab",
                        htmlClass -> "contextmenu",
                        id -> 2)
                        ]
                )
    ]
    
  4. Define the action that should occur when the item is clicked in a MenuListener.

    Example Handle expression on a MenuListener

    _event.id == 1 ?  (MENUITEMCLICK.content := { -> "Menu item with id 1 has been clicked." }) : null

Defining a Listener in a ui::Form

You can define listeners on any form component; however, every component type allows only listeners for events it can actually produce; for example, a Button component can define only an Action listener, which is fired when the user clicks a button. It cannot define a ValueChange listener since there is no value to be changed on a Button. On the other hand, a component might produce various events: A button produces just like all components an InitEvent when it is created: An Action listener on the Button will ignore the event: it catches only the events of a particular type on its component.

Note: To listen for an event on another component, you can do one of the following:

To create a listener on a form component:

  1. In the Form editor with your form definition, right-click the form component.
  2. In the context menu, select the listener type.
    creatingListener.png
  3. In the Add Listener dialog, define the listener properties:
    • You can do so by gradually going through the Basic, Advanced, and Actions tabs
    • Alternatively, you can go to the Expression tab and define your listener as an expression: if you have previously defined some properties on the Basic, Advanced, and Actions tabs, they are these are reflected in the listener expression.

Note that the event caught by the listener is available to expressions on all tabs with the exception of the Handle expression; however, the type of the event is not recognized so you might need to cast it to its type, for example, _event.cast(InitEvent).

definingListener.png
Defining properties of an ActionEvent listener on a submit Button component
You can display listener properties by double-clicking the listener in the form or on the Event Handling tab of the component's Properties view.

Disabling a Listener in ui::Forms

To disable a listener on design time, open its properties and select Listener is disabled on the Basic tab.

Filtering Events on Listeners in ui::Forms

To filter out an event so the listener does not catch it, use one of the following listener properties on the Advanced tab:

  • Execute only if visible components: The event is processed by the listener only if the component that produced the event is visible.
  • Precondition: The event is only processed if the precondition evaluates to true.
    if ((_event as ApplicationEvent).payload as Integer) = 1
      then true
      else false
    end
    
  • Event name (available only for ApplicationEventListeners): An application event is only handled by the listener, if the name of the event matches the defined event name.

Note: An event might not be processed also if the validation process fails.

Ignoring Queued Non-Immediate ValueChangeEvents

Sometimes you want to ignore queued events from other components, for example, in forms with multiple tabs, you want to ignore events on tabs that are not focused at the given moment, or you want to prevent validation on components while resetting the content of another component, etc.

To ignore events produced by other components when a particular event is processed, set the Process component property on the Advanced tab in your listener properties:

  • all: any queued events are processed
  • this: only events from the component with this listener are processed
  • components: events from the listed components and the component with this listener are processed

For example, let's assume a table with column A and column B. Both columns contain input components that are not-immediate and buttons used to submit the values from the given column. When the user changes values, ValueChangeEvents from both columns are kept in the event queue. Then the user clicks the submit button in column A. The value change listener must define as its Process component only column A. If it defines as its Process component column B as well, all the ValueChangeEvents will be processed.

Refreshing a Component in ui::Forms

To refresh the content of form components, do the following:

  1. Define IDs on the component you want to refresh.
  2. Create a private listener on the component that should cause the refresh.
    1. In the Properties view of the component, click the Event Handling tab.
    2. In the Private Listeners section, click Add.
    3. In the Add Listener view on the Basic tab, define the Listener properties:
      • Listener type: the type defines the event type the listener handles.
      • Refresh components: define IDs of the components that should be refreshed when the event is handled.

Alternatively, you can call the refresh() function from the handle expression (for example, refresh([MYTABLE, MYPOPUP])).

refreshListener.png
Listener that refreshes multiple components

Persisting Data in ui::Forms

To persist the context data of a document or to-do, enable the Persist action on the Action tab of the respective listener or call the persist() function from its handle expression.

To perform an action immediately after persist, define it in the text area below the Persist checkbox,

The Persist action is performed after the merge to the screen level before the transaction is committed.

Saving a To-Do or Document in ui::Forms

To save the state of the to-do or document for later editing, define the Save action on a listener. The action is identical to clicking the Save button on a to-do or document in the LSPS Application User Interface. Note that the save action does not persist the data, therefore make sure to activate the Persist action if required.

Note: A saved document is persisted in the system database as a SavedDocument record. If saved repeatedly, the same record is overwritten. On submit, the persisted document is removed.

To process a saved to-do or document, define the Save action closure below the Save option: it has the saved to-do or document as its input parameter.

Note that by default, Save does not preserve Column states (width and collapse state). To save these, proceed as described in Saving Column Width and Collapsed State.

Saving a To-Do or Document in a Custom Data Source

To store a saved to-do or document in your own data source, define the following:

  • a shared Record that is in the 1:1 relationship to the human::SavedDocument record
  • a document or a todo that will contain a form with a listener that will save the data as your SavedDocument subrecord in its Saving Action expression
  • implementation that will recover the saved documents, for example, another dedicated Document with a navigation
  • possibly the option for deletion of saved documents

Submitting a ui::Form

When the user submits the document or to-do, the data is saved, typically in the underlying DB via shared Records, and; in the case of documents, the model instance ceases to exist, and, in the case of to-dos, the user task finishes.

Note that the document will remain available in the list of documents since the list contains the types of documents, not their instances: Unlike To-Dos, documents availability does not depend on a Task; they are available as long as the definition of the document is on the server and their instances are created on request.

To define, when the document or to-do is submitted, do one of the following:

  • on the component that should submit the document, create a listener of the required type and on the Action tab in the listener properties, select Submit.
    actionSubmit.png
    Submit action on a click listener
  • on the component that should submit the document, create a listener of the required type and call the requestSubmit() or requestSubmitAndNavigate() from the Handle expression.
    dynamicSubmit.png
    Submit call from a listener handle expression

Navigating from a ui::Form

To navigate to a location when the form is submitted or saved, define the Navigation on the Action tab of the listener: you can navigate to a to-do or document, URL, custom application page (refer to the descriptions of data types defined in the human.navigation.datatypes resource in the Standard Library).

Note: You can define a Navigation also on the document definition: This Navigation overrides the Navigation defined on the form (that is, if you define a button that submits the form, the form will navigate as defined in the Navigation closure on the document; not in the navigation of the submit component).

Navigation expression

//redirect to the document Confirmation when the event is handled:
new DocumentNavigation(documentType -> confirmationDocument())

Note: Navigation expression is evaluated right after persisting, which allows you to use the persisted data in the navigation expression. However, the action is taken only after the submit or save action is performed.