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 serves as the "configuration file" for 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 consists of two objects: stages and workflows.
The stage definition must include a next definition, specifying what should happen if a stage is approved (Form.Status == Approved). The form will progress to the next stage when all defined workflows of the current stage have successfully completed, or it will finish if only one stage is defined.
{
"stages": {
"stage_1": {
"first": true,
"label": "Stage 1",
"appKioskMode": false,
"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. |
| appKioskMode | Boolean | "appKioskMode": false | De/activate App Kiosk Mode button for this stage. App Kiosk Mode must be enabled for form (App Kiosk Mode). Default value is true. |
| 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 toolbar 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: 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".
Workflow Definitions
Common
Common options for every workflow option typically include type specifications and error handling mechanisms (such as retries, logging, and notifications).
type - required
"type": "pdf"stringerrorAction
"errorAction": "ignore / status=Edit[, stage] / fields={"fieldname": "fieldvalue", ...}"stringerrorFeedback
"errorFeedback": "Email dispatch failed."stringerrorNotify
"errorNotify": "admin@example.com"stringerrorNotifyFrom
"errorNotifyFrom": "admin@example.com"stringerrorNotifyReplyTo
"errorNotify": "admin@example.com"stringerrorNotifySubject
"errorNotifySubject": "Workflow error"stringerrorNotifyTemplate
"errorNotifyTemplate": "errortemplate.txt"stringtype: pdf
create
false, if you want to prevent PDF creation at this time of workflow processing."create": falsebooleanlanguage
"language": "De"stringtype: copypdf
target - required
"target": "stage2.pdf"stringtype: condition
condition - required
==) 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. See more examples here."condition": "{field} != True"stringisEnhanced
"isEnhanced": truebooleantype: 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. See more examples here.
filename - required
"filename": "form.xlsx"stringtemplate - required
"template": "excel_template.xlsx"stringtype: email
Send an email. At a minimum, a subject and at least one recipient (to, cc or bcc) must be specified
subject - required
"subject": "HybridForms: Form Approved"stringattachDocuments
"attachDocuments": "^stage2.pdf$, ^uploadedDocument.docx$"stringattachEmlDocument
"attachEmlDocument": "mail.eml"stringattachImage
"attachImage": "form-logo.png"stringattachImages
"attachImages": truebooleanattachPDF
"attachPDF": truebooleanattachTemplateFiles
"attachTemplateFiles": ["Example.pdf"]Arraybcc
"bcc": "{email-address1},{email-address2}"stringbody
"body": "A new form {title} has been approved"stringcc
"cc": "{email-address1},{email-address2}"stringfilename
"filename": "attachFile.pdf"stringformat
"format": "text"stringreplyTo
"replyTo": "recipient@example.com"stringtemplateFile
"templateFile ": "mailtemplate.txt"stringto
"to": "{email-address1},{email-address2}"stringurgent
"urgent": truebooleantype: newform
fields
"fields": {"name" : "{name_textfield}", "date": "{work_date}",...}{ [key: string]: string }formUpdateModel
"formUpdateModel": "{\"title\": \"newTitle\", \"fields\": {\"field1\": \"{control01}\"}}"stringgroup
"group": "hf-group"stringjsonEscapeModel
"jsonEscapeModel": truebooleanowner
"owner": "user@hybridforms.net"stringstage
"stage": "S3"stringstatus
"status": "Edit"stringtemplate
"template": "bc40e199-e8a1-4a4f-9b53-a5e8f16154c0"stringtype: request
url - required
"url": "https://example.com/api/endpoint"stringauthenticationType
"authenticationType:" "Adfs"stringbodyFile
"bodyFile": "somefile.xml"stringbodyFilePattern
"bodyFilePattern"=".*\.pdf$"stringcertificate
"certificate": "MIILSQIBAzCCCw8GCSqGSI....=="stringcertificatePassword
"certificatePassword": "{secret}"stringclientSecret
"clientSecret": "exampleSecret"stringfields
"fields": {"fld1":"result_data_fld1",...}{ [key: string]: string }formUpdateModel
"formUpdateModel": "{\"fields\": {\"field1\": \"{result_value1}\"}}"stringheaders
"headers": {"X-Access-Token":"1234",...}{ [key: string]: string }impersonate
"impersonate": falsebooleanjsonEscapeModel
"jsonEscapeModel:" falsebooleanlogResponse
"logResponse:" falsebooleanmessage
"message": "Status code '{result_returnCode}' returned by service. Error: {result_message}"stringmetaData
"metaData": "https://adfs.example.com/adfs/.well-known/openid-configuration"stringpassword
"password": "examplePassword"stringrequestType
"requestType": "POST"stringresourceId
"resourceId": "ClientID"booleanretryDelay
"retryDelay":300numberskipRetryStatus
"skipRetryStatus" = "^2"stringsuccess
"success": "{result_returnCode}==0"stringsuccessIsEnhanced
"successIsEnhanced:" falsebooleantimeout
"timeout": 300numberuserName
"userName": "exampleUser"stringtype: xmlrequest
Send XML formated data to the service.
url - required
"url": "https://example.com/api/endpoint"stringauthenticationType
"authenticationType:" "Adfs"stringbodyFile
"bodyFile": "somefile.xml"stringbodyFilePattern
"bodyFilePattern"=".*\.pdf$"stringcertificate
"certificate": "MIILSQIBAzCCCw8GCSqGSI....=="stringcertificatePassword
"certificatePassword": "{secret}"stringclientSecret
"clientSecret": "exampleSecret"stringfields
"fields": {"fld1":"result_data_fld1",...}{ [key: string]: string }formUpdateModel
"formUpdateModel": "{\"fields\": {\"field1\": \"{result_value1}\"}}"stringheaders
"headers": {"X-Access-Token":"1234",...}{ [key: string]: string }impersonate
"impersonate": falsebooleanjsonEscapeModel
"jsonEscapeModel:" falsebooleanlogResponse
"logResponse:" falsebooleanmessage
"message": "Status code '{result_returnCode}' returned by service. Error: {result_message}"stringmetaData
"metaData": "https://adfs.example.com/adfs/.well-known/openid-configuration"stringpassword
"password": "examplePassword"stringrequestType
"requestType": "POST"stringresourceId
"resourceId": "ClientID"booleanretryDelay
"retryDelay":300numberskipRetryStatus
"skipRetryStatus" = "^2"stringsuccess
"success": "{result_returnCode}==0"stringsuccessIsEnhanced
"successIsEnhanced:" falsebooleantimeout
"timeout": 300numbertransformFile
"transformFile": "nameofxsltemplate.xslt"stringuserName
"userName": "exampleUser"stringtype: jsonrequest
Send JSON data to the service.
url - required
"url": "https://example.com/api/endpoint"stringauthenticationType
"authenticationType:" "Adfs"stringbodyFile
"bodyFile": "somefile.xml"stringbodyFilePattern
"bodyFilePattern"=".*\.pdf$"stringcertificate
"certificate": "MIILSQIBAzCCCw8GCSqGSI....=="stringcertificatePassword
"certificatePassword": "{secret}"stringclientSecret
"clientSecret": "exampleSecret"stringfields
"fields": {"fld1":"result_data_fld1",...}{ [key: string]: string }format
"format": "Minimal/Brief/Full/Repeating"stringformUpdateModel
"formUpdateModel": "{\"fields\": {\"field1\": \"{result_value1}\"}}"stringheaders
"headers": {"X-Access-Token":"1234",...}{ [key: string]: string }impersonate
"impersonate": falsebooleanincludeCharset
"includeCharset": truebooleanincludeFiles
"includeFiles": truebooleanjsonEscapeModel
"jsonEscapeModel:" falsebooleanlogResponse
"logResponse:" falsebooleanmessage
"message": "Status code '{result_returnCode}' returned by service. Error: {result_message}"stringmetaData
"metaData": "https://adfs.example.com/adfs/.well-known/openid-configuration"stringpassword
"password": "examplePassword"stringrequestType
"requestType": "POST"stringresourceId
"resourceId": "ClientID"booleanretryDelay
"retryDelay":300numberskipRetryStatus
"skipRetryStatus" = "^2"stringsuccess
"success": "{result_returnCode}==0"stringsuccessIsEnhanced
"successIsEnhanced:" falsebooleantimeout
"timeout": 300numberuserName
"userName": "exampleUser"stringtype: execute
Call an executable or a script on the server. Special parameter {PDF} refers to the path of a copy of the form.pdf file.
program - required
"program": "path_to_script_on_server"stringarguments
"arguments": "{templateId} {itemId}"stringfields
{"control01": "{result_value1}"}{ [key: string]: string }files
{"result_file.jpg": "{result_files_image}"}{ [key: string]: string }formUpdateModel
"formUpdateModel": "{\"fields\": {\"field1\": \"{result_value1}\"}}"stringjsonEscapeModel
"jsonEscapeModel": falsebooleantimeout
"timeout": "300"numbertype: setowner
owner - required
"owner": "{field}"stringtype: setcurrentowner
owner - required
"owner": "{field}"stringtype: setstatus
status - required
"status ": "Archived"stringtype: setcurrentstatus
status - required
"status ": "Archived"stringtype: setgroup
group - required
"group": "grp_admin"stringtype: setcurrentgroup
group - required
"group": "grp_admin"stringtype: setfield
This option is deprecated; we recommend using formupdate instead.
field - required
"field": "control01"stringvalue - required
"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}."value" : "new value"stringtype: setfeedback
feedback - required
"feedback" : "Feedback message"stringtype: stagechange
stage - required
"stage": "stage_3"stringtype: updatecatalogentries
catalogName - required
"catalogName": "catalog_name"stringentries
"entries": "{catalog_entries}"stringentriesObject
"entriesObject": [ { "Fields": { "ID": "{id_catalog}", "Berichtsjahr": "{berichtsjahr_catalog}", "Bestellnummer": "{bestellnummer_catalog}" } } ]arraytype: deletecatalogentries
catalogName - required
"catalogName": "catalog_name"stringentryIds
"entryIds": "{ItemID}"stringentryIdsObject
"entryIdsObject": ["ID1", "ID2", "ID3"]arraytype: stop
stopWithError
true, the workflow will terminate with an error, and all previous steps will be undone. If set to false, the workflow will stop at the current stage, and earlier workflows will be completed as usual."stopWithError": truebooleantype: formupdate
formUpdateModel - required
"formUpdateModel": "{\"fields\": {\"field1\": \"{result_value1}\"}}"stringjsonEscapeModel
"jsonEscapeModel": falsebooleanWorkflow 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 |
| CatalogPath | Filesystem path for the cached catalogs used by the item |
| AssetPath | Filesystem path for the cached assets |
| 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 - you probably want the owner instead |
| EditorEmail | Email of this user (if any) |
| EditorID | The ID (UPN) of the user who last changed the form |
| FormPath | Filesystem path with the files attached to the item |
| Group | The name of the currently 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 |
| Now | Current Timestamp (UTC) in ISO8601 Format |
| Owner | The user who owns the form - this need not be the editor! |
| OwnerEmail | Email of this user (if any) |
| OwnerID | The ID (UPN) of the user who owns the form |
| content of form.pdf (only for exec and request workflows) | |
| ReachoutUrl | Url to Reachout form |
| ReachoutConfirm | Url to Reachout confirm form |
| ServerUrl | Base url of HybridForms server |
| Stage | 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 |
| TemplatePath | Filesystem path for the cached template for by the item |
| Title | The form "Title" |
| Version | The current version number of the Form Item |
| XML | XML representation of the Form Item (only for exec and request workflows) |
Form Definition
Conditions
The visibility of HybridForms elements (e.g. pages, tabs, blocks, fields, etc.) can 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>
<li>...</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-hf-bind="textContent: data.stage.id"></span>
<span data-hf-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" />