Skip to main content
Version: 4.2 (beta)

Client JavaScript Extension API

caution

WARNING! The client-side JavaScript extensions API is experimental and subject to changes.

A project can have specific javascript code that runs on the client-side and manages various events. This code has to be written in an index.js file located inside the project's directory.

Events​

These are functions executed on specific events.

initEvent​

function initEvent()

Executed when the web page is loaded. It's a good place to set up the interface and set variables, for example.

userCommand​

function userCommand(name, param)

Called by user clicks on Button object in action User mode.

This function can optionally return a string. Returning a command response string handles the command on the client without sending the request to the server. See the Command API for supported command response strings.

Parameters:

  • name: string - the name field of the user object
  • param: string - the param of the user object

Returns:

  • null: proceed to send the request to server as it is
  • "": assume the event was resolved. Don't send the request to the server
  • command response string: handle the command on the client without sending the request to the server. See the Command API for supported responses.
  • "error": error. Don't send the request to the server
  • an object, to specify new name and param values to be sent to the server
{name:"new name", param:"new param"}

userSubmit​

function userSubmit(name, param)

Called on every submit request of a Button object in Submit mode. Parameters and return values are the same as the userCommand function.

uiEvent​

function uiEvent(id, attr, value)

Executed on every UISet received from the server, intercepts a UISet and allows to change it, prevent its execution or execute any other custom code (e.g. set variables).

Parameters:

  • id: string - id of the ui object
  • attr: string - attribute name
  • value: string - new value being set

Returns:

  • null: discard the UISet
  • <string>: set a new value for the UISet. To keep the UISet as it is, return the initial value

pageOpenEvent​

function pageOpenEvent(name)

Called when a page is opened.

Parameters:

  • name: string - the page's id

Returns:

  • false: don't open the page. A pageOpenEvent is called on the previous page, as if it was reopened.
  • null: proceed to open the page
// page open event
function pageOpenEvent(name) {
console.log("opening "+name);
if (name =="wconfig") {
console.log("nope 1");
return false;
}
}

pageCloseEvent​

function pageCloseEvent(name)

Called when a page is closed.

Parameters:

  • name: string - the page's id

Returns:

  • false: don't close the page
  • null: proceed to close the page
// page close event
function pageCloseEvent(name) {
console.log("closing "+name);
if (name =="sconfig") {
console.log("nope 2");
return false;
}
}

pageBackEvent​

function pageBackEvent(name)

Called when a page back is requested.

Parameters:

  • name: string - the page's id

Returns:

  • false: don't close the page
  • null: proceed to close the page
// page back event
function pageBackEvent(name) {
console.log("backing from "+name);
if (name =="sconfig") {
console.log("nope 3");
return false;
}
}

dataSourceQuery​

dataSourceQuery(dataSourceId, columns)

Called when datasource data is requested.

If the function returns an object, the request is not sent to the server and the object is used as the response.

Parameters:

  • dataSourceId: string - the identifier of the datasource from which data is requested.
  • columns: Array - an array of column identifiers specifying the fields requested by the client. Contains "*" if all columns are requested.

Returns:

  • JSON Object - either the requested data or error information.
  • null: proceed to send the request to the server as it is

Success Response Structure:

  • timestamp: number - a UNIX timestamp indicating the moment of data retrieval.
  • columns: Array - an array of objects describing each column’s metadata:
    • name: string - the column name. It has to be unique within the datasource.
    • type: string - the column data type, which can be varchar, integer, decimal, boolean, date, time or timestamp.
    • key: boolean - indicates whether the column is a primary key. Optional, default is false. 0/1 values are also accepted.
    • size: number - the column size, in bytes. Optional.
    • nullable: boolean - indicates whether the column can contain null values. Optional, default is false. 0/1 values are also accepted.
    • readonly: boolean - indicates whether the column is read-only. Optional, default is false. 0/1 values are also accepted.
  • rows: Array - rows, where each row contains values corresponding to the specified columns. If "*" is received in the columns parameter, all available columns should be included in the response.

Error Response Structure:

  • error: a JSON object returned when the query fails:
    • code: int - a standard Command API error code. Optional.
    • message: string - a descriptive message explaining the error. Optional.
    • display: string - set to popup to display the error in a modal popup. Optional.

Query errors are shown as non-blocking toasts by default; use display: "popup" for a modal. The browser developer console logs the datasource id and any returned error code or message.

Response Example:

Successful Query:

{
"timestamp": 1702309200,
"columns": [
{ "name": "username", "type": "string", "key": true },
{ "name": "password", "type": "string" }
],
"rows": [
["user1", "abc12"],
["user2", "xyz34"]
]
}

Error Example:

{
"error": {
"code": 500
}
}

dataSourceInsert​

dataSourceInsert(dataSourceId, columns, data)

Called when an insert operation is attempted.

If the function returns an object, the request is not sent to the server; instead, the object is used as the response, and a session refresh is automatically triggered.

The returned JSON object can also include the standard Command API response keys. When the function returns a custom response while the current form or table edit popup remains open, the top-level fields property can modify the current fields, for example to display field errors or change field values. This is mainly useful before the SQL operation runs, or whenever the function skips or replaces the SQL operation and keeps the editor open.

Parameters:

  • dataSourceId: string - the datasource id.
  • columns: Array - array of column ids.
  • data: JSON Object - { "rows": [["<col 1 value>", "<col 2 value>", ...], ...] }

Returns:

  • JSON Object - inserted rows. Triggers a session refresh.
    • inserted: int - The number of rows successfully inserted.
  • null - no action is taken.

Response Example:

{
"inserted": 3
}

dataSourceUpdate​

dataSourceUpdate(dataSourceId, columns, data)

Called when an update operation is attempted.

If the function returns an object, the request is not sent to the server; instead, the object is used as the response, and a session refresh is automatically triggered.

To support table CSV imports, update functions should also include the keys of rows not found in the datasource in not_found. During import, keyed rows are tried as updates first; rows returned in not_found are then inserted. This protects filtered or stale datasource views, where a row that looks new to the client may already exist in the datasource. Returning only an update count is not enough for the insert fallback, because the table needs the specific missing keys.

The returned JSON object can also include the standard Command API response keys. When the function returns a custom response while the current form or table edit popup remains open, the top-level fields property can modify the current fields, for example to display field errors or change field values. This is mainly useful before the SQL operation runs, or whenever the function skips or replaces the SQL operation and keeps the editor open.

Parameters:

  • dataSourceId: string - the datasource id.
  • columns: Array - array of column ids.
  • data: JSON Object - contains the data to update.
    • rows: Array – An array of objects, each representing a row to update:
      • <key value>: string – the key value identifying the row to update. This is the property name.
      • Value (Array): an array of column values corresponding to the column IDs specified in the columns parameter.
{
"rows": [
{
"<key value>": ["<col 1 value>", "<col 2 value>", ...]
},
...
]
}

Returns:

  • JSON Object - updated rows. Triggers a session refresh.
    • updated: int - The number of rows successfully updated.
    • not_found: Array - An array of keys not found in the datasource. Optional; required for table CSV import fallback.

Example Data:

{
"rows": [
{
"key1": ["key1", "value1", "value2"]
},
{
"key2": ["key2", "value3", "value4"]
}
]
}

Response Example:

{
"updated": 2,
"not_found": ["key1"]
}

dataSourceDelete​

dataSourceDelete(dataSourceId, data)

Called when a delete operation is attempted.

If the function returns an object, the request is not sent to the server; instead, the object is used as the response, and a session refresh is automatically triggered.

The returned JSON object can also include the standard Command API response keys.

Parameters:

  • dataSourceId: string - the datasource id
  • data: JSON Object - { "rows": ["key 1>", "key 2>", ... ] }

Returns:

  • JSONObject - deleted rows. Triggers a session refresh.
    • deleted: int - the number of rows successfully deleted.
    • not_found: Array - An array of keys not found in the datasource. Optional.
  • null - no action is taken.

Response Example:

{
"deleted": 1,
"not_found": ["key1"]
}

Functions​

varSet​

varSet(name, value)

Sets the value of a variable. If the name ends with !, the variable will be stored in the browser's cache, so that it'll available even after reloading the page or closing and reopening the browser.

varGet​

varGet(name)

Gets the value of a variable previously set with varSet.

uiSet​

uiSet(id, attr, value)

Sets a UI attribute on every object with the specified ID, only in this browser. The value is not sent to the server, so other clients are not affected, and a later UISET of the same attribute from the server replaces it.

webLog​

webLog(string)

Adds a line to the daily log file, viewable from the Manager's Log Viewer.

sendCommand​

sendCommand(name, param, onLoaded, onError)

Sends a command to the server asynchronously, with optional callbacks for success and error handling. Parameters:

  • name: string — command name to send to the server (will be URL encoded)
  • param: string — command parameter (will be URL encoded)
  • onLoaded: function(responseJson) — optional callback invoked when the request succeeds. responseJson is the parsed JSON object returned by the server.
  • onError: function() — optional callback invoked when the request fails. Called without parameters.

Examples​

Using varget and varset​

In this example we declare a persistent variable (stored in the browser's local storage) the first time any user button is pressed, we increment it each time up to 10 and then we reset it to 0. When the variable equals 3, the page "page1" is shown. When the variable equals 7, the request isn't forwarded to the server.

function userCommand(name, param) {
var a = varGet("counter!"); // get the variable value

if (!a) // first time and when a is 0
a = 1;
else if (a < 10)
a++;
else // reset
a = 0;

varSet("counter!",a); // set the variable value

webLog("usercommand:"+name+","+param+". Counter:"+a)
if (a == 3)
return "page:page1";
else if (a == 7)
return "";
else
return null;
}

Sending a command​

Try once, then handle onLoaded or onError​

function StartupEvent() {
// send the command and handle result with callbacks
sendCommand("myname", "myparam", function(responseJson) {
webLog("loaded " + JSON.stringify(responseJson));
// do something with the parsed JSON response
}, function() {
webLog("error");
});
}

Retry with a manual loop (example pattern)​

function sendWithRetry(name, param, retries, delay) {
var attempt = 0;

function tryOnce() {
sendCommand(name, param, function(responseJson) {
webLog("loaded " + JSON.stringify(responseJson));
}, function() {
attempt++;
if (attempt <= retries) {
setTimeout(tryOnce, delay);
} else {
webLog("error, already tried " + retries + " times");
}
});
}

tryOnce();
}

function StartupEvent() {
// retry 3 times with 100ms delay
sendWithRetry("myname", "myparam", 3, 100);
}