Stages and Workflows
The steps of the form processing workflow ("stages") can be defined by a JSON file. This file is named "stages.json" and can be provided as part of your template definition.
Note: "Stages" require a Server version 7.2.* or higher AND an App version 7.3 or higher!
JSON file
The JSON file represents the "configuration file" of stages and workflows initialized by clicking the toolbar button "approve".
Unless a stages.json file is provided the form definition is processed in "stage 1" with all default settings.
The JSON file consist of two objects "stages" and "workflows".
The stage definition has to contain a "next" definition which defines what should happen if a stage is approved (Form.Status == Approved).
The form will move on to the next stage when all defined workflows of the previous stage have finished sucessfully or finish if only on stage is defined.
{
"stages": {
"stage_1": {
"first": true,
"label": "Stage 1",
"next": {
"stage": "stage_2",
"workflows": ["wf_pdf","wf_cond1" "wf_email1", "wf_grp1", "wf_excel" ],
"buttonLabel": "Approve Stage 1: {{field_id}}",
"dialogTitle": "Approve dialog title",
"dialogMessage": "Message text of the approve dialog - Finishing {{field_id}}"
},
"stateChanges": {
"Group": {
"workflows": [ "wf_email1" ]
}
}
},
"stage_ ...": {
},
"stage_final": {
"label": "Stage final",
"next": {
"workflows": [ "wf_archive" ]
}
}
},
"workflows": {
"wf_pdf": {
"type": "pdf",
"create": true
},
"wf_email1": {
"type": "email",
"to": "office@icomedias.com",
"subject": "New HybridForms process created ",
"body": "A new HybridForms process was created.",
"erroraction": "ignore",
"errorfeedback": "Notification could not be sent",
"errornotify": "admin@icomedias.com",
"filename": "email-filename.pdf",
"attachPDF": true,
"attachImages": true,
"attachimage":"form-logo.png"
},
"wf_email2" : {
"type": "email",
"to": "office@icomedias.com",
"subject": "A new form",
"template": "mailtemplate.txt"
},
"wf_grp1": {
"type": "setgroup",
"group": "icoad\\ag-sachbearbeiter"
},
"wf_current_grp": {
"type": "setcurrentgroup",
"group": "icoad\\ag-mitarbeiter"
},
"wf_archive": {
"type": "setstatus",
"status": "Archived"
},
"wf_current_archived": {
"type": "setcurrentstatus",
"status": "Archived"
},
"wf_cond1": {
"type": "condition",
"condition": "{field} != True"
},
"wf_newValue": {
"type": "setfield",
"field": "fieldID",
"value": "new Value"
},
"wf_newCheckboxValue": {
"type": "setfield",
"field": "fieldID",
"value": "{true}"
},
"wf_newRadioboxValue": {
"type": "setfield",
"field": "fieldID",
"value": "{null}"
},
"wf-newform": {
"type": "newform",
"title": "{Title}",
"template": "bc40e199-e8a1-4a4f-9b53-a5e8f16154c0",
"status": "Edit",
"stage": "S1",
"owner": "user@hybridforms.net",
"group": "hf-group",
"fields": {
"name" : "{name_textfield}",
"date": "{work_date}"
}
},
"wf_owner": {
"type": "setowner",
"owner": "{fieldValueUPN}"
},
"wf_current_owner": {
"type": "setcurrentowner",
"owner": "{Editor}"
},
"wf_excel": {
"type": "createexcel",
"template": "excel_template.xlsx",
"filename": "form.xlsx",
"errorNotify": "admin@icomedias.com",
"errorFeedback": "Fehler beim Erzeugen des Excel"
}
}
}
Workflows executed by finishing a "one-stage" form item must be defined inside a stages.json as well, simply skip the entry "stage" inside the "next" object.
"S1": {
"first": true,
"label": "Default Stage",
"next": {
"workflows": ["wf_email"]
}
}
If the stage enging is enabled, the app kiosk mode is disabled by default. The app kiosk mode could be activated for a specific stage.
Stages and workflows can also be created and edited in the Admin UI. Go to the formdefinition template, in the section "stages" click the "Edit"-button.
Stage object
Configure a stage object by specifying a custom name (e.g. "stage_1" ) and the values for the keys label
, next
, stagechanges
and once first
.
The key-value pairs label
, next
and first
are required and first
must be unique.
Property | Type | How to use | Description |
---|---|---|---|
first | Boolean | "first": true | Specify the stage where to start. |
label | String | "label": "Stage 1" | Set the ID/name of the stage used in your form for conditions |
next | Object | "next": { } | Define the options of the workflows initialized by finishing the stage |
../stage | String | "next": {"stage":"stage_final"} | Set the stage processed next |
../workflows | JSON Array | "next": {"workflows": ["wf_pdf","wf_cond1" "wf_email1", "wf_grp1"] } | Specify the workflows invoked by finishing the stage |
../buttonLabel | String | "next": {"buttonLabel":"Approve Stage 1: {{field_id}}"} | For better usability define an appropriate label of the "Approve" button in the form tool bar for each stage. {{field_id}} placeholder gets replaced by list data value. |
../dialogTitle | String | "next": {"dialogTitle": "Approve dialog title"} | Specify the title of the approve dialog for each stage. {{field_id}} placeholder gets replaced by list data value. |
../dialogMessage | String | "next": {"dialogMessage": "Message text of the approve dialog"} | Specify the approve dialog message text for each stage. {{field_id}} placeholder gets replaced by list data value. |
stateChanges | Object | "stateChanges": { "Group": {"workflows": [ "wf_email1" ] } } | Define the workflows invoked by changing the form's status in the stage's life cycle. |
Workflow object
Define all your workflows invoked by stage or status changes.
These workflows can be used multiple times and can be of different types as there are: conditions, requests, emails sent or changes of the form item meta data (e.g the owner or the assigned group).
The workflows are processed in order of the JSON array position. A workflow of "type": "condition"
is applied to all following workflows until a new condition is defined.
in the example {"workflows": ["wf_pdf","wf_cond1", "wf_email1", "wf_grp1"]}
the condition of the workflow "wf_cond1"
controls the execution of workflow "wf_email1"
and "wf_group"
.
Property | Additional Property | Type | How to use | Description |
---|---|---|---|---|
type | String | "type": "pdf" | Set the type of the workflow, further properties are available depending on type. | |
errorAction | String | `"errorAction": "ignore" | "status=Edit/..."` | |
errorFeedback | String | "errorFeedback": "Email dispatch failed. " | Provide an error message (List page feedback dialog). | |
errorNotify | String | "errorNotify": "admin@domain.net | Provide an email address for an error notification email. | |
type: pdf | create | boolean | "create": "true" | Set option to false, if you want to prevent pdf creation at this time of workflow processing |
type: copypdf | target | String | "target": "stage2.pdf" | Provide a filename, the form.pdf is copied and stored as attached document of the form item. |
type: condition | condition | String | "condition": "{field} != True" | Define the condition to evaluate. Test for equality ("==") or inequality ("!="), please use uppercase for testing boolean values (True / False).To check if a form field value is null or empty compare the form field to a fake (i.e. not existing) form field. |
type: createexcel | Creates an excel with data of the form based on an excel template file that contains form field replacers. These replacers are contained in double curly braces, eg: {{field_id}} , in an excel cell. | |||
template | String | "template": "excel_template.xlsx" | Provide the filename of the excel template that is included in the formdefinition template files. | |
filename | String | "filename": "form.xlsx", | Provide a filename for the excel output file. | |
type: email | to | String | "to": "{email-address1},{email-address2}" | Set the recipient's email address(es). |
cc | String | "cc": "{email-address1},{email-address2}" | Set additional email address(es). | |
bcc | String | "bcc": "{email-address1},{email-address2}" | Set additional email address(es) not shown in header. | |
from | String | "from": "{email-address1}" | Set sender Address. | |
subject | String | "subject": "HybridForms: Form Approved" | Provide a subject line. | |
body | String | "body": "A new form {title} has been approved" | Provide a short email body message. You can include values of form fields. | |
bodyFile | String | "bodyFile ": "mailtemplate.txt" | Provide an email template file for more complex email content. | |
attachPDF | Boolean | "attachPDF": true | Set the value to true to attache the form.pdf to the email. | |
filename | String | "filename": "attachFile.pdf" | Rename the form.pdf file attached to the email, note: this does not affect the stored form.pdf. | |
attachDocuments | String | "attachDocuments ": "stage2.pdf, uploadedDocument.docx" | Attach the named documents made avaliable by the app feature "Documents" to the email | |
attachImages | Boolean | "attachImages": true | attach all images (photos/sketches etc) contained in the form. | |
attachimage | String | "attachimage": "form-logo.png" | attach an image from the form template and make it available for reference inside your mailtemplate.txt. | |
type: newform | status | String | "status": "Edit" | Specify the status of the new form. |
stage | String | "stage": "S3" | Specify the stage of the new form. | |
title | String | "title": "{Title}" | The new form inherits the title of the current form. | |
template | String | "template": "bc40e199-e8a1-4a4f-9b53-a5e8f16154c0" | Specify the template id of the new form if the created form is not of the same type. | |
owner | String | "owner": "user@hybridforms.net" | Specify the owner of the new form if the new form should be assigned to a diffenet editor. | |
group | String | "group": "hf-group" | Specify the group of the new form if the new form should be assigned to a diffenet group. | |
fields | String | "fields": {"name" : "{name_textfield}", "date": "{work_date}",...} | Specify the form fields and the values inherited by the new form. | |
type: request | url | String | "url": ".....", | Specify the URL to connect to. |
requesttype | String | "requestType": "POST" | Define the request method ("POST" or "GET"). | |
impersonate | Boolean | "impersonate": false | Set the value to true to call the service authenticated as the user submitting the form. | |
resourceId | String | "resourceId": "ClientID" | Set the ADFS/AzureAD identity of the called service for impersonation. | |
timeout | int | "timeout": 300 | Timeout in seconds for calling the specified service. Default 100 seconds. | |
success | String | "success": "{result_returnCode}==0" | Conditional expression to verify successfull completion. Fields from a Json or XML body returned by the service can be referenced. | |
message | String | "message": "Status code '{result_returnCode}' returned by service. Error: {result_message}" | template for the history entry in case the success condition is not met | |
fields | Dictionary | "fields": {"fld1":"result_data_fld1",...} | List of fields to set in the form using values from the body returned by the called service. | |
headers | Dictionary | "headers": {"X-Access-Token":"1234",...} | List of additional http headers to set when calling the service | |
type: xmlrequest | Send XML formated data to the service; this is an extension to request, so all fields from request apply, plus additional properties | |||
transformFile | String | "transformFile": "nameofxsltemplate.xslt" | Provide an XSLT file for transformation of HybridForms XML to POST body. | |
type: jsonrequest | Send JSON data to the service; this is an extension to request, so all fields from request apply, plus additional properties | |||
format | String | "format": "Minimal/Brief/Full/Repeating" | Specify how complete the information in JSON should be, same as can be specified when requesing forms using the API. | |
includeFiles | Boolean | "includeFiles": true | set to true to include attachment binary data in "files" property (as "base64Content" ) | |
includeCharset | Boolean | "includeCharset": true | set to true to include charset attrribute in the content type ("application/json; charset=utf-8") | |
type: execute | Call an executable or a sctript on the server. Special parameter {PDF} refers to the path of a copy of the form.pdf file | |||
program | String | "program": "path_to_script_on_server" | location on the server of a script to execute | |
arguments | String | "arguments": "{templateId} {itemId}" | parameters to pass to the called script or program | |
type: setowner | owner | String | "owner": "{field}" | Change the owner of the form item when proceeding to the next stage. |
type: setcurrentowner | owner | String | "owner": "{field}" | Change the owner of the form item in the current stage. |
type: setstatus | status | String | "status ": "Archived" | Define the new form item status ("New", "Edit","Group", "Approved" or "Archived") when proceeding to the next stage. |
type: setcurrentstatus | status | String | "status ": "Archived" | Define the form status ("New", "Edit","Group", "Approved" or "Archived") in the current stage. |
type: setgroup | group | String | "group": "grp_admin" | Define a new group assignment when proceeding to the next stage. |
type: setcurrentgroup | group | String | "group": "grp_admin" | Define a new group assignment in teh current stage. |
type: setfield | field | String | "field": "fieldID" | Define the fieldID of a form field to be changed .. |
value | String | "value" : "new value" | Define the new value of the defined form field at stage change. Enter the new value by using the variant string "new value" or by referencing a field value {{another fieldID}} or set the value of RadioBoxes or CheckBoxes using the variant {true}, {false} or {null} | |
type: stagechange | stage | String | "stage": "stage_3" | Define a stage to proceed out of the predefined stage order. |
Workflow data
Besides any form field value (i.e addressed by {form field id}
) you can use the following server meta data:
Property | Description |
---|---|
Author | the name of the user who created the form |
AuthorEmail | email of this user (if any) |
AuthorID | the ID (UPN) of the user who created the form |
ClientId | the ID of the sub system the form belongs to |
Created | Creation date of the form item (datetime in UTC format) |
Created_Date | Creation date of the form item - dateOnly |
Created_HFLocal | "Local" creation time of the form item |
Created_Time | Creation time of the form item |
Culture | the HF.Culture field from the form definition |
DisplayVersion | the version of the form at the time of PDF generation/ of the workflow action |
Editor | the user who last changed the form |
EditorEmail | email of this user (if any) |
EditorID | the ID (UPN) of the user who last changed the form |
Group | the name of the currently to the form item assigned group |
ItemID | HF.ItemID field |
Modified | Date of the last modification of the form item (datetime in UTC format) |
Modified_Date | Date of the last modification of the form item - dateOnly |
Modified_Time | Only the time of the last modification of the form item |
Modified_HFLocal | The "local" time of the last modification of the form item |
Owner | the user who owns the form - this must not be the editor!! |
OwnerEmail | email of this user (if any) |
OwnerID | the ID (UPN) of the user who owns the form |
ReachoutUrl | Url to Reachout form |
ReachoutConfirm | Url to Reachout confirm form |
ServerUrl | Base url of HybridForms server |
StageID | the id of the current form stage |
StageLabel | the label of the current form stage |
Status | value of the HF.Status field |
TemplateID | HF.FormID of the form definition |
TemplateName | the name of the form definition |
Title | the form "Title" |
Version | the current version number of the form item |
Note: You can use all these server meta data to generate a PDF filename except the time values because of the time format - a colon is not allowed!
Form definition
Conditions
The visibilty of HybridForms elements (e.g. pages, tabs, blocks, fields, etc.) would be defined by a new condition type "stage". The "val" configures the relevant stages.
<form>
...
<li data-hf-title="Repair"
data-hf-condition='{
"cond": [{
"type": "stage",
"id": "stage_2",
"val": true
}],
"else": "readonly"
}'>
<a href="#repair-block1"></a>
<a href="#repair-block2"></a>
<li>
...
</form>
list-/headerTemplate
The stage id and stage label can be used by the list-/headerTemplate as well. Access the information by "data.stage.id" and "data.stage.label".
<form>
...
<span data-win-bind="textContent: data.stage.id"></span>
<span data-win-bind="textContent: data.stage.label"></span>
...
</form>
Images in mailtemplate.txt
Attached images can be referenced inside your email body by the HTML tag img
and the path prefix `cid.
<img src="cid:logo.png">