---
title: Functions available in the modern client
description: |
  Details about the functions/methods used in the UIBUILDER front-end client library. Some functions are available to your own custom code and some are hidden inside the `uibuilder` client object.
created: 2023-01-28 15:56:57
updated: 2024-08-25 15:20:01
---

Functions accessible in client-side user code.

- [Receiving Messages from Node-RED](#receiving-messages-from-node-red)
- [Sending Messages to Node-RED](#sending-messages-to-node-red)
- [Variable Handling](#variable-handling)
- [UI Handling](#ui-handling)
- [HTML/DOM Cacheing](#htmldom-cacheing)
- [Event Handling](#event-handling)
- [Utility](#utility)
- [Startup](#startup)
- [Alphabetical function list](#alphabetical-function-list)

> [!NOTE]
> Where functions are marked as being accessible as Node-RED command messages, details can be found in [Controling From Node-RED](client-docs/control-from-node-red).


## Receiving Messages from Node-RED

UIBUILDER automatically creates a live websocket channel from the Node-RED server to your browser when you open a UIBUILDER page. By sending a msg to a UIBUILDER node, it will be transferred to ALL connected clients unless you specify otherwise.

To process a message in your browser, you can use one of the event handling UIBUILDER library functions such as [`onChange`](#event-handling) or [`onTopic`](#event-handling). Alternatively, you can use the standard `document.addEventListener` function to listen for one of the UIBUILDER library's custom events.

You can also do `uibuilder.set('msg', {/*your object details*/})` in your front-end code which instructs the client to treat the object as though it had come from Node-RED.

You can use one or more of the `msg._uib.pageName`, `msg._uib.clientId`, or `msg._uib.tabId` properties to control whether a specific page, client or browser tab will process an inbound message. Use this where you have multiple pages or clients and need to target a message to a specific one.

UIBUILDER also allows you to issue control commands from Node-RED to your front-end app by sending messages to the `uibuilder` node containing `msg._uib.command` which must be set to [one of the recognised commands](/client-docs/control-from-node-red).

### Rooms

Rooms are a Socket.IO server concept. For UIBUILDER, they are simulated on the client by using standard message titles. Their use allows flexible messaging from any uibuilder connected client or a custom uibuilder node to any other uibuilder connected client or custom uibuilder node.

UIBUILDER clients are automatically subscribed to a number of rooms based on the client socket ID, page name and client ID. They are also subscribed to a "global" channel.

See also [sendRoom](#sendRoom) for sending messages to an arbitrary room.

#### `joinRoom(room)` - Join an arbitrary socket.io room to receive messages from it :id=joinRoom

This simulates joining a specified room on the client side, uibuilder will start forwarding messages sent to the room to this client.

> [!WARNING]
> As yet, the client has no way of handling messages from the server in these rooms.

#### `leaveRoom(room)` - Leave an arbitrary socket.io room to stop receiving messages from it :id=leaveRoom

This simulates leaving a specified room on the client side, uibuilder will stop forwarding messages sent to the room to this client.

## Sending Messages to Node-RED

### `eventSend(domevent, originator = '')` - Send a standard message back to Node-RED in response to a DOM event :id=eventSend

This is a convenience function that is useful to attach as an event handler on an HTML DOM event (e.g. the click event of a button). Since it only requires the DOM event object that the DOM provides automatically.

In HTML code, use as `<button onclick="uibuilder.eventSend(event)">`. `onchange` and other event types will work as well.

The response includes some additional useful event data such as what modifier keys were active (e.g. shift, ctrl, etc) when the event happened.

If you want to add custom data to the response, you can add `data-xxxx` attributes to the originating HTML tag. These appear as named `msg.payload` properties.

If the source event is generated by a tag inside an HTML `<form>`, the names and values for all input elements in the form at the time of sending will be attached as `msg.payload` properties. Extended data for all input elements inside the form are included in `msg._ui.form`.

If the source event type is `change` (e.g. a user changed an input field and then moved to a new field), the value of the input is put into both `msg.payload.value` and `msg._ui.newValue`. If you want to report the old value as well, you need to add something like `onfocus="this.setAttribute('data-oldvalue', this.value)"` to the element's attributes. This would be included both in `msg.payload.oldvalue` and in `msg._ui.attribs.data-oldvalue`. Alternatively, `onfocus="this.uib_oldvalue = this.value"` would cause the previous value to be included as `msg._ui.props.uib_oldvalue`.

> [!NOTE]
> When using `eventSend` on a button within a form, the message will be sent even if the form is invalid. `msg._ui.form.valid` will be true or false so that you can check for validity within Node-RED. Additional validity data will be available within each returned `msg._ui.form` object of which there is one entry for each input type (including buttons).
>
> See [Zero-code element types > Forms](elements/forms) for more detail.
>
> The input element validity property can contain any of the following: badInput, customError, patternMismatch, rangeOverflow, rangeUnderflow, stepMismatch, tooLong, tooShort, typeMismatch, valueMissing. See [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState) for details of the meanings.


### `beaconLog(txtToSend, logLevel)` - Send a short log message to Node-RED :id=beaconLog

This has the advantage of working even if Socket.IO is not connected. It uses a logging API provided by UIBUILDER.

However, only text strings can be sent and messages need to be kept short. It only works with modern browsers that support the web beacon API.

The `logLevel` matches both Node-RED and UIBUILDER defined log levels (e.g. error, warn, info, debug, trace ).

### `getPageMeta()` - Requests the current page's static file metadata from the server :id=getpagemeta

This is handled as a uibuilder control message. The return data is also a control message handled by the internal function `uibuilder._ctrlMsgFromServer()`.

The returned data is set into the uibuilder [managed variable `pageMeta`](/client-docs/variables#read-only).

### `htmlSend()` - Sends the whole DOM/HTML back to Node-RED :id=htmlSend

Results in a standard message sent to Node-RED where the `msg.payload` contains the whole current HTML page as a string.

Use with the `uib-save` node to fix the latest page complete with any dynamic updates as the html page to load for new client connections for example.

The returned message includes `msg.length` to allow checking that the returned html payload wasn't truncated by a Socket.IO message length restriction.

This can also be triggered from Node-RED. Send a message to the `uibuilder` node containing `msg._uib.command` set to "htmlSend". [Reference](client-docs/control-from-node-red?id=get-complete-copy-of-the-current-web-page)

### ~~logToServer()~~ - Not yet reliable. Will cause the input to appear in Node-RED logs :id=logToServer

### `send(msg, originator = '')` - Send a custom message back to Node-RED :id=send

The `msg` format is the same as used in Node-RED. 

The `originator` is optional and if used, should match the id from a `uib-sender` node. That allows you to specifically return a message into a flow that uses one of those nodes. However, ensure that the `uib-sender` node has turned on the flag to allow returned messages.

### `sendCtrl(msg)` - Send a custom control message back to Node-RED :id=sendCtrl

The message will be assessed by UIBUILDER and passed to its #2 (bottom) output port if considered acceptible.

This lets you create your own control custom messages should you wish to. Use with caution.

### `sendCustom(channel, msg)` - Send a message to a custom socket.io channel :id=sendcustom

This allows for front-end browser code to send a message back to Node-RED on any arbitrary Socket.IO channel.

This is only really useful for custom extension nodes for UIBUILDER.

### `sendRoom(room, msg)` - Send a message to an arbitrary socket.io room :id=sendRoom

Socket.IO rooms are server-side concepts for partitioning messages. This simulates the feature on the client side.

See also [joinRoom](#joinRoom) and [leaveRoom](#leaveRoom) for controlling receipt of room messages.

### `setOriginator(originator = '')` - Set/clear the default originator :id=setOriginator

Will automatically be used by `send` and `eventSend`.

Set to an empty string to remove.

### `setPing(ms)` - Set a repeating ping/keep-alive HTTP call to Node-RED :id=setPing

This uses an HTTP API call to a custom UIBUILDER API endpoint in Node-RED. So it works even if the Socket.IO connection is not working. It is used to check that the Node-RED server and the UIBUILDER instance are both still working.

#### Example

```javascript
uibuilder.setPing(2000) // repeat every 2 sec. Re-issue with ping(0) to turn off repeat.

// Optionally monitor responses
uibuilder.onChange('ping', function(data) {
   console.log('pinger', data)
})
```

### `uploadFile(File)` - Upload a file to Node-RED over Socket.IO :id=uploadFile

`File` must be a reference to a FileHandler API file object. These can be generated by `<input type="file">` or file drag/drop change events.

Converts the reference to a Buffer and attempts to send back to Node-RED as a standard message.

> [!WARNING]
> Socket.IO has a default maximum message size of 1MB. Any file close to this size may fail. The uibuilder client library will issue an error message if the message content is equal to or larger than the current `maxHttpBufferSize` setting.
>
> You can change this by setting an override in Node-RED's `settings.js` file and restarting Node-RED. See the [settings documentation](/uib-configuration#settingsjs) `socketOptions` for details. The client variable `uibuilder.maxHttpBufferSize` contains the current size setting. This is also shown in Node-RED in the initial "client connect" control message.

## Variable Handling

> [!NOTE]
> See [client variables](client-docs/variables) for details of what uibuilder variables are available.

### `copyToClipboard(varToCopy)` - Copy the specified uibuilder variable to the browser clipboard :id=copyToClipboard

Can only be used as an event handler because browsers do not allow unrestricted JavaScript access to the browser clipboard.

`varToCopy` has to be a variable specified in UIBUILDER. One that could be retrieved by `uibuilder.get('varToCopy')`.

```html
<button onclick="copyToClipboard('version')">Copy UIBUILDER client version string to clipboard</button>
```

### `get(prop)` - Get a uibuilder property :id=get

This is the preferred method to get an exposed UIBUILDER variable or property. Do not try to access variables and properties directly unless explicitly shared in this documentation. This function can also be called from Node-RED via `msg._uib.command` - `get` with `msg._uib.prop` set to the variable name to get.

#### Example

```javascript
console.log( uibuilder.get('version') )
```

### `getManagedVarList()` - Get a list of all uibuilder managed variables :id=getManagedVarList

A UIBUILDER managed variable is one that has been created with `uibuilder.set()` (or changed from Node-RED with the equivalent command msg). As such, it can be watched for changes with `uibuilder.onChange()`.

This function can also be called from Node-RED via `msg._uib.command` - `getManagedVarList`. The returned `msg.payload` contains the list. Optionally, you can also add `msg._uib.prop` set to `full` which will return an object where each key/value is the variable name. This can be usefull for some types of processing.

### `getWatchedVars()` - Get a list of all uibuilder watched variables :id=getWatchedVars

Shows all variables that are being watched using `uibuilder.onChange()`.

This function can also be called from Node-RED via `msg._uib.command` - `getWatchedVars`. The returned `msg.payload` contains the list.

> [!WARNING]
> `localStorage` is shared per _(sub)domain_, e.g. the IP address/name and port number. All pages from the same origin share the variables.

### `getStore(id)` - Attempt to get and re-hydrate a key value from browser localStorage :id=getStore

Note that browser localStorage is persisted even after a browser closes. It can be manually cleared from the browser's settings. You can also remove an item using the `removeStore` function.

If the `id` is not found in the store, `null` is returned. If the store is not available or some other error occurs, `undefined` is returned.

All `id`s have a pre-defined UIBUILDER prefix added to the key name to help ensure that the key being saved will be unique. This prefix is defined in the library and cannot be changed, it is set to `uib_`.

Because the browser storage API only allows strings as values, the data has to be serialised. This function attempts to unserialise (re-hydrate). It should be noted that sometimes, this process results in values that may differ from the original. For example, `uibuilder.setStore('mydate',new Date()); console.log( uibuilder.getStore('mydate') )` will return the saved date as an ISO8602 date string, not a JavaScript Date object.

### `removeStore(id)` - Attempt to remove a uibuilder key from browser localStorage :id=removeStore

Does not return anything. Does not generate an error if the key does not exist.

> [!WARNING]
> `localStorage` is shared per _(sub)domain_, e.g. the IP address/name and port number. All pages from the same origin share the variables. It also only survives until the browser is closed.

### `set(prop, val, store, autoload)` - Set a uibuilder property and dispatch a change event :id=set

This is the preferred method to set an exposed UIBUILDER variable or property. Do not try to set variables and properties directly.

When using set, the variable that is set becomes ***responsive***. That is to say, that issuing a set triggers both the internal event handler (as used in `uibuilder.onChange('prop', ...)`) but also the DOM custom event `uibuilder:propertyChanged`. Normally, you will want to use the `onChange` handler.

> [!TIP]
>
> To send an update message to Node-RED whenever a managed variable changes, use `uibuilder.onChange('varname', (data) => uibuilder.send({payload: data}))` in your JavaScript.

Note that you can add additional custom data variables to the UIBUILDER object but care must be taken not to overwrite existing internal variables. This is useful if you want to be able to automatically process changes to your own variables using the `onChange` handler.

#### Arguments

* `prop` - (required) the variable to set and manage
* `val` - (required) the value to set the prop to
* `store`  - (optional) true/false. Default=false. If true, the change is written to the browser `localStorage` as well if possible.
  
  > [!WARNING]
  > `localStorage` is shared per _(sub)domain_, e.g. the IP address/name and port number. All pages from the same origin share the variables. It also only survives until the browser is *closed*.

* `autoload` - (optional) true/false. Default=false. If true and if `store` is true, uibuilder will try to automatically restore the variable on future page loads. Do another `set` with this set to false to turn off.

#### Remote call

This function *can also be called from Node-RED* via `msg._uib.command` - `set` with `msg._uib.prop` set to the variable name to set. and `msg._uib.value` set to the new value. `msg._uib.options` is used as `{store: true, autoload: true}` to optionally pass the additional arguments.


#### Example

```javascript
// Optionally send changes back to Node-RED
uibuilder.onChange('loglevel', (data) => uibuilder.send({topic: 'loglevel changed', payload: data}))

uibuilder.set('logLevel', 3)
```

### `setStore(id, val, autoload)` - Attempt to save to the browsers localStorage :id=setStore

Write a value to the given id to localStorage. Will fail if localStorage has been turned off or is full.

The value to save has to be serialisable. Some JavaScript objects cannot be serialised (using `JSON.stringify`). If this happens `false` is returned and an error output to the browser console. However, you can store any basic value (number, string, boolean) as well as array's and objects.

Browsers set a limit on the size of the store for a particular source. Typically this is 10MB but may be altered by the user. The user can turn off localStorage as well.

Returns `true` if the save was successful, otherwise returns false.

Errors are output to the browser console if saving fails but processing will continue.

> [!WARNING]
> `localStorage` is shared per _(sub)domain_, e.g. the IP address/name and port number. All pages from the same origin share the variables. It also only survives until the browser is closed.

## UI Handling

These are the new dynamic, configuration-driven UI features. They let you create your UI dynamically from simple data sent to the client.

In addition, internal message handling will recognise standard messages from node-red and process them. So these functions won't always be needed. You can also do `uibuilder.set('msg', {/*your object details*/})` which instructs the client to treat the object as though it had come from Node-RED.

For functions with no descriptions, please refer to the code. In general, these will not need to be used in your own code.

### `applyTemplate(sourceId, targetId, config)` - Apply template element content to the page :id=applyTemplate

This takes HTML (including styles and scripts) from a `<template>` tag. Templates are not active parts of the page but can be applied to a page, potentially multiple times. Great if you have some standard content that you might need to dynamically add to the page (a new list entry or table row for example).

`sourceId` (required) must be the HTML id attribute value of a `<template>` tag on-page.

`targetId` (required) must be the id of an on-page element to which the template contents will be _appended_ as children.

`config` (optional) is an object with 2 possible properties:

* `config.onceOnly` (optional) if set to `true`, the contents of the template will be consumed and can not be re-used. Otherwise, the template may be reused as often as needed.
* `config.attributes` (optional) if provided, must be an object containing attribute-name:value pairs. These will be applied to the **first child element** of the template allowing any attribute (e.g. `id`, `class`, etc) to be set.

> [!NOTE]
> If the template contains `<style>` content, this becomes global to the page once it has been applied once.
>
> If the template contains `<script>` content, this is **run every time the template is applied**. So make sure you wrap any code in a test that will prevent it from re-running if that is important.

See the Node-RED example library "Dynamic SVG Example" flow for an example using this function.

### `addClass(classNames, el)` - Add one or more classes to an element :id=addClass

`classNames` can be a string to add a single class or an array of strings for multiple classes.

`el` must be a single HTML element, e.g. `$('#more')`

```javascript
uibuilder.addClass('myclass', $('#more'))
uibuilder.addClass(['class1', 'class2'], $('#more'))
```

See also [removeClass](#removeClass). Uses [`el.classList.add`](https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList/add)

Note that if you want to _toggle_ a class on/off, use the HTML DOM: `$('#more').classList.toggle('myclass')`. See [MDN DOMTokenList/toggle](https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList/toggle) for details.

### `buildHtmlTable(data)` - Builds an HTML table from an array (or object) of objects :id=buildHtmlTable

The first row of data is also used to define the columns.

If the data is an object of objects, the outer keys are used as row ID's (prefixed with "r-").

### `convertMarkdown(mdText)` - Convert's Markdown text input to HTML :id=convertMarkdown

Returns an HTML string converted from the Markdown input text. Only if the Markdown-IT library is loaded, otherwise just returns the input text.

### `elementExists(cssSelector, msg = true)` - Does the element exist on the page? :id=elementExists

Returns a payload of true or false depending on whether the selected element exists on the page.

Available as a command. Can be called from Node-RED with a message like: `{"command":"elementExists","prop":"#more"}`.

### **TEMPORARILY DEPRECATED** Do not use ~~`elementIsVisible(cssSelector, stop = false, threshold = 0.1)` - Can an HTML element currently be seen by the user?~~ :id=elementIsVisible

> [!NOTE]
> This function was not working correctly and the complexities of using the Intersection Observer API mean that a resolution would take more time than is currently warrented.
> So, for now, this function is not usable.
>
> Info retained for future use.

When the selected element is showing at least 10% in the users browser view, sends a message to Node-RED with `msg.isVisible` set to `true`. Will send another message if the elements shows less than 10%. Will continue to send messages when the element moves in and out of visibility.

To turn it off, call it again with the same cssSelector but with the `stop` argument set to `true`.

The `threshold` argument defaults to 0.1 (10%). It must be between 0 and 1 and represents, as a percentage, how much of the element must be in the browser viewport to trigger an output.

Notes:

* Unlike the visibility control message, this function sends a standard message AND is not effected by the browser tab visibility. So even if the tab containing the page is not visible but the element would be if the tab were showing, the result of this function is still TRUE.
* Requires the browser to support the IntersectionObserver API (available to all mainstream browsers from early 2019).
* The element has to exist on the page before it can be observed.
* Turn on the optional `msg._uib` feature in the UIBUILDER node to see which client is sending the messages.
* Due to the nature of the IntersectionObserver API, this fn is not available as a command for now.

### `getElementAttributes(el)` - Returns an object containing attribute-name/value keypairs (or an empty object) :id=getElementAttributes

`el` = Target element.

Attempts to get target elements attributes. This can fail for certain target types, if so, returns empty object. Ignores `class`, `id` and `name` attributes.

Returns an array of key/value HTML attribute objects.
  
### `getElementClasses(el)` - Checks for CSS Classes and return as array if found or undefined if not :id=getElementClasses

`el` = Target element.

Checks for CSS Classes and returns them as an array if found or undefined if not.

### `getElementCustomProps(el)` - Returns an object containing an elements custom property/value pairs :id=getElementCustomProps

An elements custom properties are those set using code that are not standard properties. Unlike an elements attributes, they can contain any valid JavaScript data.

Excludes any properties that start with `_`.

### `getFormElementDetails(el)` Returns an object containing the key properties of a form element :id=getFormElementDetails

For HTML Form elements (e.g. input, textarea, select), returns the key properties/attributes such as `value` and `checked`.

The details are quite comprehensive and are designed to level out some of the inconsistencies normally found in HTML inputs.

This function is also used by the `uibuilder.eventSend(event)` function.

### `getFormElementValue(el)` Check for el.value and el.checked, return as an object :id=getFormElementValue

If found, `el.checked` will also set the `value` property in the returned object for ease of use.

HTML only uses the `checked` property on 2 input types. Where it is used, the `value` property is not used. This inconsistency results in extra code or hard to find errors. This function therefore returns both properties where `checked` is used.

### `htmlSend()` - Sends the whole DOM/HTML back to Node-RED :id=htmlSend2

See under [Message Handling](#message-handling) above for details.

### `include(url, uiOptions)` - insert an external file into the web page :id=include

Requires a browser supporting the [`fetch` API](https://caniuse.com/fetch). This function is asynchronous, that should be allowed for when using in custom front-end code.

> [!NOTE]
> This function uses the standard [`replaceSlot`](#replaceslotel-component-replace-or-add-an-html-element39s-slot-from-text-or-an-html-string) internal function. As such, it will use [DOMPurify](client-docs/readme#_1-dompurify-sanitises-html-to-ensure-safety-and-security) if loaded. DOMPurify will block the loading of most file types.

The `uiOptions` parameter is **required** and must contain at least an `id` property. Options are:

```json
{
  // REQUIRED: Must be unique on the web page and is applied to the wrapping `div` tag.
  "id": "unique99",
  // A CSS Selector that identifies the parent element to which the included 
  // file will be attached. If not provided, 'body' will be used
  "parent": "#more",
  // Optional. If the parent has multiple children, identifies where the new element
  // will be inserted. Defaults to "last". May be "first", "last" or a number.
  "position": "last",
  // Optional. Attributes that will be applied to the wrapping DIV tag
  "attributes": {
    // NB: The "included" class is applied by default, if adding further 
    //     classes it is generally best to include that.
    "class": "myclass included"
  }
  // Other properties from the UI `replace` mode may also be included but 
  // caution is required not to clash with properties from the included file.
}
```

Each of the includes are wrapped in a `div` tag to which the supplied `id` attribute is applied along with a class of `included`. This makes styling of the included elements very easy. For example, to style an included image, add something like this to your `index.css` file: `.included img { width: 100%, border:5px solid silver;}`.

The following file types are handled:

* *HTML document/fragment* (*.html) - Will be wrapped in a div given the specified `id` attribute.
  
  If the `DOMPurify` library is loaded before the UIBUILDER client library, it will be used to sanitise the HTML.

* *Image* - Any image file type recognised by the browser will be shown using an `img` tag (wrapped in the div as usual).
* *Video* - Any video file type recognised by the browser will be shown using a `video` tag (wrapped in the div as usual). The video controls will be shown and it will auto-play if the browser allows it.
* *JSON* - A `*.json` file will be syntax highlighted and shown in a panel. The syntax highlight CSS is contained in the `uib-brand.css` file and can be copied to your own CSS definitions if needed. The panel is defined as a `pre` tag with the `syntax-highlight` class added.
* *PDF* - A `*.pdf` file will be shown in a resizable iFrame.
* *Text* - The contents of the text file will be shown in a resizable iFrame.
* *Other* - Any other file type will be shown in a resizable iFrame.

Any file type that the browser cannot handle will trigger the browser to automatically download it. This is a browser limitation.

Can be called from Node-RED with a message like: `{"command":"include","prop":"./test.html","value":{"id":"incHtm","parent":"#more","attributes":{"style":"width:50%;"}}}`.

### `loadScriptSrc(url)`, `loadStyleSrc(url)`, `loadScriptTxt(string)`, `loadStyleTxt(string)` - Attach a new script or CSS stylesheet to the end of HEAD synchronously :id=load

Either from a remote URL or from a text string.

Directly call the functions of the same name from the `ui.js` library.

### `loadui(url)` - Load a dynamic UI from a JSON web response :id=loadui

Requires a valid URL that returns correct _ui data. For example, a JSON file delivered via static web server or a dynamic API that returns JSON as the body response.

Directly calls `_ui.loadui` from the `ui.js` library.

### `notify(config)` - Use the browser and OS notification API to show a message to the user :id=notify

Requires a browser that supports the [Notification API](https://developer.mozilla.org/en-US/docs/Web/API/Notification/Notification).

> [!WARNING]
> Users will almost certainly have to spot that their browser initially blocks notifications for a particular web endpoint.
> They will need to allow notifications manually before they will work.

#### Examples

```javascript
// Simple string input
uibuilder.notify( 'My simple message to the user' )
// Node-RED msg object style input
uibuilder.notify( {topic: 'My Title', payload: 'My simple message to the user'} )
// Notification API style input
uibuilder.notify( {title: 'My Title', body: 'My simple message to the user'} )

// If notifyConfig.return = true, a promise is returned.
// The resolved promise is only returned if the notification is clicked by the user.
// Can be used to send the response back to Node-RED
uibuilder.notify(notifyConfig).then( res => uibuilder.eventSend(res) )
```

When returning the response to Node-RED, the following style of msg is output:

```json
{
  "payload":"notification-click",
  "_ui": {
    "type":"eventSend", 
    "props": {"userAction":"click"}, 
    "notification": {
      "actions":[],"badge":"","body":"My simple message to the user",
      "data":null,"dir":"auto","icon":"","image":"","lang":"",
      "renotify":false,"requireInteraction":false,"silent":false,
      "tag":"","timestamp":1688303511972,"title":"My Title","vibrate":[]
    },
    "event":"click",
    "clientId":"-4MmSwnSrvJIOzVWgqcQv","pageName":"index.html","tabId":"t588851"
  },
  "_socketId":"RlLfI6HDnhbcttB5AAAH","topic":"title","_msgid":"64a614702ff90fff"
}
```

### `removeClass(classNames, el)` - Remove all, one or more classes from an element :id=removeClass

`classNames` can be a string to remove a single class, an array of strings for multiple classes. Or can be an empty string, `null` or `undefined` to remove all classes (will remove the `class` attribute).

`el` must be a single HTML element, e.g. `$('#more')`

```javascript
uibuilder.removeClass(null, $('#more')) // remove all
uibuilder.removeClass('myclass', $('#more')) // remove 1
uibuilder.removeClass(['class1', 'class2'], $('#more')) // remove multiple
```

See also [addClass](#addClass). Uses [`el.classList.remove`](https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList/remove)

Note that if you want to _toggle_ a class on/off, use the HTML DOM: `$('#more').classList.toggle('myclass')`. See [MDN DOMTokenList/toggle](https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList/toggle) for details.

### `replaceSlot(el, component)` - Replace or add an HTML element's slot from text or an HTML string :id=replaceSlot

This function is mostly for internal use.

`el` must be an HTML Element, its slot content will be replaced.

`component` must be a single `_ui` components entry with a `slot` property that will be used to replace the `el`s slot.

Will use [DOMPurify](client-docs/readme#_1-dompurify-sanitises-html-to-ensure-safety-and-security) if that library has been loaded.

Directly calls `_ui.replaceSlot` from the `ui.js` library.

### `replaceSlotMarkdown(el, component)` - Replace or add an HTML element's slot from a Markdown string :id=replaceSlotMarkdown

This function is mostly for internal use.

The [Markdown-IT](client-docs/readme#_2-markdown-it-converts-markdown-markup-into-html) library must be loaded for this to work, otherwise it silently fails.

`el` must be an HTML Element, its slot content will be replaced.

`component` must be a single `_ui` components entry with a `markdownSlot` property that will be used to replace the `el`s slot after being run through Markdown-IT to turn it into HTML.

Will use [DOMPurify](client-docs/readme#_1-dompurify-sanitises-html-to-ensure-safety-and-security) if that library has been loaded.

Directly calls `_ui.replaceSlotMarkdown` from the `ui.js` library.

### `returnElementId(el)` - Return elements existing ID or, add a new unique id to the element and return it :id=returnElementId

Returns the element's existing ID. Or, if not present, attempts to create a page unique id from the name attribute or the attribute type. The last 2 will use a page-unique number to enforce uniqueness.

### `sanitiseHTML(htmlText)` - Ensures that input HTML text is safe :id=sanitiseHTML

Returns a safe, sanitised HTML string IF the DOMPurify library is loaded. Otherwise returns the input.

### `scrollTo(cssSelector)` - Scroll visible page to an element based on a CSS Selector :id=scrollTo

If the top of the selected element is not currently visible in the browser window, will scroll (the top by default) to make it visible.

An optional 2nd argument can be added to better control what becomes visible. Please see the options for the [`scrollIntoView`](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView) DOM API for details of the options. The options object is passed through to that API.

In addition, the cssSelector string `top` or `start` will scroll to the top of the page and `bottom` or `end` will scroll to the bottom of the page.

Returns `true` if the element was found, false otherwise.

Can also be called from Node-RED with a command message: `{"_uib": {command: "scrollTo", "prop": "cssSelector"}}` or, with options: `{"_uib": {command: "scrollTo", "prop": "#mydivid", "value": {"block": "bottom"}}}`.

### `showDialog(type, ui, msg)` - Show a toast or alert style message on the UI :id=showDialog

Directly calls `_ui.showDialog` from the `ui.js` library.

`type` is either "notify" or "alert".

`msg` is optional. If passed, msg.topic and msg.payload will be used.

`ui` allows control over the element that is created. Allowed properties are:

```json
{
  // Optional title. May include HTML. If not set, will use msg.topic
  "title": "",
  // The message content. Note that msg.payload will also be added. May include HTML.
  "content": "",
  // Optionally set to any class name or one of: 
  //   'primary', 'secondary', 'success', 'info', 'warn', 'warning', 'failure', 'error', 'danger'
  "varient": "",
  // Optionally turn off the 10s auto-hide of the message.
  "noAutohide": false,
  "autohide": true, // opposite of noAutoHide, use one or the other
  "autoHideDelay": 10000, // 10s
  // Make the dialog modal - currently not used as all dialogs are model. For future use.
  "modal": true,
  // Append messages after each other otherwise latest messages appear on top.
  "appendToast": false,
}
```

### `showMsg(boolean, parent=body)` - Show/hide a card that automatically updates and shows the last incoming msg from Node-RED :id=showMsg

Simply add `uibuilder.showMsg(true)` early in your index.js custom code and a box will be added to the end of your page that will automatically show the last message sent from Node-RED. Use `uibuilder.showMsg()` to toggle the display.

`uibuilder.showMsg(false)` or `uibuilder.showMsg()` will remove the box and stop the updates.

You can also position the box in a different location by specifying a "parent". This is a CSS selector that, if found on the page, UIBUILDER will add the box to the end of. For example, `uibuilder.showMsg(true, 'h1')` would attach the box to the end of a heading level 1 element on the page. Don't forget that the box will inherit at least some of the CSS style from the parent, so attaching to an H1 element will make the text much bigger.

This function can also be called from Node-RED via `msg._uib.command` - `showMsg` with `msg._uib.value` set to `true`. Leave the value property off to toggle the display.

Adds/removes `<div id="uib_last_msg">` to/from the page.

### `showStatus(boolean, parent=body)` - Show/hide a card shows the current status of the uibuilder client library :id=showStatus

Simply add `uibuilder.showStatus(true)` early in your index.js custom code and a box will be added to the end of your page that will show all of the important settings in the UIBUILDER client. Use `uibuilder.showStatus()` to toggle the display.

`uibuilder.showStatus(false)` or `uibuilder.showStatus()` will remove the box and stop the updates.

You can also position the box in a different location by specifying a "parent". This is a CSS selector that, if found on the page, UIBUILDER will add the box to the end of. For example, `uibuilder.showStatus(true, 'h1')` would attach the box to the end of a heading level 1 element on the page. Don't forget that the box will inherit at least some of the CSS style from the parent, so attaching to an H1 element will make the text much bigger.

This function can also be called from Node-RED via `msg._uib.command` - `showStatus` optionally with `msg._uib.value` set to `true`. Leave the value property off to toggle the display.

Adds/removes `<div id="uib_status">` to/from the page.

### `syntaxHighlight(json)` - Takes a JavaScript object (or JSON) and outputs as formatted HTML :id=syntaxHighlight

Is used internally by the `showMsg` function but may be useful for custom processing. If used in custom code, make sure to wrap the output in a `<pre>` tag.

Requires some CSS that is contained in both the `uib-brand.css` and older `uib-styles.css`. Feel free to copy to your own CSS if you don't want to reference those files.

Use as:

```javascript
const eMsg = $('#msg')    // or  document.getElementById('msg') if you prefer
if (eMsg) eMsg.innerHTML = uibuilder.syntaxHighlight(msg)
```

### `ui(json)` - Directly manage UI via JSON :id=ui

Takes either an object containing `{_ui: {}}` or simply simple `{}` containing ui instructions. See [Config Driven UI](client-docs/config-driven-ui.md) for details of the required data.

Directly calls `_ui.ui` from the `ui.js` library.

### `uiGet(cssSelector, propName=null)` - Get most useful information, or specific property from a DOM element :id=uiGet

Will return an array of found elements with properties.

If no `propName` supplied, will return a selection of the most useful information about the selected element(s).

Returned data can be sent back to Node-RED using: `uibuilder.send( uibuilder.uiGet('#myelementid') )`.

Where a propName is supplied, if you ask for the `value` attribute - `uibuilder.uiGet("#eltest", "value"}` - if the selected element is an `input` type, the input's value attribute will be returned. But if it is some other kind of element type, the element's inner text will be returned.

Can be called from Node-RED with a message like: `{"_uib: {"command": "uiGet", "prop": "#more"} }`.

Uses `nodeGet` internally.

### `uiWatch(cssSelector, startStop=true/false/'toggle', send=true, showLog=true)` - watches for any changes to the selected HTML elements :id=uiWatch

Uses [Mutation Observer](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/MutationObserver) to watch for and report on any changes to the DOM (the page).

Can send the output to the console log (the `showLog` argument. Shows at log level 2 - Info) and/or back to Node-RED (the `send` argument).

Uses `nodeGet` (the same as `uiGet`) to capture standard information about added/removed nodes.

Sends useful data back to Node-RED automatically. It also triggers a custom event (`uibuilder:domChange`) to allow front-end processing too.

If `startStop` is undefined, null or 'toggle', the watch will be toggled.

Can be called from Node-RED with a message like: `{"_uib: {"command": "uiWatch", "prop": "#more"} }`.


## HTML/DOM Cacheing

### `clearHtmlCache()` - Clears the HTML previously saved to the browser localStorage :id=clearHtmlCache
### `restoreHtmlFromCache()` - Swaps the currently displayed HTML to the version last saved in the browser localStorage :id=restoreHtmlFromCache

### `saveHtmlCache()` - Manually saves the currently displayed HTML to the browser localStorage :id=saveHtmlCache

> [!NOTE]
> Browser local cache is generally limited to 10MB for the whole source domain.
> Therefore, it is quite easy to exceed this - use with caution.

### `watchDom(startStop)` - Start/stop watching for DOM changes. Changes automatically saved to browser localStorage :id=watchDom

`uibuilder.watchDom(true)` will start the browser watching for any changes to the displayed HTML. When it detects a change, it automatically saves the new HTML (the whole page) to the browser's `localStorage`. This persists across browser and device restarts.

You can ensure that the page display looks exactly like the last update upon page load simply by adding `uibuilder.restoreHtmlFromCache()` at the start of your index.js custom code.

> [!note]
> Browser `localStorage` capacity is set by the browser, not UIBUILDER. Very large pages might concevably fill the storage as might other things saved to it.
>
> You should be able to change the capacity in the browser settings but of course, this would have to be done on every client device.


## Event Handling

> [!NOTE]
> You can use one or more of the `msg._uib.pageName`, `msg._uib.clientId`, or `msg._uib.tabId` properties
> to control whether a specific page, client or browser tab will process an inbound message.
> Use this where you have multiple pages or clients and need to target a message to a specific one.

### `onChange(prop, callbackFn)` - Register on-change event listeners for uibuilder tracked properties :id=onChange

Returns a reference to the callback so that it can be cancelled if needed.

Uses the `uibuilder:propertyChanged` event internally.

#### Example

```javascript
const msgChgEvt = uibuilder.onChange('msg', (msg) => {
    // Dump the msg as text to the html element with an id of "msg"
    const eMsg = $('#msg')
    if (eMsg) eMsg.innerHTML = uibuilder.syntaxHighlight(msg)
})
```

### `cancelChange(prop, cbRef)` - remove all the onChange listeners for a given property :id=cancelChange

Both arguments must be provided. With `cbRef` having been saved when the listener was set up.

```javascript
uibuilder.cancelChange('msg', msgChgEvt)
```

### `onTopic(topic, callbackFn)` - like onChange but directly listens for a specific topic :id=onTopic

```javascript
const topicChgEvt = uibuilder.onTopic('my topic', (msg) => {
    // Do something when we get a message from Node-RED
    // with this specific msg.topic
})
```

### `cancelTopic(topic, cbRef)` - like cancelChange for for onTopic :id=cancelTopic

Both arguments must be provided. With `cbRef` having been saved when the listener was set up.

```javascript
uibuilder.cancelTopic('my topic', topicChgEvt)
```

### `watchUrlHash` - Toggle (or manually set on/off) sending URL Hash changes back to Node-RED in a standard msg :id=watchUrlHash

Manually set on/off using the parameter, e.g. `watchUrlHash(true)`. Or toggle by not sending the parameter.

URL Hashes are used by front-end routers for single-page apps (SPAs). Turning on this feature lets you track user "page" changes in SPA's. Don't forget to turn on the optional "Include msg._uib in standard msg output." flag (uibuilder advanced settings) if you need to track changes in multiple browser tabs or users. Which most likely you will want to.

Can also be called as a command from Node-RED via `msg._uib.command` = `watchUrlHash`. The optional `msg._uib.prop` set to true/false will manually turn on/off.

This function uses the `truthy` utility function for the optional parameter and so will accept truthy/falsy entries not just true/false.

### Custom Events

The UIBUILDER library also issues a number of custom events. These can be handled using the standard `document.addEventListener` JavaScript function. See [Custom Events](client-docs/custom-events.md) for details.

## Utility

### `$(cssSelector)` - Simplistic jQuery-like document CSS query selector, returns an HTML Element :id=dollar

This is a convenience method to help you select HTML DOM elements in your own custom code. All it does is use ` document.querySelector(cssSelector)`. So any errors are the same as the native function.

As per the native function, it returns a single [HTML element](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement). If the CSS Selector provided is not unique (e.g. >1 element would be returned), only the first element found in the DOM is returned. Use `document.querySelectorAll(cssSelector)` if you want to get back an array of selected elements.

If the UIBUILDER client finds an existing definition of `$` on startup, it will not make this global. However, it would still be usable as `uibuilder.$(...)`. This avoids clashes with libraries such as jQuery.

If the selector finds a `<template>` tag, it returns its _first child_ instead of the tag. This is to ensure that if you clone it, it will be valid for applying event handlers. A template element is not visible on-page but is used for cloning multiple times or for swapping between different displays (removing the old element and replacing with a new one - not hide/show).

> [!NOTE]
> Worth noting that the Chromium DevTools console also uses the same definition of `$()` that UIBUILDER does. [Reference](https://developer.chrome.com/docs/devtools/console/utilities/#querySelector-function). UIBUILDER's definition supercedes that of the DevTools console however. The devtools version allows a 2nd parameter which UIBUILDER does not.
>
> In addition, UIBUILDER's version gracefully handles the selection of a `<template>` tag where it returns the template's first child rather than the template itself.

#### Example

```javascript
const eMsg = $('#msg')
if (eMsg) eMsg.innerHTML = uibuilder.syntaxHighlight(msg)
```

### `$$(cssSelector)` - Returns an array of HTML elements properties :id=dollar2

This function is a convenience wrapper around `Array.from(document.querySelectorAll(cssSelector))`. So it returns an array. The array has an entry for each found element (an empty array if nothing found). Each entry in the array returns the _properties_ of the found element.

This means that it returns different data to the `$()` function.

This is very similar to the function of the same name in the Chromium DevTools. The only difference being that UIBUILDER's function does not accept a 2nd parameter. UIBUILDER's function supercedes that of the DevTools.

### `arrayIntersect(a1, a2)` - Intersection of two input arrays :id=arrayIntersect

Takes 2 arrays as input and returns a new array, which could be empty, of the intersecting items.

### `connect()` - Manually (re)connect Socket.IO communications between the browser and Node-RED :id=connect

Allows fine control of the communications.

### `disconnect()` - Manually disconnect Socket.IO communications between the browser and Node-RED :id=disconnect

Allows fine control of the communications. Also stops the auto-reconnect timer.

### `formatNumber(value, decimalPlaces, intl, opts)` - Format an input number to a given locale and decimal places :id=formatNumber

Takes numeric input and formats it using the JavaScript standard [`INTL` library](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString).

Allows optional setting of the number of decimal places.

The `intl` argument takes the form like `en-GB`, `de-DE` (German), `ja-JP` (Japanese), etc. If not provided, the function takes the browser's current locale using `navigator.language` so that the number defaults to being formatted in the browser's current locale.

The `opts` argument allows passing INTL number formatting options, for example: `{ style: 'currency', currency: 'JPY' }` to get currency formatted as Japanese Yen.

> [!NOTE]
> This function is compatible with the [`uib-var` web component's `filter` attribute](client-docs/custom-components#filter). e.g. `<uib-var topic="mytopic/#1" filter="uibuilder.formatNumber(2, 'de-DE')">[...]</uib-var>`

### `hasUibRouter` - Returns true if a uibrouter instance is loaded, otherwise returns false :id=hasUibRouter

Note that, because the router will be loaded in a page script, it is not available until AFTER the uibuilder library has loaded and socket.io initialised.

### `log` - output log messages like the library does :id=log

Use as `uibuilder.log(1, 'my:prefix', 'Some text', {some:'optional data'})` which produces:
![Example log output](../images/example-log-output.png)

First argument is the log level (0=Error, 1=Warn, 2=Info, 3=log, 4=debug, 5=trace). If the UIBUILDER logLevel variable is set to less than the requested level, the output will not be shown. The names can be used instead of the numbers.

The first 2 arguments are required. All remaining arguments are included in the output and may include array, objects, etc.

To set the log level to display in your code, use `uibuilder.logLevel = 5` or `uibuilder.logLevel = 'trace'`. Set to your desired level.

Future versions of this function after v6.1 will extend it to output to an on-page visible log and/or log back to Node-RED.

### `makeMeAnObject(thing, property)` - Return a valid object if input is null or a string :id=makeMeAnObject

`property` defaults to "payload" if not supplied. So `uibuilder.makeMeAnObject("mystring")` will output `{payload: "mystring"}`.

### `navigate(url)` - Either show a new route or navigate to a new page :id=navigate

Returns the current URL after navigation (if any).

The URL can be:

1. A full URL (e.g. `https://example.com/somewhere`)
2. A relative URL (e.g. `./anotherpage.html`)
3. A routing hash (e.g. `#route02`)

Or a combination of (1 OR 2) and 3.

#### Relative URLs

Are relative to the CURRENT PAGE. So if that is 
`index.html`, `./page2.html` would be in the same
source folder as would `./folder` (which would move to
`./folder/index.html`).

Similarly, if on the `folder` page, `../` would move up
a level to the main index html page.

#### Routing Hashes

For pure front-end routing, using `uibrouter` or similar
library, simply send `#newroute` to move to the new route
without reloading the page.

Putting a hash on the end of a full or relative URL will
trigger the route on the resulting page load.

### `round(num, decimalPlaces)` - Round a number to a set number of decimal places :id=round

Fast but accurate number rounding (https://stackoverflow.com/a/48764436/1309986 solution 2) using the "half away from zero" method (AKA "commercial" rounding), the most common type.

Inputs must be numbers otherwise an error is generated.

### `truthy(val, [default])` - Returns true or false or the optional default value depending on the value :id=truthy

True accepts 'on', 'On', 'ON', 'true', 'True', 'TRUE', '1', true, 1
False accepts 'off', 'Off', 'OFF', 'false', 'False', 'FALSE', '0', false, 0

If neither truthy or falsy, the optional default value is returned or `undefined` if that parameter is not supplied.

### `urlJoin(...)` - Join all arguments together as a valid URL path string :id=urlJoin

Removes leading/trailing `/` characters from each argument and then joins them with `/`. The result starts with a `/` but does not have one on the end.

Examples: `uibuilder.urlJoin('/aaa/', '//bbbb/ccc/')` -> `/aaa/bbbb/ccc`, `uibuilder.urlJoin('aaa', 'bbbb')` -> `/aaa/bbbb`.

## Startup

### `start(options)` - Mostly no longer needed - Starts Socket.IO communications with Node-RED :id=start

> [!NOTE]
> In most cases, you no longer need to call this yourself. The client startup is now more robust and should rarely need any help. The exception will be if you are loading a page from an external server instead of from Node-RED.
>
> Use the `uibuilder.showStatus()` function to display the status of the client library on-page. This can show when the start function has failed and show what you need to change.

Unlike the original UIBUILDER client, this version:

* Rarely needs to be manually called. It should work for all page locations including in sub-folders as long as the client allows cookies.

* Only allows passing of a single options object.

* Allows being called again which will reset the Socket.IO connection and internal msg event handlers.

#### Options

While multiple properties can be given in the options object, only the following are currently used:

* `ioNamespace` - This is normally calculated for you. However, if using an external server to serve the page, you may need to manually set this. Check the UIBUILDER node details page in the Node-RED Editor for what this should be set to.
* `ioPath` - As above.
* `nopolling` - If set, will turn off Socket.IO's HTTP long-polling transport. Forcing it to only use websockets.

## Alphabetical function list

Those marked with `*` can be triggered with a command message from Node-RED flows. Those marked with `§` are low-code _ui functions and so can be triggered from Node-RED using messages containing [suitable `_ui` properties](client-docs/config-driven-ui).

If examining the library code, please remember that functions starting with `_` are for *internal* use.

### `uibuilder` functions :id=uibuilder-fns

Available in front-end JavaScript as `uibuilder.xxxxx` or `uib.xxxxx`.

* [`$`](#dollar) - Alias of `document.querySelect`.
* [`$$`](#dollar2) - Alias of `document.querySelectAll`.
* `$ui`§ - Reference to the ui.js library, not a function.
* [`addClass`](#addClass)§ - Adds a class name to an HTML element.
* [`applyTemplate`](#applyTemplate)§ - Applies `<template>` tag contents as appended children of the target.
* [`arrayIntersect`](#arrayIntersect) - Return new array of the intersection of the 2 input arrays.
* [`beaconLog`](#beaconLog)
* [`buildHtmlTable`](#buildHtmlTable) - Create an HTML table from an array/object input.
* [`cancelChange`](#cancelChange) - Cancel a managed variable event watcher.
* [`cancelTopic`](#cancelTopic) - Cancel a topic event watcher.
* [`clearHtmlCache`](#clearHtmlCache)
* [`connect()`]() - Manually (re)connect Socket.IO communications between the browser and Node-RED.
* [`convertMarkdown`](#convertMarkdown) - Convert a Markdown string to HTML.
* [`copyToClipboard`](#copyToClipboard)
* [`elementExists`](#elementExists)*
* ~~[`elementIsVisible`](#elementIsVisible)~~ - Temporarily deprecated.
* [`eventSend`](#eventSend) - Returns standardised data to Node-RED. For form inputs or other events.
* [`formatNumber`](#formatNumber) - Outputs a number as a formatted string.
* [`get`](#get)* - Return the value of a managed variable.
* [`getElementAttributes`](#getElementAttributes) - Return object containing attribute-name/value keypairs (or an empty object).
* [`getElementClasses`](#getElementClasses) - Checks for CSS Classes and return as array if found or undefined if not.
* [`getElementCustomProps`](#getElementCustomProps) - Return object containing an elements custom property/value pairs.
* [`getFormElementDetails`](#getFormElementDetails) - Return object containing the key properties of a form element.
* [`getFormElementValue`](#getFormElementValue) - Check for el.value and el.checked, return as an object.
* [`getManagedVarList`](#getManagedVarList)* - Returns list of all managed variables.
* [`getPageMeta`](#getPageMeta) - Asks the server for the created/update timestamps and size (in bytes) of the current page.
* [`getStore`](#getStore)
* [`getWatchedVars`](#getWatchedVars)* - Returns list of all managed variables.
* [`hasUibRouter`](#hasUibRouter)
* [`htmlSend`](#htmlSend)* - Sends the current page's full HTML back to Node-RED.
* [`include`](#include)*
* [`joinRoom(room)`](#joinRoom) - join an arbitrary socket.io room to receive messages from it.
* [`keepHashFromUrl`](#keepHashFromUrl)
* [`leaveRoom(room)`](#leaveRoom) - leave an arbitrary socket.io room to stop receiving messages from it.
* [`loadScriptSrc`](#load)§
* [`loadScriptTxt`](#load)§
* [`loadStyleSrc`](#load)§
* [`loadStyleTxt`](#load)§
* [`loadui`](#loadui)§
* [`log`](#log)
* [`logToServer`](#logToServer)
* [`makeMeAnObject`](#makeMeAnObject) - Returns the input as an object.
* [`navigate`](#navigate)* - Forces the browser to change URL.
* [`notify`](#notify)
* [`onChange`](#onChange)
* [`onTopic`](#onTopic)
* [`removeClass`](#removeClass)§
* [`removeStore`](#removeStore)
* [`replaceSlot`](#replaceSlot)§
* [`replaceSlotMarkdown`](#replaceSlotMarkdown)§
* [`restoreHtmlFromCache`](#restoreHtmlFromCache)
* [`returnElementId`](#returnElementId) - Return elements existing ID or, add a new unique id to the element and return it.
* [`round`](#round) - Rounds the input number to a given set of decimal places.
* [`sanitiseHTML`](#sanitiseHTML) - Ensures that the input HTML is safe.
* [`saveHtmlCache`](#savehtmlcache)
* [`scrollTo`](#scrollTo)*
* [`send`](#send) - Sends a custom message back to Node-RED.
* [`sendCtrl`](#sendCtrl) - Sends a control message back to Node-RED.
* [`sendCustom`](#sendcustom) - Sends a message to a specified Socket.IO channel.
* [`sendRoom(room, msg)`](#sendRoom) - Send a message to an arbitrary socket.io room.
* [`set`](#set)* - Create/update a uibuilder managed variable.
* [`setOriginator`](#setOriginator)
* [`setPing`](#setPing)
* [`setStore`](#setStore)
* [`showDialog`](#showDialog)
* [`showMsg`](#showMsg)*
* [`showStatus`](#showStatus)*
* [`start`](#start)
* [`syntaxHighlight`](#syntaxHighlight)
* [`truthy`](#truthy)
* [`ui`](#ui)
* [`uiEnhanceElement`](#uiEnhanceElement)
* [`uiGet`](#uiGet)*
* [`uiWatch`](#uiWatch)*
* ['uploadFile'](#uploadFile)
* [`urlJoin`](#urlJoin) - Join arguments as a valid URL path string.
* [`watchDom`](#watchDom)
* [`watchUrlHash`](#watchUrlHash)*

### Global (`window`) functions :id=global-fns

These are attached to the `window` (AKA `globalThis`) object if they can be.

They will not be attached if there is a name clash to avoid issues with other libraries. The `$` and `$$` definitions in particular are widely used by other libraries and frameworks, this will generally not cause any issues since their use should be the same (jQuery use is slightly different but should generally still work). `$ui` is not likely to be used by another library but if it is, this may be slightly more problematic - however, it is rare that you will use this directly anyway.

* [`$`](#dollar) - Alias of `document.querySelect`
* [`$$`](#dollar2) - Alias of `document.querySelectAll`
* `$ui`§ - Reference to the ui.js library, not a function.
* `on` - Alias of `window.addEventListener`
* `uib` - Alias of `uibuilder`.
* `uibuilder` - the loaded instance of the client library.

### Extended HTML `Element` class methods :id=element-class-methods

These are added to the prototype of the [`Element` built-in HTML class](https://developer.mozilla.org/en-US/docs/Web/API/Element). This enables them to be used in any case that returns an HTML object based on the `Element` class. For example, the `$(cssSelector)` function will return something useful such that `$('#custom-drag').on('wheel', (e) => console.log('wheel', e))` will add an event listener to the HTML element with an id of `custom-drag`. `$$(cssSelector)` will return an array of elements.

> [!TIP]
> SVG's and MathML elements also inherit from this class and so these utility functions will work on them as well.

As with the global functions, these are only attached if they don't already exist. Some other libraries or frameworks might also define them which should not be an issue as it is anticipated they will behave in the same way.

* `on` - Alias of `<element>.addEventListener`. [[Reference](https://developer.mozilla.org/en-US/docs/Web/API/element#events)]
* `query` - Alias of `<element>.querySelect`
* `queryAll` - Alias of `<element>.querySelectAll`

### Extended HTML `document` object methods :id=html-document-methods

* `on` - Alias of `document.addEventListener`
