Skip to main content

Introduction

Scripts in iCL Designer provide a variety of ways to make content interdependent and interlinked.

You are able to change the visibility, perform calculations, or extend questions and answers.

At the same time, scripts are very approachable, as you do not need to have programming skills to use them. This is achieved by using blockly, which is an editor that allows you to define scripts similar to assembling a puzzle.

When to use scripts​

There is a broad variety of use cases for blockly scripts. They are often used to create dynamic answers or to change the visibility of specific workbook areas based on input.

Another area for scripts are Content Items, which can receive data from previous inspections as well as update existing data or create new data sets.

Scripts are also used to limit, filter or sort data or lists, doing calculations or providing date and time values to work with.

Blockly script UI​

All scripts will be created in a seperate window - the blockly editor. By default it is located at the bottom of the user interface.

You are able to access the blockly-editor in the properties window at every puzzle icon Blockly Script Area by clicking on it.

Now, a script can be created

  1. using any of the provided blocks
    The fallback content to display on prerendering
  2. or using the value of another field, by dragging its Link handle (the puzzle-piece that appears on the outer edge of a question or answer node when you hover it) and dropping it into the blockly editor
    The fallback content to display on prerendering
the Link handle

When you hover a question or answer node in the mindmap, a Link handle (a puzzle-piece) appears on the node's outer edge. Drag this handle into the blockly editor to insert a reference to that field's value. A plain click on the handle only shows a short hint on how to use it β€” it does not insert anything.

The difference is the following: If you use only a constant value in your script like in the first case (1), this script will be evaluated once (when the field it belongs to is created). Thereafter it will not change anymore. Therefore, the first script creates a default value, that the user can later overwrite.

If you, however, use the value of any other field in your script, like in case (2), your script now depends on that field. That means, that whenever those other fields change (e.g. because the user enters some other value), your script will be re-evaluated.

When creating a new script, the editor will have a red border, which indicates, that the script is missing something or has unconnected elements in the script area. This will happen often when building or changing scripts, and while having a red border, the script will not work and, thus, cannot be saved.

You can close the editor at every point by hitting the X in the top right of the window. When there is still a script error while closing the blockly window, a prompt will reassure, if you want to close the window and lose current unsaved changes of this script.

Blockly window docking​

You can change the position of the blockly editor by performing a drag&drop action on its colored headline. Several arrows appear in the corners and in the middle, which you can address via hovering the window over that arrow. The window will be positioned in the indicated grey area.

note

The new window position will not be saved after closing the workbook.

Scriptable properties​

You can find the blockly editor at the following locations:

PropertyUsable atAllowed OutputPurpose
TitleWorkbook / Checklist / Chapter / Headline / FieldText, NumberChanges the title of that node.
MandatoryFieldBooleanIf the output is true, this field becomes mandatory. False will disable its mandatory status.
ExistsChapter / Headline / FieldBooleanIf the output is true, the field will exist in the iCL Filler. If it doesn't exist, all related scripts and follow-up-fields will be treated as not existent.
HiddenChapter / Headline FieldBooleanIf the output is true, you are not able to see this field, but the iCL Filler can still access its data and values.
ReadonlyFieldBooleanIf the output is true, the field is in an readonly state, where no changes can be made. Be careful when mixing mandatory with readonly parameters.
Scripted AnswerFieldText Number Date TimeThis script automatically sets the answer of the field with or without a condition/relation.
Minimum/MaximumChapter / HeadlineNumberModifies the minimum and maximum occurrence of that node.
QueryChapter / Headline / Field (Databound)-Creates a connection between two content types based on a matching entry.
Order byChapter / Headline-Modifies the order of this repeated section.
FilterContentType / Field (Content Item)-Sets a filter for the loaded content items of that field to restrict/limit/filter/ data.
MappingsField (Content Item)depends on mapping data typeA Mapping stores data to add/modify Content Item data for Content Types.
ListField (Databound)ListProvides answers based on a list of data
script evaluation

To get an understanding of when and why such scripts are evaluated, see here.

Available blocks​

Text blocks​

BlockFunctionAllowed Types
Allows translatable and non-translatable input.Text, numbers, special characters
Connects several display elements together.All
Allows to compare two text for equality or inequality (if they are the same or not).Text
Allows to insert a special character (e.g. new line)-
Returns a copy of the text with the whites paces removed from one or both ends.Text
Displays the attached text in upper/lower case or title case.Text
Returns the position of the first/last occurrence of the first text in the second text. Returns 0 if text is not found.Text
Returns the letter at the specified position. #1 is the first item.First input: text, Second input: number
Returns a specified portion of the text.First input: text, Second and third inputs: number
URL-encodes the given text so it is safe to use in a URL or query string (e.g. a space becomes %20).Text
URL-decodes the given text, resolving percent-escapes back to their original characters (e.g. %20 becomes a space).Text
Creates a new unique id, for example 0198f2c1-4a3b-7d2e-9f10-3c5a7b9e2d4f. It is a UUIDv7, so the first part is a timestamp and newer ids sort after older ones. Note that it returns a different value every time the script is evaluated, so it is not a stable identifier for a field.-

Math blocks​

BlockFunctionAllowed Types
Enables the entry of numbers.Number
Creates a number from text.Text
Enables mathematical calculations - sum, minimum- maximum value, average.Number, number fields
Compares two numbers with each other.Number
Enables basic mathematical calculations.Number, number fields
Enables rounding - commercial, up, down.Number, number fields
Enables rounding with defined decimal places - commercial, up, down.Number, number fields
Calculates the root of a number.Number
Calculates the remainder of a division.Number
Returns a random number between -2,147,483,648 and 2,147,483,648.
Returns a random number between the given minimum and maximum values. The lower limit is inclusive, while the upper limit is exclusive. This means for example: If you specify a minimum of 0 and a maximum of 3, possible values are: 0,1,2 (so 3 is not part of the result set).Number, number fields
Returns an array with the given amount of unique/not unique random numbers between the given minimum and maximum values. The lower limit is inclusive, while the upper limit is exclusive. This means for example: If you specify a minimum of 2 and a maximum of 5, possible values are: 2,3,4 (so 5 is not part of the result set).Number, number fields

Date & time blocks​

BlockFunctionAllowed Types
Returns the current date of the device.Datetime
A date field composed of the individual date components.Number
Adds a specified number of days/months/years to a date.First input: number, Second input: date
Returns either the year, month, day or weekday as a number.Date
Returns the calendar week of a date as a number. The dropdown switches between the European (ISO 8601, weeks start Monday, week 1 contains the first Thursday) and American (weeks start Sunday, week 1 contains January 1st) calculation.Date
Compares two date fields and returns a boolean value.Date
Returns given text as formatted date.Text
Returns given text as custom formatted date.First input: Text, Second input: Text
Calculates the duration between two points in time.Timepicker
Use text field as input for date blocks/fields

When you have to use a text field as input for a date block/field, the text will be interpreted as a valid date in case it uses one of following date formats:

MM/dd/yyyy HH:mm:ss
MM/dd/yyyy HH:mm
MM/dd/yyyy
yyyy-MM-ddTHH:mm:ssZ

The last format is an international standard called "ISO 8601" which is also used in REST interface of iCL Portal.

Logic blocks​

BlockFunctionAllowed Types
A branch operator to cover different cases logically.First input: boolean, Second and third inputs: all
A branch operator to cover different cases logically. Allows to add additional else-if branches.First input: boolean, Second and third inputs: all
A logical truth operator for true and false.-
Enables mathematical comparisons.Boolean
Negates a following logical statement.Boolean
Returns the value null.-
If the result of the first block is an error, returns the second blocks value, otherwise the result of the first blockany

Lists blocks​

BlockFunctionAllowed Types
Filters in a list according to certain criteria.List
Creates a list with 1 entry, can be extended.All
Creates a list with 3 entries, can be reduced/extended.All
Filters the given list using the provided logical block, where the logical block is used for each and every element of the list.First input: list, Second input: boolean
Returns the length of a list.List
Takes a list or single value. If it is a single value, wraps it in a list. If it is a list that contains lists, it removes those lists and, instead, moves their items into the main list.List
If used with text from list, it takes a list and joins it together with the specified delimiter. If used with list from text, it takes a text and splits it using the specified delimiter.List
Reverses the elements of the given list.List
Returns distinct elements of the given list.List
Sorts the elements of the given list ascending/descending.List
Sorts the elements of the given list ascending/descending by a specified expression.First input: list, Second input: text, number, boolean, date
Checks whether any/every element in the list fulfills the given boolean expression. Returns a boolean.First input: list, Second input: boolean
Creates a new list with the results of executing the provided expression on every element in the given list.First input: list, Second input: all

Regex blocks​

BlockFunctionAllowed Types
Checks whether the text matches the regular expression and returns true or false.First input: text, Second input: pattern
Replaces every match of the regular expression with the replacement text. The replacement may refer to capture groups with $1, $2, ...First input: text, Second input: pattern, Third input: text
Returns the first match of the regular expression, or nothing if the text does not match.First input: text, Second input: pattern
Returns a list with every match of the regular expression. The drop-down selects whether the whole match or one of the capture groups is collected. Returns nothing (not an empty list) if there is no match, so check the result before passing it to a list block.First input: text, Second input: pattern
A ready-made regular expression for a common format, selected from a drop-down: natural number, decimal number (with optional or required decimals), e-mail address, IBAN, URL or GUID.-
Escapes all special characters of the given text so it is matched literally when used inside a regular expression. Use this whenever a pattern is built from an answer or other free text.Text

Working with regular expressions​

A regular expression (short: regex) is a small pattern language for describing what a text has to look like β€” for example "digits only", or "two letters followed by two digits".

iCL uses the JavaScript regex syntax

Scripts are executed by the iCL Filler script engine, which uses the JavaScript (ECMAScript) regular expression syntax β€” not the .NET syntax. When you build and test a pattern, use a tester set to the ECMAScript/JavaScript flavour, such as regex101.com (select ECMAScript (JavaScript) on the left) or RegExr.

Avoid .NET-oriented testers such as regexstorm.net: features like named groups, lookbehind or \p{...} character classes are written differently there, and a pattern that works on such a site may fail or behave differently in iCL.

A good introduction and a complete syntax reference: MDN β€” Regular expressions guide and the MDN regex cheat sheet.

The ready-made patterns​

The pattern block has two drop-downs and reads like a sentence, for example Natural number β€” anywhere in the text.

The first drop-down picks the format. You can always use a plain text block instead if you need a different expression.

The second one decides how much of the text has to match, and it matters a great deal:

  • only if it is the entire text β€” the expression is anchored (^…$), so the complete text has to have that format. Use this together with matches pattern to check an answer.
  • anywhere in the text β€” the expression is left unanchored, so it matches at any position. Use this together with first match of / all matches of to pull a value out of a longer text.

Hover over the block to see the exact regular expression the current selection produces.

Nothing found? Check the scope first

An anchored pattern never finds anything inside a longer text: ^\d+$ matches the text 42, but finds nothing in Order 42. If first match of or all matches of returns nothing, switch the second drop-down to anywhere in the text.

EntryExpression (anywhere in the text)Matches
Natural number\d+Digits only, no sign and no decimals: 0, 42
Decimal number (optional)[+-]?\d+([.,]\d+)?A number with an optional sign and optional decimals β€” whole numbers are also accepted: 42, -3.5, 3,5
Decimal number (required)[+-]?\d+[.,]\d+The same, but the decimals are required: -3.5, 3,5 β€” 42 does not match
E-mail address[^@\s]+@[^@\s]+\.[^@\s]+A pragmatic e-mail check: something, an @, a domain with a dot, no spaces
IBAN[A-Z]{2}\d{2}[A-Z0-9]{11,30}Two uppercase country letters, two check digits, then 11–30 letters or digits β€” written without spaces
URL(https?\|ftp):\/\/[^\s/$.?#].[^\s]*An http, https or ftp address
GUID[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}A GUID in the usual 8-4-4-4-12 notation β€” this also matches the ids created by the new unique id block

In only if it is the entire text mode the same entries are used wrapped in ^…$ β€” so "Natural number" becomes ^\d+$.

These patterns are deliberately kept simple and readable rather than covering every edge case of the respective standard. If you need a stricter check, use your own pattern.

Example: pulling values out of a longer text​

With first match of, the anywhere in the text scope and this text …

Invoice 2024-17: contact office@opti-q.com or visit https://opti-q.com/support .
Transfer 1250,75 EUR to AT611904300234573201 , ref 42, ticket 0198f2c1-4a3b-7d2e-9f10-3c5a7b9e2d4f

… each format returns the first thing it finds:

Pattern entryResult
Natural number2024
Decimal number (required)1250,75
E-mail addressoffice@opti-q.com
IBANAT611904300234573201
URLhttps://opti-q.com/support
GUID0198f2c1-4a3b-7d2e-9f10-3c5a7b9e2d4f

Swap first match of for all matches of to get every hit as a list instead of just the first. In only if it is the entire text mode every one of these would return nothing, because the text as a whole is neither a number nor an e-mail address.

Using capture groups​

Parentheses in a pattern create a capture group: a part of the match you want to read out separately. Groups are numbered from left to right by their opening parenthesis, starting at 1.

Take the text Order A-42 and B-7 with the pattern ([A-Z])-(\d+):

Drop-down settingResult
all matchesA-42, B-7 β€” the complete match each time
capture group 1A, B β€” only the part matched by ([A-Z])
capture group 242, 7 β€” only the part matched by (\d+)

So instead of getting the whole match and cutting it apart afterwards, you pick the piece you are interested in directly. If the selected group does not exist in a particular match, that entry of the list is empty.

Why you need "escape for use in a pattern"​

Characters like ., +, (, ), * or ? have a special meaning inside a regular expression. That is fine while you write the pattern, but it becomes a problem as soon as the pattern is built from something a user typed β€” an answer, a content item value, a field name.

The escape for use in a pattern block puts a backslash in front of every such character, so the text is searched for literally:

Text used as a patternUsed directlyWrapped in escape for use in a pattern
a.cThe . means "any character", so it also matches abc and axc β€” probably not what you wantedBecomes a\.c and matches only the literal text a.c
3.5 (mm)The ( ) are read as a group, so 3.5 (mm) itself is not foundBecomes 3\.5 \(mm\) and is found
1+1+ means "one or more of the previous character", so this matches 11 β€” but not the text 1+1 you were actually looking forBecomes 1\+1 and matches 1+1
Preis (nettoThe unclosed ( makes the whole pattern invalid and the script fails with an errorBecomes Preis \(netto and is found

Rule of thumb: if any part of your pattern comes from an answer or another free-text value, wrap that part in escape for use in a pattern. If you typed the whole pattern yourself, you do not need it.

Checklist field blocks​

BlockFunctionAllowed Types
Compares two values with each other. Mind that you cannot compare with numbers here. Use a text-block in the 'create list with'-part for comparison or switch to math-blocks if comparing two numbers.Text
Checks if a field has a value or no value at all.Fields
Allows to resolve all input fields that match the specified pattern. You can resolve all input fields with it or you can get only specific type of input fields e.g. all text fields, all number fields, etc.-
Allows to resolve all option fields that match the specified pattern. You can resolve all option fields with it or you can get only specific type of option fields e.g. all checkbox fields, all dropdown fields, etc.-

User properties blocks​

BlockFunctionAllowed Types
Shows the ID of the logged in user.-
Shows the username of the logged in user.-
Shows the first name of the logged in user.-
Shows the last name of the logged in user.-
Shows the e-mail address of the logged in user.-

Formatting blocks​

BlockFunctionAllowed Types
Returns the given date as formatted text. Provides a dropdown list to select the intended format.Date
Returns the given time as formatted text. Provides a dropdown list to select the intended format.Time
Returns the given number as formatted text. Provides a dropdown list to select the intended format.Number
Returns the given object (can be a number/date/etc.) as formatted text using the specified format string. You can read more about format string in Microsoft Docs or in our documentation.All

Task blocks​

BlockFunctionAllowed Types
Allows to get certain properties of the task of the inspection. Properties: external ID, title, inspector, inspected object(s), description, start date and due date.-
Returns true if the inspection was started with a task, false otherwise.-

Inspection blocks​

BlockFunctionAllowed Types
Provides information about the current inspection. Properties: language.-