Sorry, I couldn't resist and the weather was terrible today! I was going to release 1.4.1 but in the end, the updates were too big - so here is v1.5.0
Summary of changes in v1.5
-
MAJOR UPDATE - The base component has been updated to handle more uibuilder message inputs.
You can send a msg with the msg.topic set to component-name::id
to set any property or attribute of the component. This update now allows you to set classes, styles, data-attributes, and values. Any other property is added as a property of the element rather than an attribute.
-
UPDATE - labeled-input
component
- Added auto change event to send changes immediately to Node-RED via uibuilder when the input value changes. Only if uibuilder is present and the input is not inside a form. The documentation has been updated to reflect this. The returned message topic is
labeled-input/change/name
where name
is the name of the input. The payload contains the changed value. msg._meta
contains additional data that may be of use including: the previous value, id, name and type of input.
-
button-send
- Add uibuilder message sending demo.
-
Start to add uibuilder-specific HTML. Commented out but making it easier to incorporate into uibuilder pages.
_test-template.html
live/button-send.html
live/call-out.html
live/collapsible-headings.html
live/data-list.html
live/h1-title.html
live/html-include.html
live/led-gauge.html
alpha/labeled-input.html
To use the demo/test pages with uibuilder for Node-RED, copy the whole pages
folder into your uibuilder instance folder and set the node to use that folder using the advanced tab. Then uncomment the relevant lines in the HTML head section for any page you want to use and comment out the stand-alone lines.
Test page for using with UIBUILDER for Node-RED
Here is a quick test page to help people use the web-components library with UIBUILDER.
After importing, don't forget to first name the uibuilder node and deploy. Then install the components library using uibuilder's Library Manager tab. Then you can follow the readme at the top of the imported page.
[{"id":"2c47031326e8fd01","type":"tab","label":"TI WC Tests","disabled":false,"info":"Testing the TI Web Components library\r\n\r\nRead the readme first to correctly set up these\r\ntests.","env":[]},{"id":"349a99ecf4a3ad8a","type":"group","z":"2c47031326e8fd01","name":"If the data-list test page is showing. Update the first list. New HTML text content is sent first and then a new list.","style":{"fill":"#e3f3d3","fill-opacity":"0.2","label":true,"color":"#000000"},"nodes":["b6221e56cb4d6652","fd5456075222084c","625003b509fdb71d","f6378b50eef90925","f9139d2d46e53071"],"x":54,"y":519,"w":702,"h":122},{"id":"a6adf8c814ea39df","type":"group","z":"2c47031326e8fd01","name":"Core","style":{"label":true,"color":"#000000"},"nodes":["d79da848f082d821","c1c1273697d0c0d3","dc8c6e18b6b209b6","baf98201102ea713"],"x":54,"y":99,"w":552,"h":142},{"id":"5280fb631c7d3157","type":"group","z":"2c47031326e8fd01","name":"Page controls","style":{"fill":"#bfbfbf","fill-opacity":"0.35","label":true,"color":"#000000"},"nodes":["ca1fb080bf336089","f7556a7999836b28","4493aeefd709cb84","5edd6397d8c76a02"],"x":834,"y":99,"w":332,"h":162},{"id":"0958c88d9e5ba8df","type":"group","z":"2c47031326e8fd01","name":"Testing <led-gauge> (Toggle updates on the page first)","style":{"fill":"#e3f3d3","fill-opacity":"0.25","label":true,"color":"#000000"},"nodes":["411273962d195075","9bb62bc1cd7bad3c"],"x":54,"y":679,"w":682,"h":82},{"id":"be701bbd8a0980fa","type":"group","z":"2c47031326e8fd01","name":"Testing <collapsible-headings> - any content added with headings should be collapsible - content is added at the top of the page","style":{"fill":"#e3f3d3","fill-opacity":"0.26","label":true,"color":"#000000"},"nodes":["473a297be9f81407","b108f5a5b6204a53","b0cdd123141f5eb7","617053f26322eea0","9396d8d9ec748531","2c9f8b6801b1efab"],"x":48,"y":799,"w":1128,"h":328},{"id":"617053f26322eea0","type":"group","z":"2c47031326e8fd01","g":"be701bbd8a0980fa","name":"Add/replace #more.manual-2 with heading and paras - using uib-tag node","style":{"fill":"#bfdbef","fill-opacity":"0.23","label":true,"color":"#0070c0"},"nodes":["13453844827fc8b3","9802142222f2ff62","1e1f465e6c58a04b"],"x":74,"y":919,"w":632,"h":82},{"id":"2c9f8b6801b1efab","type":"group","z":"2c47031326e8fd01","g":"be701bbd8a0980fa","name":"Replace #collapsible-headings-1 (\"My first heading\") with heading and paras - using uib-update node","style":{"fill":"#dbcbe7","fill-opacity":"0.32","label":true,"color":"#6f2fa0"},"nodes":["d0f33006afda148d","e2b5591574a4b793","badffe14b0166b36"],"x":74,"y":1019,"w":632,"h":82},{"id":"aa3ba2bdfe68dfdf","type":"group","z":"2c47031326e8fd01","name":"<labeled-input>: change first input's background colour and value","style":{"fill":"#e3f3d3","fill-opacity":"0.31","label":true,"color":"#000000"},"nodes":["3e4bf23522996347","64d9ee32caf6e104"],"x":54,"y":399,"w":662,"h":82},{"id":"9396d8d9ec748531","type":"junction","z":"2c47031326e8fd01","g":"be701bbd8a0980fa","x":940,"y":960,"wires":[["b0cdd123141f5eb7"]]},{"id":"c39c272bd6ec06f7","type":"junction","z":"2c47031326e8fd01","x":940,"y":1060,"wires":[["b0cdd123141f5eb7"]]},{"id":"d79da848f082d821","type":"debug","z":"2c47031326e8fd01","g":"a6adf8c814ea39df","name":"Std Output","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"","statusType":"counter","x":545,"y":140,"wires":[],"l":false},{"id":"c1c1273697d0c0d3","type":"uibuilder","z":"2c47031326e8fd01","g":"a6adf8c814ea39df","name":"components-html","topic":"","url":"components-html","okToGo":true,"fwdInMessages":false,"allowScripts":false,"allowStyles":false,"copyIndex":true,"templateFolder":"blank","extTemplate":"","showfolder":false,"reload":true,"sourceFolder":"tests","deployedVersion":"5.0.0-dev.2","showMsgUib":false,"title":"Testing TotallyInformation web components","descr":"","editurl":"vscode://file/src/uibRoot/components-html/?windowId=_blank","x":320,"y":160,"wires":[["d79da848f082d821"],["dc8c6e18b6b209b6"]]},{"id":"dc8c6e18b6b209b6","type":"debug","z":"2c47031326e8fd01","g":"a6adf8c814ea39df","name":"Ctrl Output","active":false,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"","statusType":"counter","x":545,"y":200,"wires":[],"l":false},{"id":"baf98201102ea713","type":"link in","z":"2c47031326e8fd01","g":"a6adf8c814ea39df","name":"link in 1","links":["5edd6397d8c76a02","b6221e56cb4d6652","9bb62bc1cd7bad3c","84a0deb0e6c3c8ca","d8f1bf63848edeca","b0cdd123141f5eb7","3e4bf23522996347"],"x":95,"y":160,"wires":[["c1c1273697d0c0d3"]]},{"id":"ca1fb080bf336089","type":"inject","z":"2c47031326e8fd01","g":"5280fb631c7d3157","name":"Toggle Visible Msgs","props":[{"p":"_uib","v":"{\"command\":\"showMsg\"}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":970,"y":140,"wires":[["5edd6397d8c76a02"]]},{"id":"f7556a7999836b28","type":"inject","z":"2c47031326e8fd01","g":"5280fb631c7d3157","name":"Log Lvl 5","props":[{"p":"_uib","v":"{\"command\":\"set\",\"prop\":\"logLevel\",\"value\":5}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":1000,"y":180,"wires":[["5edd6397d8c76a02"]]},{"id":"4493aeefd709cb84","type":"inject","z":"2c47031326e8fd01","g":"5280fb631c7d3157","name":"Reload","props":[{"p":"_ui","v":"{\"method\":\"reload\"}","vt":"json"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"reload","x":1010,"y":220,"wires":[["5edd6397d8c76a02"]],"info":"Sends a pre-formatted msg to the front-end that\r\ncauses the page to reload itself."},{"id":"5edd6397d8c76a02","type":"link out","z":"2c47031326e8fd01","g":"5280fb631c7d3157","name":"link out 55","mode":"link","links":["baf98201102ea713"],"x":1125,"y":180,"wires":[]},{"id":"b6221e56cb4d6652","type":"link out","z":"2c47031326e8fd01","g":"349a99ecf4a3ad8a","name":"link out 56","mode":"link","links":["baf98201102ea713"],"x":715,"y":560,"wires":[]},{"id":"fd5456075222084c","type":"inject","z":"2c47031326e8fd01","g":"349a99ecf4a3ad8a","name":"data-list:","props":[{"p":"str","v":"$formatNumber($random()*100, \"0.0\")\t\t","vt":"jsonata"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":160,"y":560,"wires":[["625003b509fdb71d","f9139d2d46e53071"]]},{"id":"625003b509fdb71d","type":"uib-update","z":"2c47031326e8fd01","g":"349a99ecf4a3ad8a","name":"Change dl1 text","topic":"","mode":"update","modeSourceType":"update","cssSelector":"#dl1","cssSelectorType":"str","slotSourceProp":"<p>List is replaced by a message from Node-RED.</p>","slotSourcePropType":"str","attribsSource":"","attribsSourceType":"msg","slotPropMarkdown":false,"x":360,"y":560,"wires":[["b6221e56cb4d6652"]]},{"id":"f6378b50eef90925","type":"change","z":"2c47031326e8fd01","g":"349a99ecf4a3ad8a","name":"Change dl1 list","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\"keyvalueseparator\":\" ๐ \",\"liststyle\":\"'๐ '\",\"data\":{\"xxx\":\"Triple x\",\"yyy\":\"Triple y\",\"zzz\":\"triple z\"},\"style\":\"background-color: var(--surface4);\"}","tot":"json"},{"t":"set","p":"topic","pt":"msg","to":"data-list::dl1","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":550,"y":600,"wires":[["b6221e56cb4d6652"]]},{"id":"f9139d2d46e53071","type":"delay","z":"2c47031326e8fd01","g":"349a99ecf4a3ad8a","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":380,"y":600,"wires":[["f6378b50eef90925"]]},{"id":"e098e4cc596316be","type":"comment","z":"2c47031326e8fd01","name":"NOTE: Many of the component web pages have delayed actions in front-end code. \\n You may need to give them a few seconds before sending dynamic updates from Node-RED to avoid clashes.","info":"","x":430,"y":300,"wires":[]},{"id":"baa286f94c606dab","type":"comment","z":"2c47031326e8fd01","name":"Web components home page: https://wc.totallyinformation.net/ \\n Readme first","info":"[Web components home page](https://wc.totallyinformation.net/)\n\nCopy the `tests` folder from the\n`@totallyinformation/web-components` package.\n\nThen make sure that the delivery folder (on\nthe advanced tab) is set to use the `tests`\nfolder.\n\nFor each page, you will need to uncomment\nthe uibuilder links. You can leave the\noriginal links in place if you want since they\nsimply will fail to load.\n\nThe head section contains the `<script>` tags\nthat load the libraries. For use with uibuilder\nthey should look something like this:\n\n```html\n<!-- For stand-alone use -->\n<!-- <script defer src=\"../../dist/call-out.iife.min.js\"></script>\n<script defer src=\"../../dist/alpha/labeled-input.iife.min.js\">/* NB: Loads <labeled-input> AND <input-group> */</script> -->\n<!-- For uibuilder use -->\n<script defer src=\"../../../uibuilder/uibuilder.iife.min.js\">/* THE UIBUILDER LIBRARY MUST BE IN THE HTML! DO NOT REMOVE */</script>\n<script defer src=\"../../../uibuilder/vendor/@totallyinformation/web-components/dist/call-out.iife.min.js\"></script>\n<script defer src=\"../../../uibuilder/vendor/@totallyinformation/web-components/dist/labeled-input.iife.min.js\"></script>\n<!-- <script defer src=\"./index.js\">/* OPTIONAL: Put your custom code in that */</script> -->\n```\n\nOther links, with the exception of the documentation\nlinks should work fine.","x":280,"y":40,"wires":[]},{"id":"42a730fdc388dcbf","type":"comment","z":"2c47031326e8fd01","name":"Example updated: 2025-09-20 \\n Requires a minimum of v1.4.1 of the component package. \\n Tested using UIBUILDER v7.5.0","info":"","x":830,"y":40,"wires":[]},{"id":"411273962d195075","type":"inject","z":"2c47031326e8fd01","g":"0958c88d9e5ba8df","name":"led-gauge::led-gauge-1 - set to value 65, set colour breaks at 60 and 80","props":[{"p":"topic","vt":"str"},{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"led-gauge::led-gauge-1","payload":"{\"value\":65,\"colors\":{\"60\":40,\"80\":0}}","payloadType":"json","x":350,"y":720,"wires":[["9bb62bc1cd7bad3c"]]},{"id":"9bb62bc1cd7bad3c","type":"link out","z":"2c47031326e8fd01","g":"0958c88d9e5ba8df","name":"link out 10","mode":"link","links":["baf98201102ea713"],"x":695,"y":720,"wires":[]},{"id":"473a297be9f81407","type":"inject","z":"2c47031326e8fd01","g":"be701bbd8a0980fa","name":"Check if Markdown-IT loaded? (payload should be true)","props":[{"p":"_uib","v":"{\"command\":\"get\",\"prop\":\"markdown\"}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":300,"y":840,"wires":[["b0cdd123141f5eb7"]]},{"id":"b108f5a5b6204a53","type":"inject","z":"2c47031326e8fd01","g":"be701bbd8a0980fa","name":"Replace #more div with Markdown Content - heading, para and list - heading should be collapsable - using uibuilder low-code","props":[{"p":"_ui","v":"[{\"method\":\"replace\",\"components\":[{\"type\":\"collapsible-headings\",\"id\":\"md\",\"parent\":\"#more\",\"attributes\":{},\"slotMarkdown\":\"## H2 - Markdown input\\n\\nSome text in a para\\n\\n* List #1\\n* List #2\\n\"}]}]","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":520,"y":880,"wires":[["b0cdd123141f5eb7"]]},{"id":"b0cdd123141f5eb7","type":"link out","z":"2c47031326e8fd01","g":"be701bbd8a0980fa","name":"link out 5","mode":"link","links":["baf98201102ea713"],"x":1135,"y":840,"wires":[]},{"id":"1e1f465e6c58a04b","type":"uib-tag","z":"2c47031326e8fd01","g":"617053f26322eea0","name":"","topic":"","tag":"collapsible-headings","tagSource":"","tagSourceType":"str","parent":"#more","parentSource":"","parentSourceType":"str","elementId":"manual-2","elementIdSourceType":"str","position":"last","positionSourceType":"str","slotSourceProp":"payload","slotSourcePropType":"msg","attribsSource":"","attribsSourceType":"msg","slotPropMarkdown":false,"x":530,"y":960,"wires":[["9396d8d9ec748531"]]},{"id":"13453844827fc8b3","type":"inject","z":"2c47031326e8fd01","g":"617053f26322eea0","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"auto-create-html-from-html","payload":"{\t \"mystring\": \"Boo-hoo\",\t \"mynumber\": $formatInteger($random() * 100, \"#00\")\t}\t ","payloadType":"jsonata","x":170,"y":960,"wires":[["9802142222f2ff62"]]},{"id":"9802142222f2ff62","type":"template","z":"2c47031326e8fd01","g":"617053f26322eea0","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<div style=\"border: 1px solid hsl(315deg 30% 35%)\">\n <h2>My Dynamic Heading (h2)</h2>\n <p style=\"background-color: hsl(315deg 30% 35%)\">\n Added using uibuilder's <code>uib-tag</code>\n node from a node-red HMTL template.\n </p>\n <p>\n Lorem ipsum dolor sit amet, consectetur\n adipiscing elit, sed do eiusmod tempor\n incididunt ut labore et dolore magna aliqua.\n Ut enim ad minim veniam, quis nostrud\n exercitation ullamco laboris nisi ut\n aliquip ex ea commodo consequat. Duis\n aute irure dolor in reprehenderit in\n voluptate velit esse cillum dolore eu\n fugiat nulla pariatur. Excepteur sint\n occaecat cupidatat non proident, sunt\n in culpa qui officia deserunt mollit anim\n id est laborum.\n </p>\n</div>","output":"str","x":300,"y":960,"wires":[["1e1f465e6c58a04b"]]},{"id":"d0f33006afda148d","type":"inject","z":"2c47031326e8fd01","g":"2c9f8b6801b1efab","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"auto-create-html-from-html","payload":"{\t \"mystring\": \"Boo-hoo\",\t \"mynumber\": $formatInteger($random() * 100, \"#00\")\t}\t ","payloadType":"jsonata","x":170,"y":1060,"wires":[["e2b5591574a4b793"]]},{"id":"e2b5591574a4b793","type":"template","z":"2c47031326e8fd01","g":"2c9f8b6801b1efab","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<div style=\"border: 1px solid hsl(165deg 30% 35%)\">\n <h2>My Dynamic Heading (h2)</h2>\n <p style=\"background-color: hsl(165deg 30% 35%)\">\n Replaced the previous \"My first heading\"\n and following paragraphs by using uibuilder's\n <code>uib-update</code>\n node from a node-red HMTL template.\n </p>\n <p>\n Lorem ipsum dolor sit amet, consectetur\n adipiscing elit, sed do eiusmod tempor\n incididunt ut labore et dolore magna aliqua.\n Ut enim ad minim veniam, quis nostrud\n exercitation ullamco laboris nisi ut\n aliquip ex ea commodo consequat. Duis\n aute irure dolor in reprehenderit in\n voluptate velit esse cillum dolore eu\n fugiat nulla pariatur. Excepteur sint\n occaecat cupidatat non proident, sunt\n in culpa qui officia deserunt mollit anim\n id est laborum.\n </p>\n</div>","output":"str","x":300,"y":1060,"wires":[["badffe14b0166b36"]]},{"id":"badffe14b0166b36","type":"uib-update","z":"2c47031326e8fd01","g":"2c9f8b6801b1efab","name":"","topic":"","mode":"update","modeSourceType":"update","cssSelector":"#collapsible-headings-1","cssSelectorType":"str","slotSourceProp":"payload","slotSourcePropType":"msg","attribsSource":"","attribsSourceType":"msg","slotPropMarkdown":false,"x":510,"y":1060,"wires":[["c39c272bd6ec06f7"]]},{"id":"64d9ee32caf6e104","type":"inject","z":"2c47031326e8fd01","g":"aa3ba2bdfe68dfdf","name":"labeled-input:wc01","props":[{"p":"topic","vt":"str"},{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"labeled-input::wc01","payload":"{\t \"style\": \"background-color: hsl(\" & $floor($random() * 360) & \"deg 200% 10%)\",\t \"value\": $floor($random() * 100),\t \"class\": \"cool cow\",\t \"data-something\": $floor($random() * 1000)\t}","payloadType":"jsonata","x":190,"y":440,"wires":[["3e4bf23522996347"]]},{"id":"3e4bf23522996347","type":"link out","z":"2c47031326e8fd01","g":"aa3ba2bdfe68dfdf","name":"link out 6","mode":"link","links":["baf98201102ea713"],"x":675,"y":440,"wires":[]},{"id":"469767cd1c09f5df","type":"global-config","env":[],"modules":{"node-red-contrib-uibuilder":"7.5.0"}}]
The head section of each test page contains the <script>
tags that load the libraries. For use with uibuilder they should look something like this:
<!-- For stand-alone use -->
<!-- <script defer src="../../dist/call-out.iife.min.js"></script>
<script defer src="../../dist/alpha/labeled-input.iife.min.js">/* NB: Loads <labeled-input> AND <input-group> */</script> -->
<!-- For uibuilder use -->
<script defer src="../../../uibuilder/uibuilder.iife.min.js">/* THE UIBUILDER LIBRARY MUST BE IN THE HTML! DO NOT REMOVE */</script>
<script defer src="../../../uibuilder/vendor/@totallyinformation/web-components/dist/call-out.iife.min.js"></script>
<script defer src="../../../uibuilder/vendor/@totallyinformation/web-components/dist/labeled-input.iife.min.js"></script>
<!-- <script defer src="./index.js">/* OPTIONAL: Put your custom code in that */</script> -->
Other links, with the exception of the documentation links should work fine.