Table of Contents
- Workflow Configuration
- User Experience (UX) and Usability Guidelines
- Break down big, complicated User Tasks into smaller Sub-Processes.
- Limit the number of form fields on each form.
- Provide a mapping between the real world and process flows.
- Form Types
- Form Field Types
Workflow Configuration
User Experience (UX) and Usability Guidelines
Break down big, complicated User Tasks into smaller Sub-Processes.
- People are easily overwhelmed when presented with too much complexity at once. If a User Task has too many form fields and hide/show logic in it, that's a sign you need to break it out into multiple User Tasks, encapsulated by a Sub-Process.
- By using Sub-Processes to encapsulate complexity, we can present users with only the information they need to see to accomplish one small thing at a time.
- With Sub-Processes, your diagrams will also be easier to read and share with others!
Limit the number of form fields on each form.
- Humans are very bad at holding more than 7 things in their heads at once, so limit any single form in a single User Task to 5 (7 max) fields.
- If a task requires capturing more than 7 fields, break up that task into either a linear or parallel set of User Tasks (see next point below).
Provide a mapping between the real world and process flows.
- If User Tasks really can be done at the same time, use Parallel Gateways to allow users to jump between tasks. Limit the number of parallel User Tasks to 3 (5 max).
- If some User Tasks MUST be done in order, represent those tasks as a linear sequence of tasks. Limit the number of sequential User Tasks to 3 (5 max).
Form Types
The bpmnjs/Camunda modeler provides the ability to define data entry forms associated with each User Task. There are several fields in the modeler that are used to display information on the CR Connect data entry forms, including:
General tab
Element Documentation
Text entered into the Element Documentation section of a User or Manual task appears in the header. In additional to text entry, Markdown can be used for basic formatting, like bold, underline, tables, bulleted lists, etc. The Markdown interpreter used supports most Basic and Extended formatting. If Markdown formatting falls short, HTML can be used to supplement. Jinja can also be used to inject variables from that task data into the documentation, and will allow you to do python like things within the markdown, such as looping over a list and displaying each item.
Footnotes
When defining a user task you can give the user additional information through this field displayed in a markdown style text box. If that information is long and you'd like to consolidate some of it to a popup you'll need to include a footnote. It will then show up as an info icon.
Footnote like references can be added in line to paragraphs and headings. They can occur anywhere in the text, this will result in them showing up as an info button that the user can click to view additional information. The information that is displayed for a footnote must occur somewhere in the markdown as a code block that starts with the reference.
A footnote should be in the form [^X], where X can be a number or a string. Examples of valid footnotes: [^1] or [^squirrel]
Element Documentation Text: (note, don't include that \ in front of the closing ```)
# Nature and Stuff
## Cute things
Squirrels[^6] are something some people know, and some don't.
```[^6]
# More about squirrels
* Squirrels can find food buried beneath a foot of snow. ...
* A squirrel's front teeth never stop growing. ...
* Squirrels may lose 25 percent of their buried food to thieves. ...
* They zigzag to escape predators. ...
* Squirrels may pretend to bury a nut to throw off potential thieves. ...
* A newborn squirrel is about an inch long.
\```
Will produce this effect (which opens on clicking the info button):
If you have multiple footnotes and would like to arrange them horizontally to save real estate at the top of the page, insert a non-breaking space as desired to achieve separation between elements. Use:
to add a single space 
to add 2 spaces 
to add 4 spaces
The following example uses  
:
Squirrel habitat[^1]  Acorns[^2]  Other food sources[^3]
Name field
The BPMN standard is to use a sequence when naming a User Task, e.g. Enter Study Info. The leading verb is often redundant and not needed for naming the task in the application. The application removes the first word in the Name field and uses that as a display field in the application. If the resulting string is not desired, it can be overridden using the display_name property described in the Extensions tab below.
Extensions tab
Display | Property > Id | Property > Value (example) |
---|---|---|
Change a task's display name | display_name | Can be a quoted string like "My title" or reference task data in dot notation, such as sub_invetigator.name |
Clear a task's data on reload | clear_data | True |
Form Field Types
By default, the bpmnjs/Camunda modeler supports a very limited set of form field types:
string
: Single line of textboolean
: Yes/Nolong
: Numberdate
: Date & Timeenum
: Dropdown Box
To provide more complete support for forms, we use custom types and the form field Property attributes.
You will need to add the following custom types (select custom type
in the Type dropdown):
textarea
: Multiple lines of textautocomplete
: dropdown list from spreadsheet file with optional search capabilitiesfile
: Single filefiles
: Multiple filestel
: Phone numberemail
: Email addressurl
: Website address
Then to display each of the following types of form fields, set the type and, in some cases, add a custom property with the listed value.
Display | Type | Property > Id | Property > Value |
---|---|---|---|
Text input box (single line) | string |
leave blank | leave blank |
Number input box | long |
leave blank | leave blank |
"Yes/No" radio buttons | boolean |
leave blank | leave blank |
"Yes/No" checkbox | boolean |
boolean_type |
checkbox |
Date picker | date |
leave blank | leave blank |
Dropdown box | enum |
leave blank | leave blank |
Checkboxes | enum |
enum_type |
checkbox |
Radio buttons | enum |
enum_type |
radio |
Textarea (multi-line text) | textarea (Custom Type) |
(optional properties below) | |
rows |
a number, e.g., 20 |
||
cols |
a number, e.g., 20 |
||
autosize |
true|false |
||
Single File | file (Custom Type) |
leave blank | leave blank |
Multiple Files | files (Custom Type) |
leave blank | leave blank |
Telephone number | tel (Custom Type) |
leave blank | leave blank |
Email address | email (Custom Type) |
leave blank | leave blank |
Web address | url (Custom Type) |
leave blank | leave blank |
Min/Max Values
To limit the length of a text input or textarea field, add the following Validation Constraint(s):
Constraint > Name | Constraint > Config |
---|---|
min_length |
a number, e.g., 1 |
max_length |
a number, e.g., 999 |
To limit the values in a number field, add the following Validation Constraint(s):
Constraint > Name | Constraint > Config |
---|---|
min |
a number, e.g., 1 |
max |
a number, e.g., 999 |
Grouping Fields
If a set of fields belong together, you can add a group
property:
Property > Id | Property > Value (example) |
---|---|
group |
Contact Information |
All fields with that same group name will be gathered together and displayed in a single box in the form.
Repeating Sections
If you want a user to be able add multiple groups of fields, you can add a repeat
property:
Property > Id | Property > Value (example) |
---|---|
repeat |
ConInfo |
repeat_title |
Add information for each Contact Type |
repeat_button_label |
Add Contact Info |
All fields with that same repeating section name will be gathered together and displayed in a dialog in the form. Note that the repeat_title
and repeat_button_label
must be on the first Form Field in the repeat series.
Hiding a repeating section
To hide the repeating section based on the value of some other field, add a repeat_hide_expression
property to the first field in the repeating section (i.e., the set of fields with the same repeat
property value):
Property > Id | Property > Value (example) |
---|---|
repeat_hide_expression |
someFieldName !== 'Some Value' |
Making a repeating section required
By default a repeating section does not require that anything be added. Clicking of its associated Save button will close the repeating section with no entries. In some cases you may want to required that at least one repeating section be added and saved. This can be done by adding the repeat_required
Constraint to the first field in the repeating section.
Constraint > Name | Constraint > Config (example) |
---|---|
repeat_required |
True (False by default) |
Default values
For any form field, you can enter a value that will automatically populate the form field (unless the user has previously entered and saved a value in that field). Be aware that each form field type will expect different types of default values:
Field Display Type | Default Value (example) | Restrictions |
---|---|---|
Text input box (single line) | ABC, abc, 123, $%^ |
Any alphanumeric characters or punctuation |
Number input box | 12345.678790 |
Only integers or decimal numbers |
"Yes/No" radio buttons | true |
Only the values true or false |
Date picker | 2020-02-18T16:35:07.842Z |
A date in the format YYYY-MM-DDTHH:mm . See this link for more details |
Dropdown box | some value |
Must exactly match one of the values in the values list |
Checkboxes | some value |
Must exactly match one of the values in the values list |
Radio buttons | some value |
Must exactly match one of the values in the values list |
Textarea (multi-line text) | ABC, abc, 123, $%^ |
Any alphanumeric characters or punctuation. Line breaks are not supported (for now) |
Single File | null | |
Multiple Files | null | |
Telephone number | (800) 987-6543 |
Validly-formatted U.S. phone number, with or without punctuation |
Email address | some.email@email-server.com |
Validly-formatted email address |
Web address | https://some.web-address.edu |
Valid full URL, including the http:// or https:// at the beginning |
Read-only fields
Fields can be locked so the user won't be able to edit them.
Property > Id | Property > Value (example) |
---|---|
read_only |
True |
Read_only_expression
Fields can be locked so the user won't be able to edit them dynamically, i.e., based on an expression.
Property > Id | Property > Value (example) |
---|---|
read_only_expression |
isReadOnly |
Hiding fields
Fields can be hidden and shown conditionally with an expression.
Property > Id | Property > Value (example) |
---|---|
hide_expression |
boolean (hide when Yes is selected): someBooleanFieldName |
boolean (hide when No is selected): !(someBooleanFieldName) |
|
boolean (hide when no selection made yet): not someBooleanFieldName |
|
enum: enumFormFieldID == 'enumValueId' or enumFormFieldID != 'enumValueId' |
|
date: None |
Required fields
To make a field required by default, add the following Validation Constraint:
Constraint > Name | Constraint > Config |
---|---|
required |
True |
If a field needs to be filled out based on the value of some other field(s) in the form, you can use a Python expression (see above).
Property > Id | Property > Value (example) |
---|---|
required_expression |
boolean (required when Yes is selected): someBooleanFieldName |
boolean (required when No is selected): !(someBooleanFieldName) |
|
boolean (required when no selection made yet): someBooleanFieldName == null |
|
enum: enumFormFieldID == 'enumValueId' |
Help text
There are three places where help text will be displayed on the front end when the form is rendered:
- Placeholder text: appears within the field if it is empty
- Description text: appears below the field
- Formatted description text: appears below the description text. Markdown formatting code is supported for this field.*
- Help dialog text: appears in a pop-up when the
?
button next to the field is clicked. Markdown formatting code is supported for this field.*
* Please note that you will need to replace all line breaks with \n
(for now).
To display each type of help text, add a custom property:
Type of help text | Property > Id | Property > Value (example) |
---|---|---|
Placeholder text | placeholder |
Enter your email address here |
Description text | description |
Upload a digitally-signed PDF file that is no more than 1GB in size. |
Formatted description text | markdown_description |
# Heading 1\n\nMarkdown text goes here. |
Help dialog text | help |
# This is a large heading\n\nParagraph of text goes here.\n\nThe next paragraph goes here. You can even insert [links](https://sartography.com)!\n\nThis is a list:\n- Apples\n- Oranges\n- Bananas |
Dynamic labels
If the text label of a field needs to change based on the value of some other field(s) in the form, you can use a Formly Javascript expression (see above). The example below uses a ternary (if/then) operator to display a different label if the string field dogName
is filled out. (Note that the double !
at the beginning of the example converts the string field to a boolean, returning true
if there is a value and false
if there is not a value.)
Property > Id | Property > Value (example) |
---|---|
label_expression |
!!model.dogName ? 'How old is ' + model.dogName + '?' : 'How old is your dog?' |
Dynamic default values
If you want to populate the default value of a field with the output of a Formly Javascript expression, add a value_expression
property.
Property > Id | Property > Value (example) |
---|---|
value_expression |
otherFieldName |
Populating enum
Dropdown Field Options
Dropdown fields, checkbox groups, and radio button groups can all have their options populated from two different dynamic sources: spreadsheets and task data.
Populating options from a spreadsheet
Dropdown values can be read from a separate spreadsheet if it becomes cumbersome to maintain them in the BPMN diagram. Set the type to enum and use the following properties to read the values in from a file:
Property > Id | Property > Value | Example |
---|---|---|
spreadsheet.name |
file name of spreadsheet used | customer_list.xls |
value.column |
This is what will be saved in the task data. | CUSTOMER_NUMBER |
label.column |
This value will be displayed in the drop down (or searched, see later). | CUSTOMER_NAME |
Populating options from current task data
Dropdown values can be read from the current task data as well. Set the type to enum and use the following properties to read the values in from a file:
Property > Id | Property > Value | Example |
---|---|---|
data.name |
list in the task data to use to populate the enum field |
See code block below table |
value.column |
This is what will be saved in the task data. | value |
label.column |
This value will be displayed in the drop down (or searched, see later). | label |
sponsors = study_info("sponsors")
spon_enum = [{'value':sponsor['SPONSOR_ID'], 'label':sponsor['SP_NAME']} for sponsor in sponsors]
LDAP Dropdown fields.
You may need to search for personnel against the ldap server. In this case:
- Use the Type ->
custom type
option addautocomplete
- Add an ldap.lookup property to the field, so we know this field should search ldap records.
Properties
Property > Id | Property > Value | Example |
---|---|---|
ldap.lookup |
True | True |
value.column |
This is what will be saved in the task data. | uid |
label.column |
This value will be displayed in the drop down (or searched, see later). | display_name |
Note: The autocomplete features for LDAP fields works by typing in a Computing ID, e.g. dhf8r, or the format Last Name, Fist Name, e.g. Funk, Daniel
Searchable Dropdown Fields
If the enum list is too long, you can turn it into an auto-complete field. At which point it will only be populated as the user types into the field.
- Use the Type ->
custom type
option addautocomplete
- The default number of hits in the resulting list as the user types is 5.. This number can be changed by adding an
autocomplete_num
Property and entering the desired number of results displayed as a numeric value in the Value field.
Property > Id | Property > Value | Example |
---|---|---|
autocomplete_num | integer > 0 | 15 |
Note: Currently Searchable Dropdown Fields does not work for enum lists populated from Task Data
Timer Events
Timer Definition Type | Timer Definition Example(s) | Example Explanation |
---|---|---|
Cycle | (3,timedelta(minutes=10)) | Execute timer event event three times every 10 minutes |
Date | datetime.datetime.strptime('2020-10-29','%Y-%m-%d') or datetime.datetime.now() + timedelta(days=5) | Execute the time event on October 29, 2020 or execute the timer event 5 days from now |
Duration | timedelta(minutes=10) | Execute timer event event after 10 minutes |
Notes:
- The shortest duration the timer engine will support at this time is 1 minute.
- The current_user likely will not be available during a Timer Event. The current_user is only established when a user physically opens a workflow.