Releases: TotallyInformation/node-red-contrib-uibuilder
<uib-var> and router improvements and more
📌 Highlights
-
The
<uib-var>
HTML component gets-
This is BIG! - A
topic
attribute (use instead of thevariable
attribute) that automatically watches for messages from Node-RED matching the topic and outputs the payload onto the page. This becomes the easiest way to automatically update the page! It is similar to mustache tags ({{varname}}
) in frameworks but has the advantage that it is 100% vanilla standard HTML. -
A
filter
attribute that can be used along-sidevariable
ortopic
or on its own. The attribute receives the name of a function to run whenever the source data changes. Use for formatting output. A new functionuibuilder.formatNumber
has been added that is compatible, it outputs a formatted version of an input number according to the locale and number of decimal places specified.<uib-var topic="mytopic" filter="uibuilder.formatNumber(2, 'de-DE')">[...]</uib-var>
. You can, of course, create your own filter functions. -
Access to your
./index.css
style sheet file. This lets output be styled like the rest of your page.
-
-
The
uibrouter
library gets some serious updates in this version. Including:- Automatic menu updates (to highlight the current route). Just make sure to use list items (li) for menu items and give them a
data-route="routerid"
attribute (whererouteid
is the actual route id). ThecurrentRoute
class &aria-current="page"
attribute are both added to entries matching the current route. - Route definitions now support
title
&description
properties. - New uibuilder variables to use with
<uib-var>
to show titles and descriptions that update automatically. - A fix for a missing default route - the first defined route is used in this case.
- Other small bug fixes and improvements to the logic.
- Automatic menu updates (to highlight the current route). Just make sure to use list items (li) for menu items and give them a
-
The client library gets
- Connected to a new "global" socket.io "room" allowing uibuilder connected pages to talk to each other. Note that this is still very basic, only the receiver is in place as yet. There is no function to do a global send.
- New functions
joinRoom(room)
,leaveRoom(room)
,sendRoom(room, msg)
- to interact with arbitrary communication "rooms". Not fully working yet but will eventually allow any uibuilder connect node or client to communicate with 1 or many other connected nodes/clients. - A new
navigate
function and command. Triggers a page change or a route change either from front-end JavaScript or via a command message in Node-RED. Put a client into Kiosk mode and rotate pages or route displays all from Node-RED! - A new
scrollTo
function and command. Scrolls the visible page to a specific location either from front-end JavaScript or via a command message in Node-RED. - New UI functions
addClass(classNames, el)
andremoveClass(classNames, el)
to make class handling easier. - New
connect()
anddisconnect()
functions to manually connect/disconnect the Socket.IO connections.
-
The importable example flows have been re-organised for easier access. Some new examples added: "Text Update - Different Methods", "FE Router Test"
-
No-code and low-code features now all allow more flexible class handling (add, remove, and replace using lists). HTML element data outputs also now return an array of class names, not just a combined string.
-
Front-end commands issued from Node-RED can now take a
quiet
option set totrue
to prevent the return message. e.g.{"_uib": {"command":"navigate","prop":"#newroute","quiet":true}}
-
Front-end developers now have full access to the
ui.js
library via the$ui
global.
uibuilder
node
- FIXED Previously, if an editor deployed a uibuilder node with an invalid URL, the node configuration & setup still happened which lead to odd results. Now a missing or invalid URL results in a logged error and the node is not configured. ref
uib-cache
node
- FIXED - bug introduced by last version's correction of
connections
count meant that "Only replay cache when client is really new" option resulted in the cache never being sent. - Re-worked node's html into latest format with JS in separate resources file.
uib-html
node
- Downgrade
jsdom
version to 21.* as that is the last version that supports Node.js v14.
uib-save
node
- FIXED - usePageName logic.
- FIXED - import - initial deployment does not connect to node - need to clear the entry & mark as invalid. Also, no url = invalid
- URL (uibuilder instance) drop-down list is now sorted
- On copy/paste or import, link to uibuilder node is now cleared.
uib-tag
node
- FIXED - Allow blanks in some typed input fields.
uib-update
node
- FIXED - Allow blanks in some typed input fields.
Client library
-
FIXES
- Some reported client data was incorrect. Notably the
connections
, andlastNavType
properties. Theconnections
property has now been corrected. ThelastNavType
, I now realise will never be correctly updated by the client and therefore it has been removed. Fixing these has also resulted in some simplification of the client code.
- Some reported client data was incorrect. Notably the
-
NEW -
$ui
is a new global created by the library which gives full access to theui.js
library, that library presents an instance of theUi
class. So typing$ui.version
in the browser dev console will return the current version of the ui library. Also available asuibuilder.$ui
just in case$ui
was already taken when the uibuilder library is loaded. -
NEW managed variable
globalMsg
- contains the last message received over the global socket. The global socket allows uibuilder connected pages to talk to each other. -
NEW Functions that have Node-RED remote commands
-
navigate(url)
- Load a new web page or change routes. Can be triggered from Node-RED with msg{"_uib": {"command":"navigate","prop":"#newroute"}}
. See Client Functions (navigate) in the docs for details. URL's can be full, relative (to the current page) or routing (hashes). Obviously, can be called in front-end JavaScript as well asuibuilder.navigate('./page2.html')
etc. -
scrollTo(cssSelector)
- Scroll visible page to an element based on a CSS Selector. See Client Functions (scrollTo) in the docs for details.top
,start
,bottom
,end
can be used as shortcuts for the top/bottom of the page. An optional 2nd parameter gives more control.
-
-
NEW Functions (without Node-RED remote commands)
-
connect()
,disconnect()
- These manually connect and disconnect the Socket.IO communications between the browser and Node-RED. -
formatNumber(value, decimalPlaces, intl, opts)
- Compatible with the<uib-var>
component'sfilter
attribute. Uses the JavaScript standard INTL library to allow locale-based formatting. -
keepHashFromUrl()
- Returns the route id from the URL. -
joinRoom(room)
,leaveRoom(room)
,sendRoom(room, msg)
- allows clients to join/leave/message any arbitrary room
-
-
NEW ui functions -
addClass(classNames, el)
,removeClass(classNames, el)
- seeui.js
below for details. -
NEW - the client has some early code for dealing with Socket.IO "rooms". These are really a SIO server function but some methods updated to take them into account.
-
NEW - the client now subscribes to a new "global" socket.io channel. This allows clients to talk to each other
-
Added
quiet
property to remote command processing. Setmsg._uib.quiet
totrue
to stop the library returning a message to Node-RED on completion of the command. -
When using
uiGet
ornodeGet
functions/commands, if class attribute is present, an additionalclasses
property is returned which is an array of the class names. -
Moved
$
and$$
functions toui.js
library. This library references them. So no change to usage. -
DEPRECATED Function -
elementIsVisible
- Was not working correctly and a fix is complex. Will revisit in the future. Let me know if you need this function. This would normally be a breaking change but the function is still there - it returns a console msg and a node-red msg still - and as it wasn't working, I doubt anyone has used it.
uibrouter
library
- FIXED Issue #232 - Ensure origin script is removed after re-applying to ensure only 1 instance shows instead of 2.
- FIXED - If no routerConfig.defaultRoute set, now uses the first (zeroth) defined route.
- Version bumped to v1.0.1
- NEW - Route definitions now support
title
&description
properties. - NEW uibuilder managed variables added to make it easier to use with
<uib-var>
. [uibrouter_CurrentRoute
,uibrouter_CurrentTitle
,uibrouter_CurrentDescription
,uibrouter_CurrentDetails
]. These are automatically updated whenever a route change occurs. - NEW -
routeIds
variable is a JavaScriptSet
containing the list of unique route IDs. - NEW Functions -
routeTitle
,routeDescription
- return the current route's title and description properties if set or the ID if not. - NEW Function -
currentRoute
- returns the current routes configuration object. - NEW Function -
setCurrentMenuItems
- Updates any on-page elements matching the selectorli[data-route]
such that any having a data-route attribute matching the current route id have thecurrentRoute
class &aria-current="page"
attribute added. It is removed from all other matches. This makes it very easy to highlight the current route in any on-page menu's.
uib-var
custom web component
- NEW: Added
topic
attribute - auto-monitors for messages from Node-RED with the given topic.msg.payload
...
Feature release: New front-end router. Improved uib-html, uib-save and much more
UPDATE 2023-12-29: Totally forgot to document the new custom web component built into UIBUILDER! The <uib-var>
tag provides an easy way to get dynamically updated content into your web page. See the examples library and the documentation for more details. In this release, allows the specifying of a managed uibuilder variable which will be inserted into the page and automatically updated whenever the variable updates. This is similar to mustache tags in many front-end frameworks ({{myvar}}
) but, unlike those frameworks, is totally vanilla, standards-based. Expect further improvements in future releases.
Highlights
- The new front-end routing library is available. Easy to use, robust and reasonably comprehensive. It is not dependent on uibuilder but offered with it to enable Single-Page Apps (SPA's) to be easily created with uibuilder.
- The
uib-html
node now allows an HTML string wrapper. This defaults to uibuilder's default "Blank" template HTML or can be overridden usingmsg.template
. This lets you create a fully working page from no-code and low-code configurations that can be fed direct touib-save
or used in Dashboard or with http-in/-out nodes. Or indeed with external web server tools.
New client library - uibrouter - front-end routing library
A complete, standalone library for doing front-end routing with both internal and external templates. Lightweight and simple to use. See the documentation for details.
uib-html
improvements
-
The
uib-html
node now accepts amsg.template
property which, if provided, MUST contain a valid HTML page template.This allows you to grab an existing page using the
htmlSend
command, add new elements/updates and save it back to a uibuilder instance either as the default page or another page, for example, using theuib-save
node. Overwriting a page is a way of ensuring that new accesses get a known page with structure and potentially data.You can, of course, use this node to produce HTML for use outside of UIBUILDER. For example, use uib-element/uib-update, add a template and use this node to create a complete web page for use with http-in/-out, a static website or some other web service.
You probably don't need/want the template if outputting for the Node-RED Dashboard
ui_template
node.
uib-save
improvements
- The reload client flag now actually works.
- The new "Use pageName" flag allows you to save to the uibuilder node's live folder using the page name returned from the front-end or manually set in
msg._ui.pageName
ormsg.uib.pageName
. This makes it easier to save an updated page via thehtmlSend
command (either from Node-RED or from front-end code). See the example flow to see how this works. It means that you don't need to know the folder or the pageName at all. - The filename can include folders (use
/
as separator) and missing folders will be created automatically if the "Create Folder" flag is set. Note that you cannot have any..
in the filename, this is to prevent escaping from the instance root folder and causing mayhem elsewhere. By default, new folders cannot be created (this is a safety feature), select the "Create Folder?" flag to allow creation. - The Editor js has been moved out of the html file and put into
resources/uib-save.js
. It is loaded by the html file in a link. This makes development a lot easier. The code also referencesresources/ti-common.js
to ensure consistency.
uib-tag
improvements
- FIXED - Tag name input would only accept string. Now correctly processes other types.
Client library improvements
- FIXED Client
htmlSend
, when called as a Node-RED command, was returning 2 messages. Now returns the HTML string and sends it to Node-RED directly only if the new 2nd argument is TRUE (the default so that direct calls will still work without changes). - FIXED
eventSend
when attached to a change event returns thevalue
property that allinput
tags have - except when they don't! When input is used as a checkbox, it has achecked
property instead. Function changed to return the checked value if it exists (true
orfalse
), the value property otherwise. - NEW function and command
watchUrlHash
- Toggle (or manually set on/off) sending URL Hash changes back to Node-RED in a standard msg. - NEW watched variable
urlHash
Set on load and updated as it changes. URL Hashes are used by front-end routing for Single-Page-Apps (SPA's). They do not reload the page. - New utility function
truthy
Takes a truthy/falsy input (e.g. text, number, boolean) and returns true or false (boolean). If input is neither truthy or falsy, can take a 2nd parameter which is the default return. - Function added to watch for url hash changes.
uibuilder
node improvements
uibuilder
- Reduce code complexity by moving more fs actions out intolibs/fs.js
.- Some common Node-RED Editor code and styles moved to common libraries (
resources/ti-common.js
&resources/ti-common.css
) loaded as resources. Making the editor code smaller and more consistent.
Editor panel improvements
- Major rework of tracking node instances. Custom events are now fired: 'uibuilder:node-added', 'uibuilder:node-changed', 'uibuilder:node-deleted'. With the node in question passed as data in the event. For added nodes, an extra property
addType
is added to the node object and set to either "load" (fired when the Editor is loaded which adds all nodes), "new" (when a brand new instance is added, eg from the palette), or "paste/import". The tracking code is also now only ever instanciated once when the Editor is loaded. - Better and more consistent removal of URL setting when pasting or importing existing uibuilder nodes.
- The Editor js has been moved out of the html file and put into
resources/uibuilder.js
. It is loaded by the html file in a link. This makes development a lot easier. The code also referencesresources/ti-common.js
to ensure consistency. - Improved debug information. Debug output to Editor page console is automatic if environment variable NODE_ENV is set to 'dev' or 'development' (it used to be if running on localhost). Otherwise can be turned on by manually issueing
uibuilder.debug = true
on the browser console on the Editor page.
Examples
uib-save
anduib-html
example flows added.uib-var-web-component
example flow added. Contains several examples of showing uibuilder managed variables dynamically in your HTML code. Including several no-code examples.uib-tag
example flow added.
Other improvements
- NEW node Library
libs/lowcode.js
- The beginnings of moving the zero- to low-code element translations (e.g. uib-element, uib-update and uib-tag) to their own library. With the possibility of eventually making that library available as a stand-alone front-end library as well. Not yet in use. libs/fs.js
- More replacements towards removing dependency on fs-extra. More move of filing system actions out of other nodes and libraries.- NEW utility function
getSource(propName, node, msg, RED, src, srcType)
inlibs/uiblib.js
- this is an ASYNC function that returns a promise. It is a standardised way of getting the current value from a Node-RED Typed Input field. - Enhanced tooltips not applied to the Monaco/Ace edit panel.
Feature Release & Bug Fixes
Apologies, the documentation has fallen a little behind with this release as things took longer and more new features were added than expected. But I needed to get this release out as it contains some important bug fixes as well.
NEW Features
-
New zero-code node
uib-tag
- creates a single html element based on the given tag name (e.g. create a link element from ana
tag). Also works with web component custom tags. Use this when you want to add something not covered byuib-element
. Lets you specify slot content (html or Markdown) and attributes at the same time. -
The client library now filters inbound messages according to
pageName
,clientId
, and/ortabId
set in eithermsg._uib
ormsg._ui
. -
There is a new, dynamic page at
../uibuilder/apps
that lists (with links) all uibuilder instance endpoints. Currently only a very simple list but the plan is to add an instance title and description field to uibuilder which would then be populated into this page. Use as an index of all of your main web pages (strictly, this is a list of all of the uibuilder-driven web apps. Apps may have multiple pages of course). -
The uibuilder client connection control msg now reports the URL parameters (AKA search parameters) for the connection from the client. This is another way of passing data from a client to the server. Obviously, you should never trust user input - always limit, check and validate user input.
-
uib-element
now allows the core data for the element to be defined in the node or on a context variable and other locations, you are no longer forced to usemsg.payload
. It also now allows the incomingmsg.payload
to be sent to the client to allow for local processing if required. -
uibuilder Instance routes/middleware
You can now add ExpressJS routes and other middleware to a single instance of uibuilder (a specific uibuilder node), not just to all nodes. Especially useful if you want to add custom security (login, registration, etc) to just one instance.
The new feature lets you specify the sub-url-path, the HTTP method and the callback function. Paths can include wildcards and parameters too. The routes are always added to the instance router which forces them to only ever be sub-url-paths of the specified instance. e.g. if your instance url is
test
, a route with a path of/foo/:bah
will ALWAYS be.../test/foo/...
. This is for security. Note that you are responsible for creating unique URL paths, no checking is done and ExpressJS is quite happy to have multiple path handlers but if you provide a terminating response (e.g.res.status(200)
) and nonext()
call, the call stack is obviously terminated. If you include a call tonext()
, overlapping route callbacks will also be triggered. In that case, make sure you do not do any moreres.xxxx()
responses otherwise you will get anERR_HTTP_HEADERS_SENT
error.To add route handlers, create 1 or more .js files in the
<instanceRoot>/routes/
folder. See the docs for details.What can I do? Authentication, authorisation, http headers, dynamic html changes/additions, js inserts, logging, server-side includes, server-side rendering (e.g. Jade, ...) ...
NEW NODE: uib-tag
- New zero-code node
- Creates a single html element based on the given tag name (e.g. create a link element from an
a
tag). - Works with web component custom tags.
- Lets you specify slot content (html or Markdown) and attributes at the same time.
- Filters out
msg._ui
from input if it includesmsg._ui.from
set to "client". We don't want to loop from output to input. ref
Use this when you want to add something not covered by uib-element
.
Changes to uibuilder client Library
-
FIX Change warn msg "[Ui:_uiManager] No method defined for msg._ui[0]. Ignoring" to an error so it is more visible.
-
FIX Issue #213 - SVG flow example not working
_uiComposeComponent is not a function at htmlClone index.js:52:15
Caused by the move of all ui fns to a separate class. So
_uiComposeComponent
is no longer accessible. It should not have been used in the example anyway since anything starting with an underscore should be for internal use only. My bad.`uibuilder.uiEnhanceElement(el, component)`` added. Example will be updated again once this is released
-
NEW FUNCTION
uibuilder.notify(config)
- If possible (not all browsers yet fully support it), use the browser Notification API to show an operating system notification. Supports a simple click reponse which can be used withuibuilder.eventSend
to notify Node-RED that a user clicked the notification. Note that there are significant inconsistencies in how/whether this API is handled by browsers. It may not always work. -
No longer processes input messages if either
msg._uib
ormsg._ui
includes eitherpageName
,clientId
, and/ortabId
and where those parameters do not match the current page or client. -
Improvements and corrections to the
eventSend
function. Allowing more event types to be sensible handled (including the Notify response). Also added CSS class information & specific outputs for notifications. Also, added input field types to form outputs. -
Added
window.uib
as a synonym ofwindow.uibuilder
. So you can do things likeuib.logLevel = 5
instead ofuibuilder.logLevel = 5
-
Added flag to indicate if the DOMPurify library is loaded. Added warnings to the
include()
function when it is loaded since some includes will be filtered by the purify process for safety. Updated the front-end client introduction document with details about DOMPurify, how to load it and use it. -
Added flag to indicate if the Markdown-IT library is loaded. Updated the front-end client introduction document with details about how to load the library and use it.
-
Trigger onChange when
msg.payload
received along withmsg._ui
. Previous update turned this off completely but that is too restrictive. Use the Passthrough option inuib-element
for example so that data can be further processed in the front-end if required. -
When the client sends a msg back to Node-RED that includes
msg._ui
properties, the client addsmsg._ui.from
set to "client". This lets theuib-element
,uib-update
, anduib-tag
nodes filter them out when flow editors have looped an output msg back to the input. ref
Changes to uibuilder main node
-
NEW Instance route/middleware handlers - allows you to create custom url routes and custom middleware functions that only impact routes for a single instance of uibuilder.
-
NEW Deep object find function added as
RED.util.uib.deepObjFind
so that it can be used in function nodes. Useful for manipulatingmsg._ui
objects which can get very deep. See Manipulatingmsg._ui
for details. -
NEW A dynamically generated list of all uibuilder apps is now available at
../uibuilder/apps
. In addition, title and description fields have been added to the Advanced tab in the uibuilder node. These are used on the apps page. You can also output the detailed list in Node-RED using a function node withRED.util.uib.listAllApps()
. The detailed list also shows what node defines the app. -
Filter out
msg._ui
from input if it includesmsg._ui.from
set to "client". We don't want to loop from output to input. ref
Changes to uib-element node
-
FIX Was issuing a
node.warn
showing the input type (happening on v6.1 as well) - only for table type. Now removed. -
FIX Chaining to a page title deleted the previous chain - putting title first was ok. Now works either way.
-
FIX Form checkbox "value" output from auto-send was always "on". Because HTML is sometimes utterly stupid! Input tags of type "checkbox" do not set a value like other inputs! They only set the "checked" attribute. Fixed by forcing the value attribute to be set. Issue #221, Discussion #219.
-
KEY CHANGE Added option to select core data input other than msg.payload.
This means that you can define the UI element directly in the node if you want. This includes the use of JSONata for dynamically defined elements, allowing for even simpler msg inputs should this be desired.
-
KEY CHANGE Added an option to pass through msg.payload. When sent to the front-end, the client library will trigger standard events to allow further processing of the data in the front-end.
This means that you can use
uibuilder.onChange
etc in the front-end even though the msg containsmsg._ui
which would normally prevent this from happening. -
Order of node properties changed in the Editor. Hopefully more logical.
-
Filter out
msg._ui
from input if it includesmsg._ui.from
set to "client". We don't want to loop from output to input. ref -
Form additions:
- Textarea input.
- Select options drop-down input.
Changes to the uib-update node
- Filter out
msg._ui
from input if it includesmsg._ui.from
set to "client". We don't want to loop from output to input. ref
Changes to CSS styles (uib-br...
Bug fix
BUG FIX uib-element
When creating a form, if a heading was specified, the form inputs went into the heading instead of the form.
More bug fixes and some new features
Highlights
- Client is now able to generate
xlink:href
correctly when creating SVG's viamsg._ui
low-code UI generator. - The
uiGet
client function and matchingmsg._uib
command provides extending info for tables, and lists. The inner text content of an element can be explicitly requested. - A new client function
$$(cssSelector)
is added that returns the configuration of all matching elements. There is also a new help page that explains what CSS Selectors are and gives some common examples. - The main uibuilder node now uses the extended recovery features of Socket.IO v4.6.
- The Editor panel for the uibuilder code now provides a link to VSCode if running on localhost so that editing front-end code is even easier.
Front-end client library
-
A received msg containing a
msg._ui
property no longer triggersonChange
oronTopic
event handlers. -
_ui
handling moved to a separate utility libraryui.js
to allow use elsewhere. Currently configured as a CommonJS style module which allows use in front-end code via esbuild or in Node-RED (though another library will be needed to provide direct DOM support). -
ui.js
-
New class library containing the uibuilder _ui processing so that it can be used in the future for processing in Node-RED as well.
Exports the Ui class. Must be used as:
const _ui = new Ui(log, syntaxHighlight)
log
is a logging function that, returns a function that actually logs (so it has to be called aslog(...)()
). This is normally a wrapper around console so that the correct calling location (taking into account maps) is reported.syntaxHighlight
is a function that returns returns an HTML string representing a highlighted version of the JSON input.Both of those input functions are available in the uibuilder client library. If using separately, those functions will need to be reproduced.
As the library uses
module.exports
, it must currently be built into a working script usingesbuild
or it can be imported into another script that is run through esbuild. -
Additional safety checks added to ensure browser native API's present (
document
,fetch
, etc.). -
Class constructor takes a
log
function as an argument, this is required. The log function is assumed to be the same as the one in the main library (which requires calling aslog(...)()
to ensure that the correct calling line is reported.) -
Fixed handling of
xlink
SVG attributes. Allows the use of<use>
and other tags withxlink:href
attributes. -
Auto-add correct namespaces to an
svg
tag (xmlns
andxmlns:xlink
) so that you don't have to remember. 😉 -
Improved
htmlSend
. Now includes doctype and outer html tags.msg.length
also added to allow checking that the payload wasn't truncated by a Socket.IO limit. -
A custom event is no longer fired for each method invoked in a
msg._ui
. Very unlikely anyone ever found that useful and it simplifies the code. SoonChange
andonTopic
event handler's are not called.
-
-
For
uiGet
function:- Added number of list/table rows where appropriate.
- Corrected the single attribute code.
- Extended single attribute get such that:
- If the property requested is either an element attribute OR an element property, a key/value pair will be returned.
- If the property requested is "value" and the selected element is not an input element, the element's inner text will be retured instead.
-
Extended the
uiGet
_uib command to allow getting a specific property. e.g. send a msg like:{ "_uib": {"command":"uiGet","prop":"#eltest", "value": "class"} }
to get the classes applied.
uibuilder
node
-
Added ability to limit _ui/_uib commands to a specific pageName/clientId/tabId. Simply add a property of the matching name and the commands will be ignored on any browser page not matching. You can use 1 or more of the properties, all will be checked. You can, of course still use
msg._socketId
, if present, the msg being sent is only sent to the single browser tab matching that socket.io id. -
Socket.IO v4.6 connection state recovery added - Allows a client to recover from a temporary disconnection (up to 2 minutes).
msg.recovered
added to the connection control msg. Is set to true if the client connection is a recovery.This change should reduce the number of times that a client's
_socketId
property changes value. Note that the socket id will always change if the user reloads the page.It also ensures that packets sent from the server while the connection was broken will be sent to the client after reconnection.
-
Socket.IO v4.6 disconnect description added - Adds more details about the disconnection reason to the disconnect control message.
-
When running Node-RED on localhost, the editor panel automatically turns on debug output. This used to be the case previously but the lookup to determine whether running locally was not comprehensive enough, now fixed.
-
Added links to open the instance's front-end code folder in a new VSCode window. They only appear if running Node-RED on localhost. A button is added to the top of the config panel and to the Core tab where the folder name is shown.
-
Added
$$(cssSelector)
function. This matches the function of the same name available in the Chromium DevTools console. It returns ALL elements that match the selector (unlike$(cssSelector)
which only returns the first). In addition, whereas$(cssSelector)
returns the DOM element (like jQuery),$$(cssSelector)
returns an array of the properties of each element.
uib-element
node
- Bug-fix - msg.payload is normally an instance of Object if created as an array or object via JSON/JSONata inputs from inject and change nodes. However, it turns out that is NOT the case if created in a function node. Corrected to a more robust detection method. Thanks to Rami Yeger for spotting the bug and reporting via YouTube comments.
Documentation
- Added new how-to explaining CSS Selectors and giving common examples.
- Updated for the new
$$(cssSelector)
function.
Small bug fixes
Front-end library
- BUG FIX for Issue #207 -
eventSend
function failing when in a form and when using Svelte.
uib-element
- Bug Fix: Adjust selector for type "Page Title" to avoid accidentally updating
<title>
tags in SVG's.
Documentation
- Renamed
_sidebar.md
to-sidebar.md
to stop npm publish from dropping it.
Dynamic creation of SVG
There is really only 1 new feature in this release but it is incredibly powerful! 🧙♂️
You can now use the uibuilder low-code dynamic configuration data to create SVG elements as well as HTML! This means that you could, for example, easily create an SVG-based gauge dynamically.
Client library changes
_ui
handling extended to support dynamic creation of SVG images.- Changed
_uiUpdate()
to use_uiComposeComponent()
for consistency & code reduction.
uib-brand.css
- Adjusted img, picture, video, canvas, svg background colours to match the html background colour
--surface2
.
Examples
- zero-code: Minor correction to form example (1st input had changed id)
Minor features and bug fixes
General
locales
folder withen-US
subfolder. Ready for l8n.
Client library changes
-
Bug Fix: Issue #201 - Incorrect logic in stylesheet load causing an error. Fixed.
-
New functions - can be run from Node-RED as well as front-end code:
htmlSend()
- sends the current web page back to Node-RED.uiWatch(cssSelector, startStop=true/false/'toggle', send=true, showLog=true)
- watches for any changes to the selected page elements and usesuiGet
to send useful data back to Node-RED automatically. It should also trigger a custom event to allow front-end processing too. IfstartStop
is undefined, null or 'toggle', the watch will be toggled.include(url, uiOptions)
- include external files. Includes HTML, Images, Video, PDF's and more.
-
New internal functions:
nodeGet(domNode)
- gets standard data from a DOM node (used internally by uiGet and uiWatch for consistency).
-
Updated functions:
uiGet
- now usesnodeGet
for consistency withuiWatch
.$
- now returns first child if selector returns a<template>
tag. Warn/Error logging added.
uib-element
node changes
- Bug Fix: Updating the page title (with no html id set) was setting the mode to "add" which upset chained outputs. Now corrected.
- "Form" type - improvements:
- Where
required
property is true in the input, addclass="required"
to the div that wraps the label and input. Adddiv.required label::after
styling touib-brand.css
. This will add an "*" after the label text for required inputs. See theuib-brand.css
updates for more formatting improvements. - Allow
title
property to be set in input data. Also add "Required. " to start of title. If no title property specified, make itType: ${type}
. - If no button included in the input data, add default send and reset buttons with an id of
${elementId}-btn-send
&${elementId}-btn-reset
. The Send button uses the standardeventSend
function. The Reset button returns all form inputs back to their defaults. - Formatting improvements: Inputs are outlined with
--success
if they pass validation and with--failure
if they do not. Any buttons on the form are given--warning
colour if the form does not validate. The buttons still work however. - Form data improvements: Using the
eventSend
within a form element includes data saying whether the form validates. The details for each input also say whether they validate and if they don't, why. - The documentation for "Zero-code element types" > "Forms" completed.
- Where
uib-sender
node changes
- Add the uibuilder node link node id to config data & expand editor checks for url changes. Will mark the node instance as needing re-deployment if the linked uibuilder node changed its URL. This is done by also tracking and recording the node id of the linked uibuilder node.
uib-brand.css
updates
- Added intense (more saturated) versions of info, success, warning/warn, failure/error/danger.
- Added
center
as a synonym ofcentre
. - Added
surface5
which has higher lightness than 4. - Forms formatting extended.
- Form labels are shown in Title Text (first letter of each word capitalised). If attached to a required input, an "*" is shown after the label.
- Input valid/invalid formatting added. Borders set to
--success
,--failure
collours accordingly - Buttons on an invalid form set to
--warning
colour.
Standard Templates
- Bug Fix: Issue #204 - change to
rollup.config.js
caused issues with bundled css. Fixed.
Examples
- zero-code: Improved Forms example shows off more options. Example for light/dark mode added. On-(re)load flow attached to the control output of the uibuilder node; automatically changes the page title (an alternative to using a cache node).
- New Example: Remote-Commands - Demonstrates all of the uibuilder client library functions that can be called from Node-RED.
Bug fix release - fix zero-code example
Bug Fix: The zero-code example only had a single node in it. Now corrected to have the full example set demonstrating most aspects of the zero-code uib-sender
node with some examples of the zero-code uib-update
node.
Coming of age - uibuilder grows up!
In this release, it feels like uibuilder really is growing up. No more apologising for not being a direct Node-RED Dashboard replacement, uibuilder has its own path.
You can now create and update visible web page elements direct from Node-RED data without needing to understand all of the intricacies and inconsistencies of HTML. You can create your own utility tools either in Node-RED or in front-end code that leverages the low-code UI features of uibuilder. You can get information about the current state of your web pages back into Node-RED. You can save and reload the current state of your web pages. You get custom information from the front-end to help with security decisions and control. You can use a custom web server rather than Node-RED's and you can use custom middleware for fine-grained control. And so much more. A comprehensive review of the documentation has also started with some notable updates already that will hopefully make things easier to follow.
So please enjoy this new release it might be a small number change, but it is a big leap forward that paves the way for a lot more to come.
Summary of notable changes
Just a quick summary here. See the main sections for more details.
Please remember that no changes are being made to the old
uibuilderfe.js
client. Nothing listed here applies to that.
-
New zero-code nodes
uib-element
anduib-update
let you use simple data to create dynamic web UI's. Including in this release: tables, forms, lists, raw HTML and page title. More to come. -
The client library has a number of fixes and new features
-
Extensions to the
eventSend
function to include form data and value changes. Should greatly simplify creating and using FORMs and providing quick inputs for Node-RED flows. Used byuib-element
to create zero-code input forms. -
New function:
uibuilder.showMsg()
Displays/hides an on-screen card that automatically updates with the last msg received from Node-RED. -
New function:
uibuilder.showStatus()
Displays/hides an on-screen card that shows the current status of the uibuilder client. Use for debugging where console output is not available or not desirable (e.g. debugging pages on mobile devices). -
Some client functions can now be controlled direct from Node-RED via simple messages. Changing log levels, show/hide message and status displays, getting uibuilder client variable values join the ability to reload the page. More to come in the next release.
-
New function:
uibuilder.uiGet(cssSelector)
Gets useful data about an HTML element direct from the DOM. Saves lots of faffing when digging through DOM details. -
New function:
uibuilder.watchDom(true)
Starts watching the content of the page and saves it to browser localStorage so that it can be recovered at any time. Useuibuilder.restoreHtmlFromCache()
to recover the stored HTML (e.g. on page load). Useuibuilder.watchDom(false)
to turn off anduibuilder.clearHtmlCache()
to remove the saved HTML. If desired, you can manually save the HTML at any point usinguibuilder.saveHtmlCache()
. -
The uibuilder client now reports changes of visibility of pages back to node-red via a new control msg.
-
When using the
_ui
low-code features, you can now position a new element anywhere within its parent. Either first/last or a position number can be used. -
There is a new mode for the
_ui
low-code features - "removeAll". This allows a selection of elements to be the target of a remove - for example, all list entries could be removed with a single command. -
Creates a browser
tabId
which is reported back to node-red when messages are sent. Helps identify the origin. Future uibuilder versions will let you send messages to a specific tab id which does not change even if the page is reloaded (only if the tab is closed). -
Messages sent from the client either inherit the topic from the last inbound msg or from a default set using
uibuilder.set('topic', 'my topic string')
. The default will take preference. Reset by setting to an empty string.
-
-
If you turn on the advanced option "Include msg._uib in standard msg output", messages from the client now include client details for you to use in your own security processing or just to identify where things have come from (e.g. what page name as well as what client).
-
uibuilder now makes a copy of its main
<uibRoot>/package.json
file topackage.json.bak
before it updates it. Trace and error messages have been added to the process. -
All of the templates and example flows have been refreshed with the latest standards.
-
The default style-sheet
uib-brand.css
has various updates and improvements. -
Plenty of documentation updates and additions.
Notes for this release
v6.1.0 makes the new client libraries (uibuilder.esm.min.js
and uibuilder.iife.min.js
) current and the old client library (uibuilderfe.js
) is now no longer recommended and is not being updated, it is on the road to being deprecated (it will remain until at least v7, mahbe v8 but probably not longer unless someone calls for it).
The experimental uib-list
node is now deprecated, the features are moved to the new uib-element
node. It will be removed certainly by v7.
The new uib-brand.css
style library is not yet feature complete - if you find something missing or wrong, please raise an issue. It does, however, continue to develop.
Dynamic content does not currently work fully with VueJS (and probably not other frameworks that rely on pre-building components). It is possible though to combine the vanilla HTML from the low-/no-code features with front-end frameworks. Such frameworks require both the components and the structure to be pre-defined before the DOM is fully loaded. They have their own methods to provide dynamic includes, lazy loading, etc that are very different (and generally much more complex) than uibuilder's simple to use feature. However, dynamic content DOES work with HTML components and any frameworks that are compatible with them such as Svelte. The component definitions have to be loaded before you use them (that can be dynamic too!) and you must use the ESM build of the uibuilder client library since HTML Components are ES Module only.
uibuilder
node
-
Added JSON and Form encoded body processing to all user instance routes to allow for processing POST requests
-
Added new user web endpoint
./_clientLog
(web.js
::addLogRoute()
). This can only be POSTed to and should only be used fornavigator.sendBeacon
text messages (the body of the POST has to be plain text). -
Updated optional
msg._uib
properties on standard output messages, additional metadata added:msg._uib = { "clientId":"0yB8nqLSbhWAEyEpEuPYa", "remoteAddress":"::1", "pageName":"index.html", // The uibuilder URL setting "url":"uibUrl", // ID of the client tab - NOTE: If a tab is duplicated, it will have the same ID "tabId":"t568878" }
This data should help when working out identities for authentication and authorisation as well as enabling specific page/tab/user processing.
-
Updated connect, disconnect and error control messages. They now show more details about the originating client and page.
In particular, the connect msg now has
msg.lastNavType
which shows what the browser reported about the last time the originating page loaded. e.g. "navigate", "reload", "back_forward", "prerender". This comes from the Performance browser API. -
Reinstated ability for client to send uibuilder control messages.
- New "visibility" control msg now added which uses the document
visibilitychange
event.
- New "visibility" control msg now added which uses the document
-
Editor
- Added Open button to top button bar next to Delete. Add globe icon to open buttons.
- Added Docs button next to new Open button. Add book icon to docs buttons.
- Disable the new Open button along with other disabled things when new or url has changed.
- Icon changed.
-
socket.js
- When asked to add msg._uib to std output msgs, Standardised on the same client details as for control msgs to make downstream processing easier.
- Added visibility-change control msg. Sent by FE client. Fires when the open page changes from hidden-to-visible or visa versa.
- New functions: sendCtrlMsg, getClientDetails. Standardise/simplify client details shown on control msgs.
-
web.js
- Added new
addBeaconRoute
function that sets up the./_clientLog
instance endpoint. Use the new clientuibuilder.beaconLog(txtToSend, logLevel)
function to send a simple text log back to Node-RED even if socket.io isn't working.
- Added new
-
package-mgt.js
- A backup copy of
package.json
topackage.json.bak
is now made on each write. - Trace/Error log messages added to
writePackageJson
.
- A backup copy of
IIFE/ESM/Module client library
-
Bug fixes
- Fixed issue where method:update for msg._ui handling would cause a loop and console error. An assign by reference error fixed by forcing a shallow copy at the start of
_uiUpdate
. - Fixed bug where the library was loading
uib-brand.css
even when it didn't need to. It now doesn't load automatically even if there is a single stylesheet loaded on startup.
- Fixed issue where method:update for msg._ui handling would cause a loop and console error. An assign by reference error fixed by forcing a shallow copy at the start of
-
uibuilder.eventSend(event)
function improved.-
Now prevents the default event action from happening.
-
If the element that triggers the event is part of 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 inmsg._ui.form
. -
If the event type is
change
(e.g. a user changed an input field and then moved to a new field), amsg._ui.newValue
property is generat...
-