Table of Contents
List of Tables
Table of Contents
Forms are used to display and edit the data of underlying work objects. The work object data and the form definition are fetched from the server, and the expressions used within the form definition are then used to link the form fields with corresponding data. For editable fields, any changes made are reflected in the underlying work object data, which is sent back to the server to be persisted when the form is submitted:

            Form data binding expressions are placed between two sets of curly braces, e.g.{{expression}},
            and are set into a form component's
            Value
            property:
        

                The
                Value
                property of a form component may only be bound to a single expression,
                and this may not be preceded or followed by other text.
            
The only exception to this rule is the output component, which doesn't display and edit a single value, but uses form expressions embedded within a rich text template to create textual output dynamically.
                A simple value name in double curly braces (e.g.{{value}})
                is used to link to the corresponding variable in the current work object. If the
                work object variable doesn't exist when the form is opened then it will be created
                automatically.
            
A work object in edoras one is typically part of a hierarchy, where work objects are linked together in a tree of parent/child relationships. For example a case typically serves as a container for other work objects (tasks, running processes, documents etc.). Form binding expressions can also be used to access the values from related work objects in the work object hierarchy. This is done be preceding the variable to be accessed by a qualifier:
{{parent.value}}
                    binds to the corresponding value in the current work object's parent.
{{root.value}}
                    binds to the corresponding value in the work object that is at the root of the current work object's hierarchy. The root is determined by following the parent references until a work object is found that has no parent.
As an example, if we start a process within a case then the process's parent work object will be the case. A form task created by that process will have the process work object as its parent:

                In this case
                {{root.name}}
                will bind to"Example case",
                {{parent.name}}
                will bind to
                "Example process"
                and
                {{name}}
                will bind to"Example task".
            
Bindings can be created for new variables as required, but a number of predefined bindings are used to access common work object attributes:
Table 1.1. Standard form bindings
| Binding | Editable | Form Component | Binds to | 
|---|---|---|---|
                                {{name}}
                             | Yes | Text | the work object's name | 
                                {{description}}
                             | Yes | Text | the work object's description | 
                                {{state}}
                             | No | Text | the work object's state | 
                                {{type}}
                             | No | Text | the work object's type | 
                                {{ownerId}}
                             | Yes | User selection | the work object's owner | 
                                {{assigneeId}}
                             | Yes | User selection | the work object's assignee | 
                                {{candidateGroupIds}}
                             | Yes | Share with groups selection | the work object's candidate groups | 
                                {{creationTime}}
                             | No | Date | the work object's creation time | 
                                {{updateTime}}
                             | No | Date | the work object's last update time | 
                                {{dueTime}}
                             | Yes | Date | the work object's last due time | 
                                {{resubmissionTime}}
                             | Yes | Date | the work object's last resubmission time | 
Table of Contents
Expressions can also be used within the process models to access data from the work object hierarchy and interact with other system components. In contrast to the form binding expressions, process model expressions can be more complex and have side-effects within the system (for example causing an e-mail to be sent). Whereas form expressions serve simply to link a particular data item with a form component (which then takes over the responsibility of interacting with the data), process expressions allow data object hierarchies to be traversed and method calls to be made.
The full expression language is part of the EE6 specification and only an brief overview will be provided here. For a full description of the expression language syntax please refer to the EE6 specification.
There are two basic expression types:
                    value expressions
                    have the form
                    #{value.property}
                    and resolve to a value
                
                    method expressions
                    have the form
                    #{bean.method(value)}
                    and result in a method invocation
                
One other difference between the form bindings and process expressions is that the work objects used by a form binding may have been pre-processed by the server so that the property values are in a form that makes more sense in the client's context. With process expressions this processing is not performed so you will be working with raw work objects.
            As an example, state is represented in a work object by an instance of the
            State
            class. In a form binding, the
            {{state}}
            expression will be bound to
            the
            name
            field of this object (e.g."ACTIVE"). The conversion from
            State
            instance to the state name string has already been performed by the server.
            The corresponding process binding,
            #{state}
            resolves to the underlying State object,
            which if it is used in a string context will be converted to a string literal, e.g.
            [State@51d838d9 name = 'ACTIVE']. To access the plain string value
            ("ACTIVE") we can use the java bean property convention to get the name:
            #{state.name}.
        
The same binding values that are used in forms (seeTable 1.1, “Standard form bindings”) can also be used in process model expressions, although in some cases the expression results will have a different type than the corresponding form binding (see the state example above for an explanation).
                The
                parent
                and
                root
                qualifiers are supported by process expressions, and
                there is also a
                self
                qualifier that refers to the current work object.
                self
                is the default qualifier, and so it's rarely needed.
            
                Work objects are referenced using IDs, and is often necessary to access not the ID itself but the
                referenced work object. To support this use case, an expression that resolves to a work object ID
                will automatically be converted to the corresponding work object instance if is followed by another expression.
                For example the expression
                #{ownerId.name}
                will extract the owner ID value, look up the
                corresponding work object (the user definition) and then access the
                name
                property of that
                work object.
            
As access to the user data for a work object is so common there are also some shortcut expressions to access this information directly:
Table 2.1. Work object user expressions
| Expression | Return type | Description | 
|---|---|---|
                                owner
                             | User work object | the work object's owner (corresponding toownerId.value)
                             | 
                                assignee
                             | User work object | the work object's assignee (corresponding toassigneeId.value)
                             | 
                The previous section showed how we can gain access to the user information relating to a work object.
                Once we have accessed the user work object there are a number of useful user properties that can be
                accessed (e.g. as#{owner.name}:
            
Table 2.2. User properties
| Property | Return type | Description | 
|---|---|---|
                                userLogin
                             | String | the user's login name (email address) | 
                                name
                             | String | the user's display name | 
                                userFirstName
                             | String | the user's first name | 
                                userName
                             | String | the user's surname | 
                                userAddress
                             | String | the user's address | 
                                userPhone
                             | String | the user's telephone number | 
                                userMobile
                             | String | the user's mobile telephone number | 
                                language
                             | String | the user's language | 
                Another difference between form binding expressions and process binding expressions is the
                visibility of work object variables within the work object hierarchy. With form binding expressions,
                accessing parent or root variables requires explicit use of the appropriate
                parent
                or
                root
                qualifier. With process expressions, however, this is not always required.
                With a process expression, variables from parent work objects in the hierarchy are also visible in the
                child work object. If a parent and child both have variables with the same name then the child
                variable will be resolved.
            
For example, take the following work object hierarchy:

                If we are resolving variables in the task context, then the expression
                #{root.message}
                will resolve to
                "Case message"
                as
                root
                refers to the case.
                The expression
                #{parent.message}
                will also resolve to
                "Case message"
                as
                parent
                refers to the process and this work object will inherit the
                message
                value from its parent (the case). The expression
                #{message}
                will resolve to
                "Task message"
                however, as the inherited variable from the case has been hidden by a more
                local value.
            
As mentioned earlier, process expressions can also be used to invoke methods and access properties of java beans. For security reasons it is obviously not a good idea to allow access to all beans within the server, and so edoras one defines a bean white-list containing the bean names that may be accessed. Exactly which beans are available will depend on the edoras one installation, but the following sections describe standard service beans that may be supported.
The process variable handling service allows process variables to be manipulated using a process service task. The following methods are provided:
#{processVariables.initVariables(execution, "variableName", "variableValue")}
                        
                                initializes variables if they have not yet been set on the process scope. Variable names and values may
                                also be provided by expressions (e.g.#{processVariables.initVariables(execution, "var", owner.name)}),
                                and multiple variable name/value pairs may also be set in one call (e.g.
                                #{processVariables.initVariables(execution, "var1", "a", "var2", "b")}).
                            
#{processVariables.setVariables(execution, "variableName", "variableValue")}
                        
                                follows the same syntax as
                                processVariables.initVariables()
                                but will overwrite
                                the variable values if the variable already exists.
                            
The modeler provides predefined task definitions for a number of common operations, including initializing variables. It will usually be easier and more reliable to use these templates instead of directly using expressions to achieve the same results.
Process expressions can be used in a number of different places within a process description. The following sections describe the details of each possible usage.
Expressions may be embedded within a task name to automatically create task names that are based on the context:

When the task is created, the expressions embedded in the task name will be replaced by the evaluation results.
                    A service task contains an
                    Expression
                    property which will evaluated when the service task is
                    created. This will typically be used to invoke a bean method that performs the required action:
                

Sequence flows can be controlled by adding a condition expression to the sequence flow transition:

                    The expression should resolve to a boolean expression using the boolean operators from the
                    EE6 specification. The sequence flow
                    will be taken when the expression resolves totrue.