Client JavaScript Extension API
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. Any returned string causes the log of an [OK] status. If you want to prevent logging, for example to avoid sensitive information to be written in the log file, you should return the string !
.
If you want to navigate to a specific page when the button is pressed (it would be like pressing a Button object in Link action mode), return a string starting with "page:" followed by the page name; in this case, userCommand() will be called again when that popup or page is closed, with "/close" appended to param.
You can also use "page:back" or "page:forward" to move back and forth along the pages' navigation history. Use "page:close" to close a popup.
When the interface is loaded inside the HSYCO App (iOS or Android), you can send a specific command to the app by returning a string that starts with “app:“ followed by the command; the commands currently supported are “speech“, which enables the speech recognition, and “codescan“ which enables qr/bar code scanning.
Use copy:<text>
to copy a text in the clipboard. In the HSYCO App you can also use share:<text>
to open a popup with various options. This will behave like "copy" on browser.
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
- "page:page name": navigate to the specified page
- "page:back": navigate to the previous page
- "page:forward": navigate to the next page
- "page:close": if the user button that generated the call has an open popup linked to it, close it
- "error": error. Don't send the request to the server
- "
copy:<text>
": tells the browser or HSYCO App to copy the text in the clipboard. On browser it will display a confirm popup with the text to be copied. - "
share:<text>
": tells the HSYCO App to show a share popup with various options (copy, send through email, save to files etc.). On browser it will behave like copy. - 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: an object containing error details, returned when the query fails:
- code: int - a numeric code representing the error type.
- message: string - a descriptive message explaining the error.
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": 1,
"message": "Generic error"
}
}
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.
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.
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: Array – An array of objects, each representing a row to update:
{
"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.
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.
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 begins 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.
webLog
webLog(string)
Adds a line to the daily log file, viewable from the Manager's Log Viewer.
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;
}
User Object
One or more User objects can be declared to send requests from the client to the server.
var user = new User();
function StartupEvent() {
user.setOnLoadedEvent(onUserLoaded);
user.setOnErrorEvent(onUserError);
// send reques
user.send("myname","myparam");
varSet("myvar1","myvalue");
varSet("myvar2",5.3);
varSet("myvar3",[1,2,3]);
varSet("myvar4",{"a":1,"b":2});
}
Methods
.send(name, param)
sends a virtualremote (name and param will be url encoded)
.setMaxWaitingTime(msec)
set max waiting time in msec. If a request exceeds this time, it will be aborted (and fire an onError event, if set).
.setMaxRetries(n)
set max number of retry attempts. If a a request fails, it will keep on retrying until it succeeds or the max number of retries is reached. Before retrying it will fire an onRetry event, if set. If n is 0, and retryOnErrorDelay is not 0, it will keep on retrying forever (it will never fire an onError event, if set).
.setRetryOnErrorDelay(msec)
set msec of delay before retrying after a request has failed. If msec is 0 it won't retry (and will fire an onError event, if set).
.setOnLoadedEvent(f)
f is a function that is called when the request is successful. To get the response text or xml, use .getResponseText() and .getResponseXML()
.setOnErrorEvent(f)
f is a function called when the request fails. f is called with an error code parameter: function(errCode) error codes are enumerated as .ERROR_GENERAL, .ERROR_CONNECTION ...
.setOnRetryEvent(f)
f is a function that is called when the last request failed, before retrying. To get the response text or xml, use .getResponseText() and .getResponseXML()
.getResponseText()
get the last response text
.getResponseXML()
get the last response XML
.free()
free the memory and reset the behaviour. It will be reinitialized if any method is called.
Error codes
- .ERROR_GENERAL : general error
- .ERROR_CONNECTION : no connection
- .ERROR_MAXWAITTIME : max waiting time exceeded
- .ERROR_LOGOUT : client is logged out
- .ERROR_LOCK : client is locked out
- .ERROR_NOACCESS : request returned noaccess
Examples
Try one time, then fire onLoaded or onError
var user = new User();
function StartupEvent() {
user.setOnLoadedEvent(onUserLoaded);
user.setOnError(onUserError);
// send request
user.send("myname","myparam");
}
function onUserLoaded() {
webLog("loaded "+user.getResponseText());
// do something with the response
user.free(); // won't be using it again
}
function onUserError(errCode) {
webLog("error");
user.free(); // won't be using it again
}
Retry forever, until it succeeds
var user = new User();
function StartupEvent() {
user.setOnLoadedEvent(onUserLoaded);
user.setRetryOnErrorDelay(1000); // wait one second before retrying on error
// send request
user.send("myname","myparam");
}
function onUserLoaded() {
webLog("loaded "+user.getResponseText());
// do something with the response
user.free(); // won't be using it again
}
Retry 3 times, then fire onError
var user = new User();
function StartupEvent() {
// init user object
user.setRetryOnErrorDelay(100); // retry almost immediately on error
user.setMaxRetries(3); // retry 3 times, then fire error
user.setOnLoadedEvent(onUserLoaded);
user.setOnError(onUserError);
// send request
user.send("myname","myparam");
}
function onUserLoaded() {
webLog("loaded "+user.getResponseText());
// do something with the response
user.free(); // won't be using it again
}
function onUserError(errCode) {
webLog("error, already tried 3 times");
if (errCode == user.ERROR_MAXWAITTIME)
webLog("the last request failed because it exceeded the waiting time");
user.free(); // won't be using it again
}