×

Please give details of the problem

Skip to content

Differences Between Rendering Engines

DigitalSuite provides the following rendering engines for formatting and presenting web interfaces and their widgets on different devices:

  • Application Runner: based on the Google Web Toolkit (GWT), a development framework for web applications.
  • WIRE: based on React and Material-UI, a JavaScript framework and components for building user interfaces. WIRE is newer and more advanced than Application Runner. Major advantages are its improved responsiveness, rendering and rendering performance, ease of customization, full support of HTML5, lazy loading, and faster start of JavaScript and web interfaces in general.

Designers can select the rendering engine when they create a web interface. When designing and configuring the web interface with its widgets, some differences have to be taken into account, which are described in detail in the following sections.

Stylesheets and Styles

With Application Runner, layout and style settings are spread across a web interface and its widgets. With WIRE, all layout and style definitions are collected in a central stylesheet (CSS). In addition, WIRE comes with some out-of-the-box features that were not available with Application Runner, such as the central setting of a coloring scheme.

With both rendering engines, designers can add one or more custom stylesheets in the web interface settings. Templates are available which contain the predefined styles and can be used as the basis for the customizations.

The following table summarizes the differences between the rendering engines that are related to the layout and styling:

Difference Application Runner WIRE
CSS - general Layout and style settings spread across each web interface and its widgets. Layout and style settings collected in central CSS.
Colors Definition of colors for the web interface and individual widgets spread in CSS. Definition of a coloring scheme in the web interface settings. Additional color settings possible in central CSS.
Borders - web interface Selection of a predefined layout and stylesheet with or without borders in the web interface settings. Definition of border settings in a central CSS. The predefined layout has borders enabled.
Borders - widgets Definition of borders in the settings of individual widgets. Definition of borders in a central CSS. The predefined layout is without borders.
Text direction Definition of the text direction in the web interface settings and in the settings of individual widgets. Definition of the text direction in a central CSS. The predefined layout uses the left to right direction.
Label width and position Definition of the label width and position in the settings of individual widgets like input fields, lists, arrays, or execute script widgets. Definition of the label width and position in a central CSS. In the predefined layout, labels are aligned left and above input fields or lists, and their width is optimized for WIRE.
Custom appearance of widgets Definition of custom appearance using a class suffix for a style that starts with gwt-, for example, gwt-Button-mybutton. The class suffix is specified in the widget settings. Definition of custom appearance using a class suffix for a style that starts with rmp, for example, rmpButton-mybutton. The class suffix is specified in the widget settings.
Tabs widget Tabs can be placed at the bottom and the minimum height be specified in the widget settings. Tabs cannot be placed at the bottom. The minimum height can be specified in a central CSS, for example:
.rmpTabs .headerTabPanel .headerTabsWrapper .tab {min-height: 60px;}
Custom widget No global CSS; layout and style settings defined within the widget's elements. Central CSS like for web interfaces, but without coloring scheme (the scheme of the parent web interface is used). The layout and style settings apply to the custom widget itself as well as to custom widgets it includes.

JavaScript

With Application Runner, JavaScript code snippets are spread across a web interface and its widgets. Application Runner takes care about the execution order and event management, but maintenance of the distributed code is difficult.

With WIRE, all JavaScript code is collected in at least one central versioned file, which is configured in the web interface settings and executed for all web interface instances and screens. Functions for all predefined events of all widgets are available for controlling the execution in the central JS.

Both rendering engines come with their own JavaScript API. The APIs are identical in many aspects, but some differences have to be taken into account as described below. With both rendering engines, designers can add existing JavaScript files and libraries to their web interfaces in the web interface settings.

The following table and the subsequent sections provide an overview of the differences between the rendering engines that are related to JavaScript. For details on the mentioned functions, refer to the respective API documentation.

Difference Application Runner WIRE
API JavaScript AR Widgets JavaScript WIRE
JavaScript - general JS spread across each web interface, its screens and widgets. JS centralized in at least one file per web interface.
Recommendation: The entire JS in a file should be enclosed in an IIFE to keep the DOM clean.
JS in web interface settings JS files and libraries can be specified for the header or footer to be executed before or after the web interface has been loaded. All specified JS files and libraries are executed after the web interface has been loaded to avoid blocking and make sure that all screens and widgets are available.
Current screen Known and controlled by Application Runner. RMPApplication.getCurrentScreen function in central JS returns the current screen. This can be used for conditional execution of specific script sections, for example, to avoid problems with widgets which are not available in all screens.
Variable values "[[_variable_name_]]" can be used instead of getVariable (or equivalent) to retrieve the value of a variable. getVariable (or equivalent) is used to retrieve the value of a variable.
Custom widget No central JS; scripts defined within the widget's elements. Central JS like for web interfaces.

JavaScript Differences for All Widgets

The following table provides an overview of the differences between Application Runner and WIRE which apply to all types of widgets.

Difference Application Runner WIRE
Visible / editable / required rules JS for each rule specified in widget settings. Functions in central JS file:
_widget_id_.setVisibleRule
_widget_id_.setActiveRule
_widget_id_.setRequiredRule
An example is provided below.
User input validation rule JS specified in widget settings. Function in central JS file:
_widget_id_.setValidationRule

Example:

With Application Runner, the following code can be specified as the editable rule in the widget settings of a text input widget, id_text1. The widget is editable depending on the length of text4:

1
"[[text4]]".length > 3

With WIRE, the following code would be used for the same purpose in a central JS file:

1
2
3
4
5
6
7
(() => {
      id_text1.setActiveRule(
           () => RMPApplication.get("text4").length > 3 ,
           [text4],
           true
     );
})();

Without specifying a condition, the function in the central JS file would look like this:

1
id_text1.setActiveRule(() => { }, [ ], true);

Or simply:

1
id_text1.setActive(true);

JavaScript Differences for Individual Widgets

The following table provides an overview of the differences between Application Runner and WIRE which apply to specific types of widgets in addition to those for all widgets described in the section above.

Widget Type Application Runner WIRE
Buttons Pre-launch script for all types of buttons and script for Execute Script button specified in widget settings. JS functions in central JS file:
_id_buttonWidget_.setOnPrelaunchScript
_id_buttonWidget_.setExecuteScript
Indicators (Spinners) Can be created dynamically with JS. Are implemented as SVG icons and cannot be created dynamically. The following API functions of Application Runner are not available:
getUrl
insertAbove
insertAfter
insertBefore
insertBelow
moveAfter
moveBefore
remove
setTargetUrl
setUrl
Lists and Selectors Post-loaded script in widget settings for all types of lists and selectors. JS function in central JS file:
_id_listWidget_.setPostLoadedScript
Reports
  • Post-loaded script, on row select/deselect script, and scripts for individual columns in widget settings for all types of reports.
  • No access to variables and values of the web interface, which are outside the report widget.
  • JS functions in central JS file:
    _id_reportWidget_.setPostLoadedScript
    _id_reportWidget_.setOnRowSelectDeselectScript
    _id_reportWidget_.setCustomColumnScript - see example below.
  • Access to variables and values of the web interface, which are outside the report widget.
Custom Report Loading data script in widget settings in addition to scripts for all types of report JS function in central JS file:
_id_reportWidget_.setJsReportLoadingDataScript
See example below.
Array Rules for adding and deleting rows; footer script for individual columns and for overall array; script to execute when adding a JS widget as an array column. JS functions in central JS file:
_id_arrayWidget_.setOnAddRowScript
_id_arrayWidget_.setOnDeleteRowScript
_id_arrayWidget_.setArrayColumnFooter
_id_arrayWidget_.setArrayFooter
_id_arrayWidget_.setArrayCustomColumnScript
Section Rules for opening and closing the section in widget settings. JS functions in central JS file:
_id_sectionWidget_.setOnOpenScript
_id_sectionWidget_.setOnCloseScript
Tabs Visibility rule, editable rule, and click script for each tab in widget settings. JS functions in central JS file:
_id_tabWidget_.setVisibleTabRule
_id_tabWidget_.setActiveTabRule
_id_tabWidget_.setOnclickScript
The relevant tab is specified by its index with each function.
JavaScript widget JS to execute specified in widget settings. JS to execute specified in central JS file.
Custom Widget
  • Rule for conditional loading in widget settings.
  • Access to IDs and variables within the widget by RMP_this.
  • Conditional loading must be implemented as a listener.
  • Direct access to own IDs and variables without RMP_this.
  • RMP_parent or window to access resources of parent web interface.
  • Access to custom widget's resources from parent by setLoadedCallback function.
See examples below.

The following examples show JavaScript code for specific purposes of WIRE based web interfaces in a central JS file.

Report Widget Custom Column Script

The setCustomColumnScript JS function for Report widgets takes two parameters:

  1. The index of the column.
  2. The callback function used to fill the column. The callback function takes the current row as a parameter and returns an object that contains:
    • content : the content to be displayed in the report cell (text or HTML)
    • afterCreate : a function to be executed after the content has been added to the column
    • beforeUnmount : a function to be executed before the column is removed from the report

Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
function customSciptCB (currentRow) {
    const id = currentRow.id
    function afterCreate ()  {
        console.log(' after create ----------------') 
    }
    function beforeUnmount ()  {
        console.log(' before unmount ----------------') 
    } 
    return {
         content : 'custom column here ', 
         // content may contain HTML like '<button> btn here</button>'
         afterCreateAction : afterCreate ,
         beforeUnmountAction : beforeUnmount 
    } 
}
id_report.setCustomColumnScript(3,customSciptCB)

Custom Report Loading Data Script

The setJsReportLoadingDataScript JS function provides the report content for Custom Report widgets. It takes a callback function with an options object parameter that includes:

1
2
3
4
5
6
options = {
   first : 0, // starting element; useful for pagination (number)
   nbElements: 10, // number of elements to display; page size (number)
   filters: [], // filters to apply (array like {"filter":"name","value":"smith","operator":"CONTAINS"},...]) ,
   orderBy: [] // column sorting (array like [{"order":"name","orderby":"desc"},...]) 
}

Example:

1
2
3
4
5
6
7
8
id_jsReport.setJsReportLoadingDataScript((options) => {
    var input = {}; 
    input.first = options.first;
    id_jsReport.setLoading(true); 
    // 'data' is the report data from some source after applying filters and sorting 
    id_jsReport.setData(data);  
    id_jsReport.setLoading(false);
});

Custom Widgets

With Application Runner, accessing IDs and variables within a custom widget requires the RMP_this or RMP_this.variable prefix, for example:

1
2
3
4
// access the input with ID id_input_foo
RMP_this.id_input_foo.setValue('foo bar value');
// get the variable input_foo that belongs to the current custom widget
RMPApplication.get('RMP_this.variable.input_foo');

With WIRE, RMP_this and RMP_this.variable are not required to access a custom widget's own IDs and variables:

1
2
3
4
// access the input with ID id_input_foo
id_input_foo.setValue('foo bar value');
// get the variable input_foo that belongs to the current custom widget
RMPApplication.get('input_foo');

WIRE supports additional prefixes, RMP_parent and window, to address the IDs and variables of a custom widget's parent web interface or custom widget, or the root of a hierarchy of web interfaces and custom widgets, for example:

1
2
3
4
5
6
// access the input with ID id_input_foo in the parent
RMP_parent.id_input_foo.setValue('setting parent value: hello world!');
// set the variable input_foo in the parent's parent
RMP_parent.RMP_parent.RMPApplication.set('input_foo', 'foo bar value');
// access the input with ID id_input_foo in the root web interface
window.id_input_foo.setValue('setting parent value: hello world!');

Every custom widget provides a setLoadedCallback function. It allows to set a callback when the custom widget is loaded, so that its resources can be accessed from a parent.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// from root web interface
id_parent_cw.setLoadedCallback(() => {
    // inside this function, all resources of a parent custom widget are available
    console.log(id_parent_cw.id_parent_cw_users.getValue());
    // we can also set a callback for when a child custom widget is loaded
    id_parent_cw.id_child_cw.setLoadedCallback(() => {
        // now we can access the child custom widget's resources, for example
        console.log(id_parent_cw.id_child_cw.id_child_input_1.getValue());
    });
});

Listeners

Web interfaces based on Application Runner can be configured with listeners that trigger a composite API, connector, or process. With WIRE, listeners that call connectors are not supported. Composite APIs can be launched instead.

With WIRE based web interfaces, a listener's launch event as well as any JavaScript executed upon specific events are handled in a central JavaScript file. The JavaScript to be executed is identified by a unique ID specified in the listener configuration. This is similar to configuring a listener with a composite API and the Manually via JavaScript launch event for a web interface based on Application Runner.

In summary, the differences between listeners with Application Runner and WIRE are the following:

Difference Application Runner WIRE
Action Launch a composite API, connector, or process. Launch a composite API or process.
Launch event Specified in the listener configuration in the web interface settings:
  • Screen initialized
  • A listened to variable changed
  • Screen closed
  • Manually via JavaScript
Launch functions in central JS file:
onScreenInitialized
onListenedVarsChanged
onApplicationClosed
trigger (same as with Application Runner)
JS upon event for composite API Specified in the listener configuration in the web interface settings. Success and failure callbacks of launch functions in central JS file - see example below.
JS upon process events Specified in the listener configuration in the web interface settings. Grouped into events object. Developers can select the applicable events and specify the events object with the launch functions in the central JS file - see example below.

The following examples show JavaScript code for listeners of WIRE based web interfaces in a central JS file.

Composite API Listener

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**  
------------   Composite API Listener ---------------
    The ID of the Composite API used here is id_userscapi
**/

const input = {"input_1":"value_1","input_2":"value_2"};
// input could be: var input RMPApplication.getAllVariablesValues();

const options = {
   "mode":"TEST",
   "Version":"7347",
   "listenedVars":['username'],
   "executeEvenEmpty ": false,
};
// or simply const options = {}; to execute the composite API with the mode and version of the web interface

function ok(P_computed){
   alert(JSON.stringify(P_computed));
}

function ko(P_error){
   alert(JSON.stringify(P_error));
}

id_userscapi.onListenedVarsChanged(input, options, ok, ko)
id_userscapi.onScreenInitialized(input, {}, ok, ko)

Process Listener

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**  
------------   Process Listener ---------------
    The ID of the process listener used here is id_processListener
**/

const input =  RMPApplication.getAllVariablesValues();
const options = {listenedVars : ['username'], executeEvenEmpty : false}
const events = {
    started : () => console.log('started'),
    notStarted : () => console.log('not started'),
    waiting : (id, status) => console.log('waiting ', id, status),
    cancelled : (id, status) => console.log('cancelled ', id, status),
    completed : (id, status, initial, internal, completed) =>{
             console.log('- completed ------ \n ', id, status, completed)
    },
    aborted : () => console.log('aborted')
}
// events could contain the required event functions only, e.g.:
// const events = { 
//    waiting : (id, status) => console.log('waiting ', id, status), 
//    completed : (id, status, initial, internal, completed) =>{
//        console.log('- completed ------ \n ', id, status, completed)
//     }
// };

id_processListener.onApplicationClosed(input,{},events)
id_processListener.onListenedVarsChanged(input,options,events)

Other Differences

The following table provides an overview of miscellaneous differences between the rendering engines which designers should be aware of when developing web interfaces.

Difference Application Runner WIRE
On/off widget Implemented as a checkbox:
Implemented as a switch:
JavaScript widget Icon in WebModeler Widgets tab:

Representation on the WebModeler stage:
Script result
Icon in WebModeler Widgets tab:

Representation on the WebModeler stage:
Reports
  • Date format specified for all date columns in widget settings. Filter on day only can be set for individual columns.
  • Column width in pixels.
  • Limited functionality for end users.
  • Separate date format can be specified for each date column.
  • Designer can specify a column width unit: pixels or percent.
  • Improved functionality and look & feel for end users related to scrolling, data selection, filtering and sorting, refresh, print and export, page sizing and pagination.
Arrays
  • If allowed by the designer, end users can add and delete rows, and sort them by individual columns.
  • The designer can limit the number of rows an end user can add.
  • Checkbox, radio button, and multiselect lists within an array can have a tooltip.
  • If allowed by the designer, end users can add and delete rows, and sort them by individual columns. In addition, they can re-arrange rows using drag and drop as well as print and export the entire array.
  • The designer can limit the number of rows an end user can add or delete.
  • Checkbox, radio button, and multiselect lists within an array do not have a tooltip.
Date picker Limited functionality. Improved functionality and usability with date and range selection, filtering, manual input and display.