Revised web UI API in USoft 11
This article describes the USoft 11 web UI API in terms of change relative to the API in USoft 10.1.
This article is meant to help developers who know USoft 10.1 upgrade to USoft 11. Scanning it from top to bottom will give you an overview of the main differences, and show you how to translate USoft 10.1-specific knowledge and patterns into the new USoft 11 paradigms.
New UDB object layer
USoft Web Designer exposes an API of UDB objects that allows a web UI to communicate with the Rules Engine. This code layer has been brought in line with current JavaScript standards. Obsolete technologies (jQuery, jQuery UI, handlebars, older Bootstrap versions) are being phased out and replaced by modern standards (latest Bootstrap, Vue3). This enables reactive pages among other things.
In USoft 11, the entire API has been rewritten and its coding restyled to using modules and classes. The resulting API is easier to maintain and works more like modern libraries, so that past design issues can be addressed upfront instead of being "patched away".
General aspects of the revision
Outputs changed, calls unchanged
Most outputs of API functions have changed considerably, but the way the functions are called is mostly unchanged.
Maximum use is made of classes. Outputs of API functions are now always instances of these classes, instead of some generic JSON object. For example, the
$.udb()
function now returns an array of objects instead of strings. Functions called on these arrays, however, still work the same way as before.
Reference objects (context, query details) in arrays (e.g. of data sources, rows, etc) contain actual objects instead of string references, e.g. frame context information now takes the form of context objects instead of their string ids.
Promises replace callback functions
Promises are used throughout; callback functions are deprecated. Callback functions are still available, albeit with a deprecation message when encountered.
Synchronous calls using the async: false option have been dropped. If you need the next statement to be executed when the current statement is finished, use proper Promise behavior using the await keyword, or use proper chaining functions. Correspondingly, promise options of functions have also been dropped. Instead, every function that had a promise option or callback functions now automatically returns an instance of UdbPromise. UdbPromise replaces the earlier udbPromise class.
The async function option has been dropped (many places in the UDB object layer).
The success and error callback function options are deprecated (many places in the UDB object layer).
jQuery dropped
jQuery is no longer used as a key technology for the UDB layer.
Events are now handled by native constructions, and certain selectors that were specifically jQuery, and also our own 'pseudo-selectors', can no longer be used. Convenient UI functions that were commonly used, e.g., .addClass(), .removeClass(), .data(), .on(), .off(), .trigger(), have been added to the native classes of the HTML DOM objects themselves now.
If you still require jQuery, you can simply add it to the application.html file. Be aware that USoft default controls will not use jQuery calls.
Default CSS class names of controls have changed
In USoft 10.1 the exact object names prefixed with ui were used in all CSS to refer to the browser DOM elements, e.g. uiButtonControl was used as the default class name of a button control. In USoft 11 we use the more standardized 'kebab-style' class names, e.g.,
.uiButtonControl {
max-width: 220px;
margin-right: 2px !important;
margin-bottom: 1px !important;
}
has become
.ui-button-control {
max-width: 220px;
margin-right: 2px !important;
margin-bottom: 1px !important;
}
If the old class names are used in local code specified in Web Designer, or within included javascript or CSS files in the Alt folder, then these need to be updated to reflect the new class name style.
Use of modules and how to define custom functionality in CustScript.js
The default js/CustScript.js file (see How to add a script to your application) is now loaded as an ES module — application.html includes it as <script type="module" src="js/CustScript.js"> — so it can use import statements of its own if your customizations need to pull in other JavaScript modules.
In USoft 10.1, CustScript.js defined a set of global functions that the framework called directly by name (applicationOnloadActions(), applicationOnbeforesubmitActions(), setCustomValue(), CustomAlert(), setCustomBenchmarkScripts()). In USoft 11, these same customization points are instead wired up through a single call to Udb.createApp(), passed in as an options object:
Udb.createApp({
customAlert(msg, type) {
// called when a page's Message Presentation property is set to 'Custom'
},
onbeforesubmit() {
// called on the onbeforesubmit of every page in the application
},
onloadPage() {
// called on the onload of every page in the application
},
setCustomBenchmarkScripts() {
// called when Web Benchmark is initialized and enabled in the application
},
setCustomValue(e, value, b) {
// called when a column value must be applied to a gridcell of type="custom"
e.innerText = value;
},
startPage() {
// optional: return the name of the page to start on, taking precedence
// over the publication's StartPage configuration parameter
}
}).then(() => {
// Write your own one-time startup code here, executed once the
// application has finished loading
});
Udb.createApp() bootstraps the application and returns a UdbPromise that resolves once loading has completed, so its .then() clause is the place for custom code that must run once, after startup — as opposed to onloadPage(), which runs on every page.
Udb (capital U, defined in usoft.js) is the small bootstrap class used to start the application, and is not the same object as the $.udb runtime API object used everywhere else in this Knowledge Base.
Every hook in the options object is optional: any that you omit simply falls back to a no-op, except for setCustomValue, which falls back to setting e.innerText directly. You only need to provide the hooks your application actually customizes.
Any existing functions in the upgraded CustScript.js must be looked at also; because it is an ES module now, these functions are no longer on the global (window) scope as before, and must be declared as such to be visible everywhere publicly again.
For example, this USoft 10.1 code made myHelperFunction() callable from anywhere — including an inline onclick="myHelperFunction()" attribute generated by Web Designer, or from any other, unrelated <script> tag — because top-level functions in a classic script are automatically added to window:
function myHelperFunction(value) {
return value.toUpperCase();
}
In USoft 11's module-based CustScript.js, this same declaration only creates a function local to the module: nothing outside of CustScript.js itself can see it anymore, so onclick="myHelperFunction()" would now fail with a myHelperFunction is not defined error. To restore the old, globally-callable behavior, assign the function to window (or the equivalent, engine-agnostic globalThis) explicitly, at the top level of the module:
function myHelperFunction(value) {
return value.toUpperCase();
}
window.myHelperFunction = myHelperFunction;
If you have several functions to expose this way, consider grouping them under a single namespace object instead of adding many separate globals:
window.MyApp = {
myHelperFunction(value) {
return value.toUpperCase();
},
myOtherHelperFunction() {
// ...
}
};
which can then be called elsewhere as MyApp.myHelperFunction(...).
Do the window/globalThis assignment at the top level of CustScript.js, not inside the .then() clause of Udb.createApp(). That callback only fires once the entire application has finished loading, which may be too late for other code (such as an inline event handler on the very first page) that expects the function to already be available.
Alternatively, if a function does not need anything that only an ES module offers (such as import), it does not need to live in CustScript.js at all: place it in its own file and attach it as an additional, plain (non-module) script — see How to add a script to your application. A top-level function declared in a regular, non-module script is still added to window automatically, exactly as it always was, so nothing further is needed to keep it globally callable.
$.udb functions
| Function | Changes in USoft 11 |
|---|---|
.acceptLookupValue() | Option keepOpen: dropped, because lookup display using DialogControls is no longer available. |
.applyCurrentContext() | New parameter: newPageAlias. |
.context() | Parameter create: dropped. |
.data.format | Moved to .ioFormat. |
.executeSQLStatement() | Deprecated, switching to SQLDataSources is encouraged. |
.groupRequests() | Obsolete and no longer functional. |
.isCommitted() | Name has changed into .isTransactionCommitted(). |
.off() | No longer uses jQuery to register and handle events. |
.on() | No longer uses jQuery to register and handle events. |
.setTimeout() | New behavior: to get the current values, use $.udb.setTimeout('current') instead of $.udb.setTimeout.current. |
.startPage() | No longer part of public API, so no longer directly callable. |
.status.loggedIn() | Now contains an optional parameter 'fn'. |
.status.setLoginStatus() | Moved to .setLoginStatus(). |
.trigger() | No longer uses jQuery to register and handle events. |
$.udb.ui functions
| Function | Changes in USoft 11 |
|---|---|
$.udb.dialog |
Now always returns a |
$.udb.input |
Now always returns a |
$.udb.wait | Now always returns a New feature: call count. Multiple To hide the control immediately, use |
$.udb.opacity | Now always returns a UdbPromise. |
$.udb.upload | Now always returns a UdbPromise. |
$.udb( dsRef ) functions
$.udb(<dsRef>) and $.udbMeta(<dsRef>) have been merged to a single structure, i.e., $.udb(<dsRef>).
Output changed to UdbDsc array of UdbDataSource instances instead of array of strings.
| Function | Changes in USoft 11 |
|---|---|
.busy() | New function. |
.cols() | Returns an UdbCols array of objects containing UdbColumn instances. |
.containsGetValue() | Dropped. |
.context() | New function. |
.data() | Instead of a generic JSON object, now returns an instance of the UdbDataSource class, of its specific type (i.e., UdbTableDataSource for a data source of type 'Table'). |
.dataInfo() | Replaced by .meta(). |
.extraKeys() | New function. |
.hasChild() | New function. |
.hasLookups() | New function. |
.isJoined() | Deprecated, because joined tables using the 'Joined' property are no longer supported. |
.isOnCurrentPage() | New function, previously only a data layer function. |
.isQueried() | New function. |
.joins() | Deprecated, because joined tables using the 'Joined' property are no longer supported. |
.keyCols() | Renamed to .keys(). |
.mainDataSource() | New function. |
.meta() | Returns the same array; previously used to transform $.udb() to $.udbMeta(). |
.realDataSource() | Output changed; now returns the actual data source object instead of its id value. |
.searchCols() | Returns an UdbCols array of objects containing UdbColumn instances. |
.setBusy() | New function. |
$.udb( dsRef ).rowSet( rowSetRef ) functions
This section lists changes to $.udb(<dsRef>).rowSet(<rowSetRef>) functions.
Output changed to UdbRowSets array of UdbRowSet instances instead of array of JSON objects.
| Function | Changes in USoft 11 |
|---|---|
.context() | New function. |
.data() | Dropped. |
.rows() | Returns an UdbRows array of UdbRecord instances. |
$.udb( dsRef ).rowSet( rowSetRef ).rows( ref1, ref2 ) functions
This section lists changes to $.udb(<dsRef>).rowSet(<rowSetRef>).rows(<ref1>,<ref2>) functions.
Output changed to UdbRows array of UdbRecord instances instead of array of JSON objects.
| Function | Changes in USoft 11 |
|---|---|
.cols() | Returns an UdbCols array of objects containing UdbColumn and UdbRecord instances. |
.context() | New function. |
.data() | Dropped. |
.joinedVal() | Deprecated because joined tables using the 'Joined' property are no longer supported. |
.keysString() | full parameter is dropped, because the full keys string is now always returned. |
.keysXML() | Obsolete, no longer supported. |
$.udb( dsRef ).rowSet( rowSetRef ).rows( ref1, ref2 ).cols( colRef ) functions
This section lists changes to $.udb(<dsRef>).rowSet(<rowSetRef>).rows(<ref1>, <ref2>).cols(<colRef>) functions.
Output changed to UdbCols array of UdbColumn instances instead of array of JSON objects.
| Function | Changes in USoft 11 |
|---|---|
.cols() | The .cols() and .colsMeta() functions have been merged into a single UdbCols structure. |
.colsMeta() | The .cols() and .colsMeta() functions have been merged into a single UdbCols structure. |
.context() | New function. |
.isKey() | Dropped. |
.label() | Dropped (was deprecated earlier by .prompt() in USoft 10.1). |
.meta() | Dropped. |
Object extension functions
USoft 10.1 offered extra functionality added to various kind of objects, e.g., .forEachValue() and .forEachKey(), .map(), but these could cause name clashes with third-party libraries. These functions (including some added as of USoft 11) have been moved to a .usoft extension. Use a .usoft prefix to access the USoft functions on the prototypes, for example:
object.usoft.map()
for
object.map()
.usoft is not limited to plain objects: Array, Date and String each get their own set of functions through it as well, and there are more of them than the two examples above. See UDB extension functions for the complete list, with examples for each.