7 minute read BPS Version: 2023.1.2.44


As announced in the previous post Bandwidth usage, I have modified my ‘user experience form rules’ to use less bandwidth. In addition, some of the old ones weren’t compatible with BPS 2023 R2.

Effected are:

As a result of the changes you will save 40% or 28KB whenever a form is displayed, if you are using the minified version. This includes the full form view, the task view or the preview.

Effect of the minimizing the form rules on the bandwidth
Effect of the minimizing the form rules on the bandwidth

Remark: The effect is even greater because the JavaScript is passed as string value in a JSON object. This requires escaping special characters. For example, a line break consist of the carriage return and new line characters. During the response these two characters will become four \r\n.

Unfortunately, I neither have the time nor the possibility to test this against multiple WEBCON BPS versions. There’s a great chance that they will at least work as of WEBCON BPS 2022 R4, but I only tested 2023 R2.

Info: In case you want to apply minification to your rules to, you can take a look here.

Breaking change

As mentioned in the previous post, I decided to implement a breaking change. In the past all form rules where independent of each other. This in turn was only possible, because I used some ‘utility’ functions which I duplicated in each form rule. In the past I opted for independent working form rules. Realizing how it currently works and how many form rules there are today, I changed this.

The utility functions have been moved to their own form rule, which is a prerequisite before invoking any other form rule. I won’t update the old any longer. Therefore I’ve moved them to an archive branch.

Remark: I’ve updated the old posts, so that there’s information about the breaking change and the download section reflects this information.

Using the revised form rules

General implementation

The implementation is basically the same:

  • Create the form rules using the provided JavaScript files.
  • Create an HTML field.
  • Add the <script></script> tags and call the required form rules.

I will describe each number in the screenshot in the below screenshots.

Global rules html field executes all form rules.
Global rules html field executes all form rules.

Remark: Since there will be the archived version and the new minimized version, I decided to describe the usage of the new ones in this single post instead of updating the old ones.

Remark: Even so I’m describing the implementation here it may happen that you need more information to understand some parts. Please refer to the respective posts for this.

Using the HTML field also has a nice side effect. You can invoke different rules depending on edit/view mode, for example you neither need the save* or missing* rules in view mode.

Different rules are executed depending on edit/view mode.
Different rules are executed depending on edit/view mode.

1. Common functions

The form rule will provide the ‘utility’ functions, stored in the utils folder. You can simply create it by copying the utils.min.js content into the form rule after switching to JavaScript mode. If there’s a problem and you need to debug, you can always replace the minimized one with the full version if necessary.

Copy either the full or minified version into the form rule.
Copy either the full or minified version into the form rule.

In addition to the form rule we need a business rule which returns a few information about the currently available paths. This will be cheaper in terms of bandwidth than calling the internal /desktop endpoint. The sql command is stored in the basicPathInformation.businessRule.sql file and copy & paste should work just fine. We don’t need any parameters.

Business rule GetBasicPathInformation
Business rule GetBasicPathInformation

In the HTML field you need to

  • Invoke the created rule, you need to use your one
  • Set ccls.utils.applicationId
  • Set the basic path information

HTML field code:

ccls.utils.applicationId = #{APP_ID}#;
ccls.utils.basicPathInformation = JSON.parse('BUSINESS RULE GetBasicPathInformation'); /*The created business rule to retrieve the basic path information*/

2. Breadcrumb

The breadcrumb is now divided into two parts. Originally 1 and 2 have been in the same HTML field, which was a mistake I didn’t realize till now.

The breadcrumb utilized the value of a field, in our case the ‘Title’ field. Whenever the value in the actual field changes, this would be updated. What I didn’t notice until introducing the changes, the ‘update’ recreates the whole HTML field each time. This means, that the form rule was invoked each time. Maybe the breadcrumb data was also executed. I haven’t checked the later one.

Breadcrumb HTML fields
Breadcrumb HTML fields

Defining the general breadcrumb functionality in the GlobalRules field and the actual creation in BreadcrumContainer prevents the multiple invocations.

Dividing the logic into two fields obviously requires that the one is executed before the other. This is easily achieved by placing the GlobalRules field as the first field.

The global rules field should be the first field on the form.
The global rules field should be the first field on the form.

3. Save button as path

BREAKING CHANGE The form rule dates back to November 2021 and either there weren’t HTML fields yet or I wasn’t aware of the capability. Nevertheless, in the past the form rule was loaded in the OnLoad/Behavior of the form and form rule parameters have been used.

Old version of using the unified save experience form rules.

As you have seen above, the new version is executed like any other in the HTML field. In contrast to the previous version, you need to call the createPathButton and provide the parameters yourself. The single function parameter allowed you to pass an alternativeLabel for the button. You can do the same by passing the value in JavaScript. In most cases I passed Empty as the form rule parameter and the respective value in JavaScript would be ''

HTML field code:


4. Save draft as path button

BREAKING CHANGE The same as in 3. Save button as path applies here. No more form rule parameters, you need to call createSaveDraftButton yourself and provide the id of the Save draft path in the JavaScript directly.

HTML field code:

ccls.addSaveDraftButton.createSaveDraftButton('SAVE DRAFT PATH ID', '');

5. Colorize paths

Originally the path information were retrieved using a business rule before executing the colorize function. In the new version the Common functions already has this information. Therefore, setting this information here is no longer necessary.

HTML field code:


6. No changes

There are no changes in the usage of:

  • Modal dialog, consisting of parent and child logic
  • Missing comment handler
  • Missing required fields handler

Common functions overview


This will allow you to get an id from the current URL. In case https://someserver.cosmocloud.eu/db/1/app/115/element/30544 is your url, passing app as the parameter will return 115. You can also pass an arbitrary URL as a second parameter.

ccls.utils.getIdFromUrl.(precedingElement, optional_url)


If a user switches very fast between tasks/previews, it can happen that the G_ variables don’t exist. If you experience something like this, you can call this function and pass the variable name to the function like below. This will prevent the execution until the variable was accessible, or the allotted time for recreating the G_ variables has been reached.

if ((await (ccls.utils.getGlobal('G_ISNEW')))) 


Requested a confirmation from the user, whether the user really wants to navigate away.Is used in the child dialog.


Will return the lite model for the current element which was previously available as window.initialModel. This works for new workflow instances as well as existing ones in view/edit mode. The endpoint will only be called ones after loading the page, in subsequent calls the cached value will be returned. As this model does contain only static information, this is no problem. Hitting the Refresh button or navigating to another element, will clear the cached value.

You can use the function like this:

(await ccls.utils.getLiteModel()).controls


Similar to getLiteModel but you specify which element is retrieved from which database.


In case you are supporting different WEBCON BPS vesion there may be changes in the HTML or JavaScript objects. This function will allow you to defining VersionDependingValues and retrieve those applicable for the current version.

Below we define

  • a different getFieldFromControls function for version before and as of 2023.1.1.1.
  • get the one for the current version.
  • use it.
dkr.missingRequiredFieldsHandler.VersionDependingValues = [
    version: '',
    values: {
      getFieldFromControls: async function (displayName) {
        return (await ccls.utils.getLiteModel()).controls.find((item) => { return item.displayName == displayName && (item.fieldName.indexOf("Att") == 0 || item.fieldName.indexOf("SubElems") == 0) })

  }, {
    version: '2023.1.1.1',
    values: {
      getFieldFromControls: async function (displayName) {
        return (await ccls.utils.getLiteModel()).controls.find((item) => { return item.name.translated == displayName && (item.fieldName.indexOf("Att") == 0 || item.fieldName.indexOf("SubElems") == 0) })
dkr.missingRequiredFieldsHandler.versionValues = ccls.utils.getVersionValues(dkr.missingRequiredFieldsHandler.VersionDependingValues);


You can find the JavaScript files here: