The advanced, special workflow component, Run a script can be used in order to call a script from the workflow.
The JavaScript execution engine supports ECMAScript v5.1 with the addition of the following ECMAScript 6 features:
The component has these parameters:
Note that the objects that are specific to JavaScript being run in a browser, are not available. For instance "window" and "document" are not defined.
One exception is the "console" object which is available in a limited version. The console object can be used to write to the workflow job log. For instance:
console.log("Info message");
Will write an info message to the job log.
The following methods are available on the console object for logging with different log levels:
It is possible to load other JavaScript files into the script by using the load() function. The argument can be a URL or a file system path. Note that file system paths have to be the path on the operating system's file system, not the path within the InterFormNG2 virtual file system. The full path to the file should be used. If the underlying operating system is Windows, then double-backslash (\\) can be used as backslash in the file name. Alternatively single slash (/) can always be used.
Example:
load("C:/ProgramData/InterFormNG2/resources/home/other/script/otherjs.js");
Accessing workflow variables and payload
Workflow variables
All workflow variables can be used as global variables within the JavaScript code. Note however that a lot of the pre-defined workflow variables contain a dot (.) character. This is not allowed in JavaScript variable names, so for all variable names the dot will be replaced with an underscore (_). Apart from that, it is your own responsibility to ensure that workflow variables have names that are valid in JavaScript (most importantly you should avoid variable names that are reserved words in JavaScript).
Note that if you set a JavaScript variable to a numeric value, it will become a floating point number in the workflow variable, even if an integer value has been set. This can be important to know when comparing the value.
Please notice, that the global values of the script are mixed with the workflow variables. The advantage is, that the workflow and the script can exchange information in that way (apart for the payload), so that the script can read the values set prior to the call of the script and the script can change the values of the workflow variables, which are used in the subsequent workflow components.
You should however also ensure, that you might not by accident share the same name of a workflow variable and then change the value in the script, which of course can considered as a problem, if this share of a variable was unintended.
The payload
The workflow payload will be available for JavaScript as an object with the name "payload". Note that if you have a workflow variable with the name "payload", then that variable will not be accessible in the script. Since the payload can be either a text string or binary data, the payload object has a number of methods that need to be used to read/write the payload. Note that if you directly change the payload object reference itself, then the payload will be invalidated.
The following methods are available on the payload object:
To make it possible to execute JavaScript code in a workflow, the system setting “Allow script execution in workflows” must be enabled. To change this setting, log in as administrator and change the setting under Other → System.
From a security perspective we recommend that scripting is only enabled when workflow requirements can only be achieved through scripting.
Before enabling scripting support, be aware of the following security implications:
Example1: Count the digits in a text payload.
function countDigits(str) {
let numDigits = 0;
for (i = 0; i < str.length; i++) {
if (str.charAt(i) >= "0" && str.charAt(i) <= "9") numDigits++;
}
return numDigits;
}
var totalDigits = countDigits(payload.toString());
console.log("The payload contains " + totalDigits + " digits");
Another example, where a Javascript can be called is e.g. to setup a long, advanced list of conditions e.g. to setup output variables e.g. for which printer to use for the merged result. Here the workflow can e.g. setup a normal, default printer and then we can call a Javascript with a lot of conditions to test for scenarios, where the default printer should be overridden.
This workflow is used:
It consists of these components:
So in short: The workflow reads an input XML file from a folder. The default printer is saved into the workflow variable, Printer. Then the javascript is called, which might change the value of the workflow variable, Printer. Finally the input file is merge with a template and printed on whatever printer, that is selected.
The input file has a header, that looks like this:
In the script we want use the valued for the user node and the DocType node to determine if another printer is to be selected.
The Javascript looks like this:
var Printer;
var User = payload.xpath("ng:trim(/Root/CompanyInfo/user)");
var DocType = payload.xpath("ng:trim(/Root/CompanyInfo/DocType)");
if (DocType == "Invoice") Printer = "Printer1";
if (DocType == "CreditNote") Printer = "Printer2";
if (User == "KSE") Printer = "Printer3";
The script does this:
If none of the conditions above are true, then the default Printer is used.
The final workflow component, Print use the printer, that was selected via the workflow variable, Printer.
One of the 'magic' things, that you can do with java scripts is, that you evaluate an XPath expression which is dynamic i.e. that the XPath itself is dynamic and e.g. found in a node in an input XML file.
To illustrate how that can be done we can consider this input XML file:
<test>
<data>
<name>John Smith</name>
<customerNo>123456789</customerNo>
</data>
<expressions>
<expression1>/test/data/name</expression1>
<expression2>concat(/test/data/name, ' ', /test/data/customerNo)</expression2>
</expressions>
</test>
The XML file contains a data section and an expression section.
The expression section contains the two dynamic XPath expressions, that we want to evaluate/calculate in the script.
This is here done with two sections like the one below:
The two elements are these:
In the first we extract the value (XPath expression to execute in the script) into the variable, myXpath. This sets the value (with the input XML file above) to:
"concat(/test/data/name, ' ', /test/data/customerNo)", which is the XPath expression, that we want to execute:
In the second we call the script via the Run a script component:
And we can of course also run the script once more after changing the myXpath variable to the value from the expression 1 node in the input file, which results in the value, "/test/data/name", which is another XPath expresssion to run.
The referenced script is here setup like below:
console.log("xpath expression: " + myXpath);
var xpathResult = payload.xpath(myXpath)
console.log(xpathResult);
The script outputs the expression, that it is going to execute. Then the expression found in the variable, myXpath is executed and finally the executed result is output. If you run the workflow described here, then you can see the result in the job log: