✨ UIBUILDER New Release v6.8.2 - (Important Bug Fix for v6.8.1) <uib-var> and router improvements and more

UPDATE 2024-01-04 - Important bug fix release. Please update ASAP, especially if using the new router or the uib-save node. See separate post below to see the changes.
UPDATE 2024-01-02 - Bug fix update released. Please update to v6.8.1 to avoid the bugs introduced in v6.8.0) :slight_smile:

Only 1 month after the last release! And on New-Year's day to boot. 78 commits across 197 files updated!! 11,347 total lines of code in UIBUILDER now. :sunglasses:

Hope you enjoy the update.

:pushpin: Highlights

  • The <uib-var> HTML component gets

    • This is BIG! - A topic attribute (use instead of the variable 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-side variable or topic 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 function uibuilder.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 (where routeid is the actual route id). The currentRoute 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.
  • 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) and removeClass(classNames, el) to make class handling easier.
    • New connect() and disconnect() 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 to true 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, and lastNavType properties. The connections property has now been corrected. The lastNavType, 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.
  • NEW - $ui is a new global created by the library which gives full access to the ui.js library, that library presents an instance of the Ui class. So typing $ui.version in the browser dev console will return the current version of the ui library. Also available as uibuilder.$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 as uibuilder.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's filter 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) - see ui.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. Set msg._uib.quiet to true to stop the library returning a message to Node-RED on completion of the command.

  • When using uiGet or nodeGet functions/commands, if class attribute is present, an additional classes property is returned which is an array of the class names.

  • Moved $ and $$ functions to ui.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 JavaScript Set 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 selector li[data-route] such that any having a data-route attribute matching the current route id have the currentRoute 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 contains the value to show. Applies filter if present. Just send a msg from Node-RED with the appropriate topic and the display will automatically update! (requires UIBUILDER)
  • NEW: Added filter attribute. A filter is a JavaScript function accessible from window global or uibuilder contexts. The filter is applied to the variable value before display. Can now supply ONLY the filter attribute (without variable or topic). This allows arbitrarily complex processing.
  • Auto load ./index.css instead of ../uibuilder/uib-brand.min.css - enables your own custom styling to be used. Not dependent on UIBUILDER, simply serve index.css from the same location as your main page.
  • When using UIBUILDER, the resulting HTML output is sanitised if you have the DOMPurify library loaded. If the output is a JavaScript object, it will be highlighted using uibuilder's standard JSON highlighter.
  • Improved error handling, especially for the filter attribute and its processing.

ui.js low-code->HTML hydration library

  • NEW functions - addClass(classNames, el), removeClass(classNames, el) - Add/remove classes individually. classNames can be a single class name, or an array of class names. For removeClass, an empty string, null or undefined can be used to remove all classes (removes the class attribute).

  • When using uiGet or nodeGet functions/commands, if class attribute is present, an additional classes property is returned which is an array of the class names.

  • Improved separation between payload and content in "alert" and "notify" methods.

  • Allowed low-code attributes property to be an array when specifying classes to apply. All classes in the array will be applied.

  • Moved $ and $$ functions to this library from uibuilder.

uib-brand.css

  • body left/right margins are now set by a CSS var --base-margin so they can be adjusted more easily.
  • Added new variable --emoji-fonts. Use as font-family: var(--emoji-fonts); for better emoji's. Used by custom bullets below.
  • Added li.check (AKA li.completed), li.uncheck (AKA li.unstarted), and li.started classes which change list bullets to :white_check_mark:, :x:, and :heavy_check_mark: respectively.
  • Added ui.checklist with --base-margin left/right margins and a little more space for the check bullets.
  • Added basic nav menu formatting using nav tag. Including basic horizontal menu (nav.horizontal class) formatting. Assumes list embedded in a nav tag and that the list has correct aria roles set.

Examples (import flows from Node-RED library)

  • Re-organised & renamed examples now there are more of them.
  • NEW - "Text Update - Different Methods" example
  • NEW - "FE Router Test" example

Documentation

  • Heading levels 3+ have been made lighter to better differentiate them visually.
  • The front-end client functions page now has an alphabetical list of functions.
  • Improved low-code documentation for the notify and alert methods.
  • Restructured config files for better future updates. Fixed some niggles.

Other

  • FIXED uibuilder's instance debug page was not working. Now fixed.
  • The list of all uibuilder apps available at /uibuilder/apps is now sorted by URL. Don't forget that it also uses the description fields of each uibuilder node.
  • More work done to move all filing system access into the single libs/fs.js library.
  • Usual ongoing work to tidy, clarify and simplify code & eliminate any small issues.
  • All nodes now have an Editor property addType which is set to 1 of 'load', 'new', or 'paste/import'. Allowing processing to differentiate between different circumstances that add nodes to the flow.
6 Likes

I have upgraded to 6.8.0, but now I can't deploy any new uibuilder instance.

As usual, I added an uibuilder node, inserted a name (i.e.: testing) and deployed. No instance has been created and the node is still claiming: URL does not yet exist. You must Deploy first.
If changing a deployed URL, the folder will be renamed on Deploy

Confirmed issue. Working on it.

Fix found for this issue. Note to self - don't be clever! I thought that reusing a flag already in use for a related check would be OK - it wasn't!

Need to check the other issue before I can publish an update.

Bug fixed v6.8.1 now published.

Upgraded and working, thanks!

Last week I was going to ask you about a possibile enhancement in order to have a functionality like the new <uib-var topic="..."> you have just implemented! This is awesome, thank you!

1 Like

Yes, that really is a big deal I believe. Especially for anyone who can work even a little with HTML. No heavy framework needed, 100% vanilla standards-based HMTL and capable of dealing with just about any content including Markdown and HTML safety for user-based content (both simply by loading standard 3rd-partly libraries: Markdown-IT and DOMPurify respectively - which the rest of uibuilder can use as well).


By the way, one of the things that has come to the forefront of my thinking again is the possibility of creating a WIKI or Knowledge Management tool using Node-RED, UIBUILDER and the router library.

I think the router library may have been the missing piece of the jigsaw for making it happen :slight_smile:

Thank you for your hard work, that are again nice features.

In the new router example at the uib-save node I can choose a URL, but it doesn't save it. As soon as I close the save-node, the setting is gone and I still have the red triangle. Deleting the save-node and creating a new one solves it.

In the same example is a "Goto route #1 via click event handler"-link. The page does load route#1, but the address bar of the browser still has the old route e.g. /#route02. Clicking on #2 at the navbar won't change the route anymore.

Hi Tom, thanks.

Are you using 6.8.1 or 6.8.0?

6.8.1
I don't have the issue fmarzocca mentioned. The URL of the example uibuilder-node deploys fine and I get an empty template. I don't see a difference between the imported save-node and a new created one, it has the same settings. However, the choosen URL is only saved at the new save-node.
I had no problem with the routerexample at v6.7

I've tested on my dev system and it is working as expected. When you paste/import a save node, it blanks (or should) the url field to prevent accidentally ending up connected to the wrong uibuilder node without you realising.

But you should be able to then select one of your existing uibuilder nodes and it should retain that - it certainly is for me.

However, I will try on my live system - which is just updating - as soon as I can. I will import the route example to do the test.

In the meantime, can I ask you to check both the Node-RED log and the dev tools for your editor web page to see if there are any reported issues?

Thanks.

Now tested on my live system and I can confirm the same issue as you. Will work on identifying the issue as soon as I can get the day-job out of the way :slight_smile:

Expect another bug-fix release. For reference, there is another bug I've already discovered and have a fix for:

  • FIXED Default route was always being set on load. Now correctly takes the current URL hash into account first.

I was going to report this!

1 Like

I've found the issue. It is a timing problem. I changed the node from using the list of deployed uibuilder instances to using the list of instances in the editor so that you could access a newly added uibuilder instance before you deploy. And this works great - except - on initial page load it sometimes doesn't work because the list of editor entries is build by listening to a Node-RED event and that is sometimes taking too long to run through all nodes. The result being that the validation of the uib-save node is completing before all the nodes are added to the flows. And so a chosen entry is not found.

Because the list of deployed nodes uses an api defined by uibuilder, it seems to work more quickly and I will try pre-populating the list of editor nodes with the deployed nodes and see if that is sufficient to fix the issue. I think it will be but until tested I won't know for sure.

Phew - well 1 bug actually turned into 4 :frowning:

All fixed now but too tired to publish tonight & starting to make mistakes, will get a v6.8.2 out tomorrow.

2 Likes

Changelog for the v6.8.2 bug fix:

Please update to this release as soon as possible, especially if using the new uibrouter or the uib-save node.

uibrouter library

  • FIXED Default route was always being set on load. Now correctly takes the current URL hash into account first.
  • FIXED Routes loaded via script, if pre-selected on page load (e.g. in URL hash), were crashing. Now will automatically revert to the default route and just print an error to the console.
  • FIXED On start, hash change event could be fired twice. Now does the initial route before setting up the hash change listener.

uib-save node

  • FIXED After import/paste, impossible to set a selected uibuilder node reference. Due to a timing issue in how Node-RED reports on nodes added to the flows on Editor page load. Now pre-populate the list of in-editor uibuilder nodes with deployed uibuilder nodes.
  • FIXED Correctly change saved URL if a uibuilder node changes it. In this case, the save node knows the id of its linked uibuilder node but not the name so we change the name and mark the save node as needing re-deployment.
  • FIXED In the Editor, the list of available uibuilder nodes to choose from was not sorted. Now sorted for ease of access.
  • FIXED After a paste/import, when the url changes, reset the addType flag to stop chkUrl re-blanking it by adding if (node.addType === 'paste/import') node.addType = 'load' (in oneditchange)

ti-common.js Editor support library

  • IMPROVED Due to a timing issue in how Node-RED reports on nodes added to the flows on Editor page load, the in-editor list of uibuilder node was not built soon enough for use. Now pre-populates the list of in-editor uibuilder nodes with deployed uibuilder nodes. (Only if the in-editor list has zero entries).
2 Likes

Updated. All fine.
Thanks!

1 Like