LSPS documentation logo
LSPS Documentation
Creating Forms with the ui Module

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

Creating Form Definition (ui)

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.

Passing Data to Forms as Form Parameters (ui)

A forms can receive and use arguments as it parameters when it is called.

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.

When instantiating the form, the form call must pass the arguments for the parameters.

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

Defining Form Variables (ui)

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 a Form (ui)

To create the content of a 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 (ui)

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 (ui)

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 Form (ui)

To display form preview, click the Preview button in the form editor.

runningPreview.png
Alternatively, you can use the context menu of the form definition:

  1. In the GO-BPMN Explorer, right-click the form.
  2. Select Run As -> Form Preview.
  3. 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
Make sure, Designer is connected to an LSPS Server: When displaying a form preview, the server runs a persisted instance of the module 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.

In the Management perspective, the model instances that you created as form previews are visible in the Model Instances view: to delete them, right-click anywhere into the view and click Remove All Form Preview Model Instances.

Displaying the Form Source Code (ui)

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 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 (ui)

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 (ui)

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 (ui)

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

Excluding Events on Listeners (ui)

To exclude an event so it is not caught by the listener under certain circustances, 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 (ui)

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 (ui)

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 (ui)

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 Form (ui)

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 Form on an Event (ui)

You can make a form navigate away by requesting navigation on an event action:

  1. Select or create the event listener.
  2. Double-click the listener to display its properties.
  3. Open the Action tab.
  4. Select Navigation.
  5. Define where to navigate below: 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; also, you can open the target location in a new browser tab (Chrome, Edge) or a new window (Firefox): set the openNewTab property to true.

Navigation expression

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

The 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.

Any navigation on submit is performed in the current tab: the openNewTab parameter is ignored.

Note: You can define a Navigation also on the Document or User Task: This Navigation is used when the form is submitted and overrides the Navigation defined on the event listeners. For example, if you define a button that not only navigates but also submits the form, on submit, the document or todo navigates to the Navigation defined on the document or todo; the navigation defined on the Action tab of the event listener is ignored.

Performing Action Before Session Expiration

A hook executed before session timeout is define on an Action Listener of a Button or Action Link component with the simulate-click-on-session-close hint. The hint value must be set to True: right before the session timeout, the action defined on the listener is performed.

To perform an action before the browser session with the form times out, do the following:

  1. Add a Button or Action Link component to your form.
  2. Define the simulate-click-on-session-close hint to the component with the value True.
  3. Define an ActionListener on the component.
  4. Define the action that should be performed before the session times out on the listener.