node-red-contrib-uibuilder
Version:
Easily create data-driven web UI's for Node-RED. Single- & Multi-page. Multiple UI's. Work with existing web development workflows or mix and match with no-code/low-code features.
772 lines (770 loc) • 36.3 kB
JSON
[
{
"id": "1678f3c7ab967e39",
"type": "group",
"z": "ff9704678e3a4b61",
"name": "UIBUILDER Dynamic SVG Example - Interactive bulb icons linked to Node-RED, minimal coding required (Updated 2024-07-01) \\n ",
"style": {
"label": true,
"color": "#000000",
"fill": "#ffffff",
"fill-opacity": "0.21"
},
"nodes": [
"18b02b8e78a54427",
"68208d9442bc03c1",
"5f6a472f6435e598",
"389e05735379ed2e",
"3feb6c0d7c1c07b2",
"8ce7dd9a5d97b83b",
"891a5f86c7c89917",
"3939b0bbde991557",
"5eb220cde9614fee",
"8653c6e164389a3a",
"9ca3a3da680721e7",
"bf47991b0cd95827"
],
"x": 74,
"y": 879,
"w": 1172,
"h": 508
},
{
"id": "18b02b8e78a54427",
"type": "uibuilder",
"z": "ff9704678e3a4b61",
"g": "1678f3c7ab967e39",
"name": "",
"topic": "",
"url": "uib-dynamic-svg-eg",
"okToGo": true,
"fwdInMessages": false,
"allowScripts": false,
"allowStyles": false,
"copyIndex": true,
"templateFolder": "blank",
"extTemplate": "",
"showfolder": false,
"reload": true,
"sourceFolder": "src",
"deployedVersion": "6.2.0-dev",
"showMsgUib": true,
"editurl": "vscode://file/src/uibRoot/uib-dynamic-svg-eg/?windowId=_blank",
"x": 720,
"y": 1040,
"wires": [
[
"95af327f377fa565"
],
[
"5f6a472f6435e598"
]
]
},
{
"id": "68208d9442bc03c1",
"type": "debug",
"z": "ff9704678e3a4b61",
"g": "1678f3c7ab967e39",
"name": "Std output",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "counter",
"x": 1105,
"y": 1100,
"wires": [],
"l": false
},
{
"id": "5f6a472f6435e598",
"type": "debug",
"z": "ff9704678e3a4b61",
"d": true,
"g": "1678f3c7ab967e39",
"name": "Ctrl output",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "counter",
"x": 885,
"y": 1100,
"wires": [],
"l": false
},
{
"id": "389e05735379ed2e",
"type": "comment",
"z": "ff9704678e3a4b61",
"g": "1678f3c7ab967e39",
"name": "Vanilla HTML, no framework needed. \\n Updated version of old example that used VueJS & update again for UIBUILDER v7 \\n Read this comment for details.",
"info": "This example demonstrates how to use uibuilder\nwith SVG images to create a dynamic home\nlighting dashboard.\n\nUse a background-image (see index.css) and\nthen clone the included \"bulb\" SVG \n(see index.html `<template>`) and change the\nproperties of each bulb using uibuilder's \nreduced-code functions. Colours, size, position,\netc are all controlled by CSS classes.\n\n## To use the example\n\nAs always deploy your flow after adding a\nuibuilder node, making sure the url setting \nis unique.\n\nThen update the `index.html`, `index.js` and \n`index.css` files with the flow provided.\n\nOpen the resulting page and play with\ncontrolling from Node-RED and try clicking\non the bulb symbols on the page to see \nhow all the interactions work.\n\nThis example demonstrates a hybrid way of \nworking with uibuilder to create web pages.\n\nThere is some code and some Node-RED flow.\n\nHopefully, this illustrates how a little code \ncan go a long way and that you are not \nconstrained to use just one approach but can \nmix and match as desired.\n\nAnd, it also demonstrates that you really do\nnot need a 3rd-party front-end framework like\nVueJS or REACT to produce reactive front-end\nsolutions.",
"x": 390,
"y": 960,
"wires": []
},
{
"id": "3feb6c0d7c1c07b2",
"type": "debug",
"z": "ff9704678e3a4b61",
"g": "1678f3c7ab967e39",
"name": "Std output",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "counter",
"x": 1185,
"y": 980,
"wires": [],
"l": false
},
{
"id": "8ce7dd9a5d97b83b",
"type": "link in",
"z": "ff9704678e3a4b61",
"g": "1678f3c7ab967e39",
"name": "link in 10",
"links": [
"a4fb2160fb46d36c",
"06fa35d1c6063d4c",
"bf47991b0cd95827"
],
"x": 555,
"y": 1080,
"wires": [
[
"18b02b8e78a54427"
]
]
},
{
"id": "891a5f86c7c89917",
"type": "group",
"z": "ff9704678e3a4b61",
"g": "1678f3c7ab967e39",
"name": "Control lights from Node-RED",
"style": {
"fill": "#ffbfbf",
"fill-opacity": "0.23",
"label": true,
"color": "#000000"
},
"nodes": [
"ad6de73ba713120d",
"b2b85b92b1cf7da5",
"77193b09f79ec310",
"4c9d8f9adc268c35",
"f86567acf2326bad",
"36595c40107736a2"
],
"x": 114,
"y": 1019,
"w": 302,
"h": 242
},
{
"id": "ad6de73ba713120d",
"type": "inject",
"z": "ff9704678e3a4b61",
"g": "891a5f86c7c89917",
"name": "LIGHTS (random)",
"props": [
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "LIGHTS",
"x": 250,
"y": 1060,
"wires": [
[
"b2b85b92b1cf7da5"
]
]
},
{
"id": "b2b85b92b1cf7da5",
"type": "change",
"z": "ff9704678e3a4b61",
"g": "891a5f86c7c89917",
"name": "Randomly turn on/off all bulbs",
"rules": [
{
"t": "set",
"p": "_ui",
"pt": "msg",
"to": "(\t /* Generate a true/false for each bulb */\t $b1 := $random() >= 0.5;\t $b2 := $random() >= 0.5;\t $b3 := $random() >= 0.5;\t $b4 := $random() >= 0.5;\t /* Apply to msg._ui to randomly update all bulbs */\t [\t {\t \"method\":\"update\",\t \"components\": [\t {\t \"id\":\"bulb1\",\t \"attributes\": {\t /* NB: Give this one a different colour to the others */\t \"class\":\"bulb posn1 \" & ($b1 ? \"bulb-fail\" : \"\"),\t /* We use a data attribute to make it easier to track on/off state */\t \"data-state\": ($b1 ? \"on\" : \"off\")\t }\t }\t ]\t },\t {\t \"method\":\"update\",\t \"components\": [\t {\t \"id\":\"bulb2\",\t \"attributes\": {\t \"class\":\"bulb posn2 \" & ($b2 ? \"bulb-warn\" : \"\"),\t \"data-state\": ($b2 ? \"on\" : \"off\")\t }\t }\t ]\t },\t {\t \"method\":\"update\",\t \"components\": [\t {\t \"id\":\"bulb3\",\t \"attributes\": {\t \"class\":\"bulb posn3 \" & ($b3 ? \"bulb-warn\" : \"\"),\t \"data-state\": ($b3 ? \"on\" : \"off\")\t }\t }\t ]\t },\t {\t \"method\":\"update\",\t \"components\": [\t {\t \"id\":\"bulb4\",\t \"attributes\": {\t \"class\":\"bulb posn4 \" & ($b4 ? \"bulb-warn\" : \"\"),\t \"data-state\": ($b4 ? \"on\" : \"off\")\t }\t }\t ]\t }\t ]\t)",
"tot": "jsonata"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 375,
"y": 1060,
"wires": [
[
"8653c6e164389a3a"
]
],
"l": false
},
{
"id": "77193b09f79ec310",
"type": "inject",
"z": "ff9704678e3a4b61",
"g": "891a5f86c7c89917",
"name": "LIGHT 1 on",
"props": [
{
"p": "_ui",
"v": "[{\"method\":\"update\",\"components\":[{\"id\":\"bulb1\",\"attributes\":{\"class\":\"bulb posn1 bulb-fail\",\"data-state\":\"on\"}}]}]",
"vt": "json"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "LIGHT-1",
"x": 270,
"y": 1100,
"wires": [
[
"8653c6e164389a3a"
]
]
},
{
"id": "4c9d8f9adc268c35",
"type": "inject",
"z": "ff9704678e3a4b61",
"g": "891a5f86c7c89917",
"name": "LIGHT 1 off",
"props": [
{
"p": "_ui",
"v": "[{\"method\":\"update\",\"components\":[{\"id\":\"bulb1\",\"attributes\":{\"class\":\"bulb posn1\",\"data-state\":\"off\"}}]}]",
"vt": "json"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "LIGHT-1",
"x": 270,
"y": 1140,
"wires": [
[
"8653c6e164389a3a"
]
]
},
{
"id": "f86567acf2326bad",
"type": "inject",
"z": "ff9704678e3a4b61",
"g": "891a5f86c7c89917",
"name": "LIGHT 2 on",
"props": [
{
"p": "_ui",
"v": "[{\"method\":\"update\",\"components\":[{\"id\":\"bulb2\",\"attributes\":{\"class\":\"bulb posn2 bulb-warn\",\"data-state\":\"on\"}}]}]",
"vt": "json"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "LIGHT-2",
"x": 270,
"y": 1180,
"wires": [
[
"8653c6e164389a3a"
]
]
},
{
"id": "36595c40107736a2",
"type": "inject",
"z": "ff9704678e3a4b61",
"g": "891a5f86c7c89917",
"name": "LIGHT 2 off",
"props": [
{
"p": "_ui",
"v": "[{\"method\":\"update\",\"components\":[{\"id\":\"bulb2\",\"attributes\":{\"class\":\"bulb posn2\",\"data-state\":\"off\"}}]}]",
"vt": "json"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "LIGHT-2",
"x": 270,
"y": 1220,
"wires": [
[
"8653c6e164389a3a"
]
]
},
{
"id": "3939b0bbde991557",
"type": "group",
"z": "ff9704678e3a4b61",
"g": "1678f3c7ab967e39",
"name": "User clicks turn on/off",
"style": {
"fill": "#e3f3d3",
"fill-opacity": "0.26",
"label": true,
"color": "#000000"
},
"nodes": [
"95af327f377fa565",
"c3bec95c24885417",
"a4fb2160fb46d36c"
],
"x": 894,
"y": 959,
"w": 252,
"h": 109.5
},
{
"id": "95af327f377fa565",
"type": "switch",
"z": "ff9704678e3a4b61",
"g": "3939b0bbde991557",
"name": "Switch out bulb clicks",
"property": "payload.state",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "on",
"vt": "str"
},
{
"t": "eq",
"v": "off",
"vt": "str"
},
{
"t": "else"
}
],
"checkall": "false",
"repair": false,
"outputs": 3,
"x": 935,
"y": 1020,
"wires": [
[
"c3bec95c24885417"
],
[
"c3bec95c24885417"
],
[
"68208d9442bc03c1"
]
],
"outputLabels": [
"A bulb is currently ON",
"A bulb is currently OFF",
"Anything else"
],
"l": false
},
{
"id": "c3bec95c24885417",
"type": "change",
"z": "ff9704678e3a4b61",
"g": "3939b0bbde991557",
"name": "Toggle clicked bulb state",
"rules": [
{
"t": "set",
"p": "_ui",
"pt": "msg",
"to": "(\t [\t {\t \"method\":\"update\",\t \"components\":[\t {\t \"id\": _ui.id,\t \"attributes\":{\t /* Toggle fill colour */\t \"class\":\"bulb \" & payload.posn & \" \" & (payload.state = \"off\" ? \"bulb-warn\" : \"\"),\t /* Toggle state */\t \"data-state\": (payload.state = \"on\" ? \"off\" : \"on\")\t }\t }\t ]\t }\t]\t)",
"tot": "jsonata"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 1005,
"y": 1000,
"wires": [
[
"3feb6c0d7c1c07b2",
"a4fb2160fb46d36c"
]
],
"l": false
},
{
"id": "a4fb2160fb46d36c",
"type": "link out",
"z": "ff9704678e3a4b61",
"g": "3939b0bbde991557",
"name": "Loop back to uibuilder node input",
"mode": "link",
"links": [
"8ce7dd9a5d97b83b"
],
"x": 1105,
"y": 1020,
"wires": []
},
{
"id": "5eb220cde9614fee",
"type": "group",
"z": "ff9704678e3a4b61",
"g": "1678f3c7ab967e39",
"name": "Run this to update the front-end code files (after setting the uibuilder url name)",
"style": {
"fill": "#ffffff",
"fill-opacity": "0.31",
"label": true,
"color": "#000000"
},
"nodes": [
"4f4b2563ed01b96a",
"2ae5e4c81a6d9d60",
"3bc7cd6653cb521c",
"5a1578bc66134fda",
"5003f0c412d3fccb",
"e0ae3e10d4c8573e",
"d52529f420959f1d",
"6174f2357fd373d1",
"768c8273347df9fa",
"5dce296a96d3f95e"
],
"x": 524,
"y": 1159,
"w": 682,
"h": 202
},
{
"id": "4f4b2563ed01b96a",
"type": "inject",
"z": "ff9704678e3a4b61",
"g": "5eb220cde9614fee",
"name": "",
"props": [],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"x": 585,
"y": 1200,
"wires": [
[
"5a1578bc66134fda",
"5003f0c412d3fccb",
"d52529f420959f1d",
"768c8273347df9fa"
]
],
"l": false
},
{
"id": "2ae5e4c81a6d9d60",
"type": "template",
"z": "ff9704678e3a4b61",
"g": "5eb220cde9614fee",
"name": "",
"field": "payload",
"fieldType": "msg",
"format": "html",
"syntax": "mustache",
"template": "<!doctype html>\n<html lang=\"en\"><head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <link rel=\"icon\" href=\"../uibuilder/images/node-blue.ico\">\n\n <title>Dynamic SVG Example - Node-RED UIBUILDER</title>\n <meta name=\"description\" content=\"Node-RED UIBUILDER - Dynamic SVG Example\">\n\n <!-- Your own CSS (defaults to loading uibuilders css)-->\n <link type=\"text/css\" rel=\"stylesheet\" href=\"./index.css\" media=\"all\">\n\n <!-- #region Supporting Scripts. These MUST be in the right order. Note no leading / -->\n <script defer src=\"../uibuilder/uibuilder.iife.min.js\"></script>\n <script defer src=\"./index.js\"></script>\n <!-- #endregion -->\n</head><body>\n <!-- This template defines a reusable bulb icon component. It is applied in the JavaScript code -->\n <template id=\"bulb-template\">\n <svg id=\"mybulb\" class=\"bulb\" height=\"3rem\" viewBox=\"0 0 1024 1024\" version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <filter id=\"shadow\">\n <feDropShadow dx=\"1\" dy=\"1\" stdDeviation=\"5\" flood-opacity=\"50%\" />\n </filter>\n <filter id=\"glow\" filterUnits=\"userSpaceOnUse\" x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">\n <!-- blur the text at different levels-->\n <feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"5\" result=\"blur5\" />\n <feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"10\" result=\"blur10\" />\n <feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"20\" result=\"blur20\" />\n <feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"30\" result=\"blur30\" />\n <feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"50\" result=\"blur50\" />\n <!-- merge all the blurs except for the first one -->\n <feMerge result=\"blur-merged\">\n <feMergeNode in=\"blur10\" />\n <feMergeNode in=\"blur20\" />\n <feMergeNode in=\"blur30\" />\n <feMergeNode in=\"blur50\" />\n </feMerge>\n <!-- recolour the merged blurs red-->\n <feColorMatrix result=\"red-blur\" in=\"blur-merged\" type=\"matrix\" values=\"1 0 0 0 0\n 0 0.06 0 0 0\n 0 0 0.44 0 0\n 0 0 0 1 0\" />\n <feMerge>\n <!--<feMergeNode in=\"red-blur\"/> largest blurs coloured red -->\n <feMergeNode in=\"blur-merged\" />\n <feMergeNode in=\"blur5\" /> <!-- smallest blur left white -->\n <feMergeNode in=\"SourceGraphic\" /> <!-- original -->\n </feMerge>\n </filter>\n </defs>\n <title>TITLE</title>\n <path name=\"icon\"\n d=\"M511.549861 803.293331H408.419043a73.232959 73.232959 0 0 1-67.1862-41.991375 59.795719 59.795719 0 0 1-6.71862-30.569722 207.60536 207.60536 0 0 0-33.593101-113.88061 196.519637 196.519637 0 0 0-27.882273-33.5931A463.248853 463.248853 0 0 1 217.274302 504.314738a399.086031 399.086031 0 0 1-36.95241-75.248544 242.542184 242.542184 0 0 1-15.116895-77.264131 349.032312 349.032312 0 0 1 8.062344-84.990544 314.76735 314.76735 0 0 1 51.733375-114.888403A367.172586 367.172586 0 0 1 361.724634 34.011334 327.532728 327.532728 0 0 1 433.949799 8.144647 369.524103 369.524103 0 0 1 528.682342 0.418234a333.579486 333.579486 0 0 1 126.310057 29.225997 326.860866 326.860866 0 0 1 70.881442 44.678824A382.625412 382.625412 0 0 1 808.848799 168.383736a314.095488 314.095488 0 0 1 41.991375 105.146403 312.751764 312.751764 0 0 1 6.382689 92.045095 275.799353 275.799353 0 0 1-20.15586 76.256338 449.139751 449.139751 0 0 1-61.139443 107.16199 497.513815 497.513815 0 0 1-33.5931 39.639858 160.575019 160.575019 0 0 0-31.241583 48.038134 215.331773 215.331773 0 0 0-18.812136 55.428615c-1.679655 11.757585 0 23.179239-2.687448 33.5931a171.660742 171.660742 0 0 1-3.695241 25.194826 69.873649 69.873649 0 0 1-33.593101 40.647651 74.576683 74.576683 0 0 1-39.639858 10.07793zM490.050277 88.768088c-11.085723 0-22.171446 2.351517-33.5931 4.031172a210.96467 210.96467 0 0 0-74.240752 26.538549 244.221839 244.221839 0 0 0-55.428616 44.342893 222.386324 222.386324 0 0 0-43.335099 63.82689 230.784599 230.784599 0 0 0-19.483998 94.732543 28.218204 28.218204 0 0 0 33.5931 28.890066 28.890066 28.890066 0 0 0 22.171446-26.202618v-13.773171a167.965501 167.965501 0 0 1 9.406068-49.045927 184.762052 184.762052 0 0 1 64.834684-83.98275 167.965501 167.965501 0 0 1 93.72475-33.593101 142.770676 142.770676 0 0 0 18.140274 0 23.851101 23.851101 0 0 0 19.148067-15.452826 33.5931 33.5931 0 0 0 0-19.483998 23.51517 23.51517 0 0 0-20.491791-18.140274 122.950747 122.950747 0 0 0-15.116895 0zM647.601917 943.040628a15.788757 15.788757 0 0 1-13.773171 15.116895H400.356699a17.468412 17.468412 0 0 1-16.460619-8.734206 18.812136 18.812136 0 0 1 0-20.15586 16.124688 16.124688 0 0 1 16.460619-4.703034h227.089358a19.148067 19.148067 0 0 1 19.148067 20.827722zM405.731595 899.369598a18.140274 18.140274 0 0 1-16.460619-12.765378 17.804343 17.804343 0 0 1 15.452826-23.851101H635.508401a18.812136 18.812136 0 0 1 17.804343 13.773171 19.819929 19.819929 0 0 1-10.749792 21.499584 24.187032 24.187032 0 0 1-8.734206 0H423.535938zM437.64504 1022.992207a17.132481 17.132481 0 0 1-15.452826-9.406068 18.140274 18.140274 0 0 1 15.116895-26.202618h139.411367a19.819929 19.819929 0 0 1 19.483998 17.804343 16.124688 16.124688 0 0 1-8.734206 15.788757 19.148067 19.148067 0 0 1-9.741999 3.023379H442.348074z\" />\n <!-- <circle name=\"default\" cx=\"50\" cy=\"50\" r=\"50\"></circle> -->\n </svg>\n </template>\n\n <h1 class=\"with-subtitle\">Dynamic SVG Example</h1>\n <div role=\"doc-subtitle\">Using the UIBUILDER IIFE library.</div>\n\n <p>\n This is a UIBUILDER example showing how easy it is to create a dynamic view of IoT devices in a building\n using SVG images both for the background (floor-plan) and device indicators.\n </p>\n\n <div id=\"more\"><!-- '#more' is used as a parent for dynamic HTML content in examples --></div>\n\n <h2>My House, Ground Floor</h2>\n <div id=\"floorplan\" class=\"plan\">\n <!-- \n Bulb icons are dynamically inserted here by the JavaScript code.\n The plan class provides the background plan image.\n -->\n </div>\n</body></html>",
"output": "str",
"x": 860,
"y": 1200,
"wires": [
[
"3bc7cd6653cb521c"
]
]
},
{
"id": "3bc7cd6653cb521c",
"type": "uib-save",
"z": "ff9704678e3a4b61",
"g": "5eb220cde9614fee",
"url": "uib-dynamic-svg-eg",
"uibId": "18b02b8e78a54427",
"folder": "src",
"fname": "",
"createFolder": false,
"reload": false,
"usePageName": false,
"encoding": "utf8",
"mode": 438,
"name": "",
"topic": "",
"x": 1090,
"y": 1200,
"wires": []
},
{
"id": "5a1578bc66134fda",
"type": "change",
"z": "ff9704678e3a4b61",
"g": "5eb220cde9614fee",
"name": "index.html",
"rules": [
{
"t": "set",
"p": "fname",
"pt": "msg",
"to": "index.html",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 710,
"y": 1200,
"wires": [
[
"2ae5e4c81a6d9d60"
]
]
},
{
"id": "5003f0c412d3fccb",
"type": "change",
"z": "ff9704678e3a4b61",
"g": "5eb220cde9614fee",
"name": "index.js",
"rules": [
{
"t": "set",
"p": "fname",
"pt": "msg",
"to": "index.js",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 700,
"y": 1240,
"wires": [
[
"e0ae3e10d4c8573e"
]
]
},
{
"id": "e0ae3e10d4c8573e",
"type": "template",
"z": "ff9704678e3a4b61",
"g": "5eb220cde9614fee",
"name": "",
"field": "payload",
"fieldType": "msg",
"format": "javascript",
"syntax": "mustache",
"template": "// @ts-nocheck\n/** Dynamic SVG example */\n\n// uibuilder.logLevel = 1\n\n// The Template tag in index.html contains a template \"bulb\" SVG image\n// Here, we clone that multiple times and set some properties.\n// Note that `htmlClone` is a function that will land in the uibuilder client in v6.2\n// Also, the $ function is improved in v6.2 so a copy of that is included here for convenience.\n//\n// We track state and position class on data-* attributes so that it is much easier to process\n// click events in Node-RED without having to create a custom click handler, we can just use the standard eventSend.\n// CSS classes do all the clever stuff 😁\n\nuibuilder.applyTemplate('bulb-template', 'floorplan', {\n attributes: {\n id: 'bulb1',\n // Apply base bulb class and a positioning class\n class: 'bulb posn1',\n // Track the on/off state separately - makes processing in Node-RED easier\n 'data-state': 'off',\n // Track the position class separately - makes processing in Node-RED easier\n 'data-posn': 'posn1',\n // We have to add event handlers after a clone, they cannot be included in the template\n onclick: 'uibuilder.eventSend(event)'\n }\n})\nuibuilder.applyTemplate('bulb-template', 'floorplan', {\n attributes: {\n id: 'bulb2',\n // Apply base bulb class and a positioning class\n class: 'bulb posn2',\n // Track the on/off state separately - makes processing in Node-RED easier\n 'data-state': 'off',\n // Track the position class separately - makes processing in Node-RED easier\n 'data-posn': 'posn2',\n // We have to add event handlers after a clone, they cannot be included in the template\n onclick: 'uibuilder.eventSend(event)'\n }\n})\nuibuilder.applyTemplate('bulb-template', 'floorplan', {\n attributes: {\n id: 'bulb3',\n // Apply base bulb class and a positioning class\n class: 'bulb posn3',\n // Track the on/off state separately - makes processing in Node-RED easier\n 'data-state': 'off',\n // Track the position class separately - makes processing in Node-RED easier\n 'data-posn': 'posn3',\n // We have to add event handlers after a clone, they cannot be included in the template\n onclick: 'uibuilder.eventSend(event)'\n }\n})\nuibuilder.applyTemplate('bulb-template', 'floorplan', {\n attributes: {\n id: 'bulb4',\n // Apply base bulb class and a positioning class\n class: 'bulb posn4',\n // Track the on/off state separately - makes processing in Node-RED easier\n 'data-state': 'off',\n // Track the position class separately - makes processing in Node-RED easier\n 'data-posn': 'posn4',\n // We have to add event handlers after a clone, they cannot be included in the template\n onclick: 'uibuilder.eventSend(event)'\n }\n})\n\n// htmlClone($('#bulb-template'), $('#floorplan'), {\n// // As always, we set a unique ID for every created element so it can be updated easily later\n// id: 'bulb1',\n// // You only need this if you want to choose 'first' or a position number,\n// // the clone will be added at the specified child position of the parent.\n// // position: 'last', \n// attributes: {\n// // Apply base bulb class and a positioning class\n// class: 'bulb posn1',\n// // Track the on/off state separately - makes processing in Node-RED easier\n// 'data-state': 'off',\n// // Track the position class separately - makes processing in Node-RED easier\n// 'data-posn': 'posn1'\n// },\n// // We have to add event handlers after a clone, they cannot be included in the template\n// events: {\n// click: 'uibuilder.eventSend'\n// }\n// })\n\n// htmlClone(mySelector('#bulb-template'), mySelector('#floorplan'), {\n// id: 'bulb2',\n// attributes: {\n// class: 'bulb posn2',\n// 'data-state': 'off',\n// 'data-posn': 'posn2'\n// },\n// events: {\n// click: 'uibuilder.eventSend'\n// }\n// })\n\n// htmlClone(mySelector('#bulb-template'), mySelector('#floorplan'), {\n// id: 'bulb3',\n// attributes: {\n// class: 'bulb posn3',\n// 'data-state': 'off',\n// 'data-posn': 'posn3'\n// },\n// events: {\n// click: 'uibuilder.eventSend'\n// }\n// })\n\n// htmlClone(mySelector('#bulb-template'), mySelector('#floorplan'), {\n// id: 'bulb4',\n// attributes: {\n// class: 'bulb posn4',\n// 'data-state': 'off',\n// 'data-posn': 'posn4'\n// },\n// events: {\n// click: 'uibuilder.eventSend'\n// },\n// })\n",
"output": "str",
"x": 860,
"y": 1240,
"wires": [
[
"3bc7cd6653cb521c"
]
]
},
{
"id": "d52529f420959f1d",
"type": "change",
"z": "ff9704678e3a4b61",
"g": "5eb220cde9614fee",
"name": "index.css",
"rules": [
{
"t": "set",
"p": "fname",
"pt": "msg",
"to": "index.css",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 700,
"y": 1280,
"wires": [
[
"6174f2357fd373d1"
]
]
},
{
"id": "6174f2357fd373d1",
"type": "template",
"z": "ff9704678e3a4b61",
"g": "5eb220cde9614fee",
"name": "",
"field": "payload",
"fieldType": "msg",
"format": "css",
"syntax": "mustache",
"template": "/* Load defaults from `<userDir>/node_modules/node-red-contrib-uibuilder/front-end/uib-brand.css`\n * This version auto-adjusts for light/dark browser settings but might not be as complete.\n */\n@import url(\"../uibuilder/uib-brand.css\");\n\n/* These variables build on existing variables in uib-brand.css\n * They will be incorporated into that file in uibuilder v6.2\n */\n:root {\n --warning-intense: hsl(var(--warning-hue) 100% 50%);\n --failure-intense: hsl(var(--failure-hue) 100% 50%);\n --surface5: hsl(\n /* additional background shade */\n var(--brand-hue) calc(100% * var(--surfaces-saturation)) calc(100% * (var(--surfaces-lightness) - (var(--surfaces-factor) * .20) + (var(--surfaces-factor) * var(--surfaces-bias)))));\n}\n\n\n/* Bulb classes control look, colour and position */\n\n.bulb {\n /* Default \"off\" class plus standard style */\n z-index: 9999 !important;\n /* Bulbs HAVE to be in the top z-layer */\n cursor: pointer;\n position: absolute;\n /* allows exact positioning within the parent div */\n transition: filter 2s ease-in-out 0s;\n background-color: rgba(0, 0, 0, 0.001);\n /* transparent background */\n filter: url(\"#shadow\");\n /* selects the shadow filter */\n}\n\n.bulb path {\n fill: grey;\n}\n\n.bulb-warn {\n /* Standard \"on\" class */\n filter: url('#glow');\n /* selects the glow filter instead of shadow */\n}\n\n.bulb-warn path {\n fill: var(--warning-intense);\n}\n\n.bulb-fail {\n /* Alternative \"on\" class with different colour */\n filter: url('#glow');\n}\n\n.bulb-fail path {\n fill: var(--failure-intense);\n}\n\n/* Bulb position classes, change as needed\n * Positions are relative to the parent floorplan div\n */\n.posn1 {\n top: 100px;\n left: 100px;\n}\n\n.posn2 {\n top: 120px;\n left: 270px;\n}\n\n.posn3 {\n top: 120px;\n left: 650px;\n}\n\n.posn4 {\n top: 270px;\n left: 250px;\n}\n\n/* floorplan div class change anything\n * except the position:relative.\n * The background image location is relative\n * to your uibuilder front-end files.\n */\n.plan {\n position: relative;\n width: 99%;\n height: 30rem;\n background-color: var(--surface5);\n background-repeat: no-repeat;\n background-image: url(\"./background.svg\");\n /* Sadly, can't use a GIST directly here. Copy this file to the local folder instead: */\n /* background: url(\"https://gist.github.com/TotallyInformation/02eb3716157db586f3f5b8a85c241009#file-background-svg\"); */\n}\n",
"output": "str",
"x": 860,
"y": 1280,
"wires": [
[
"3bc7cd6653cb521c"
]
]
},
{
"id": "768c8273347df9fa",
"type": "change",
"z": "ff9704678e3a4b61",
"g": "5eb220cde9614fee",
"name": "background.svg",
"rules": [
{
"t": "set",
"p": "fname",
"pt": "msg",
"to": "background.svg",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 720,
"y": 1320,
"wires": [
[]
]
},
{
"id": "5dce296a96d3f95e",
"type": "comment",
"z": "ff9704678e3a4b61",
"g": "5eb220cde9614fee",
"name": "background.svg",
"info": "Can't include this directly here otherwise\nthe flow cannot be posted to the forum.\n\nThe example background file can be obtained\nhere:\n\nhttps://gist.github.com/TotallyInformation/02eb3716157db586f3f5b8a85c241009#file-background-svg\n\nCopy the text out of it and paste into a new \nfile, `background1.svg` in the same location \nas your `index.html` file.\n",
"x": 900,
"y": 1320,
"wires": []
},
{
"id": "8653c6e164389a3a",
"type": "junction",
"z": "ff9704678e3a4b61",
"g": "1678f3c7ab967e39",
"x": 520,
"y": 1040,
"wires": [
[
"18b02b8e78a54427"
]
]
},
{
"id": "9ca3a3da680721e7",
"type": "inject",
"z": "ff9704678e3a4b61",
"g": "1678f3c7ab967e39",
"name": "Toggle Visible Msgs",
"props": [
{
"p": "_uib",
"v": "{\"command\":\"showMsg\"}",
"vt": "json"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"x": 230,
"y": 1320,
"wires": [
[
"bf47991b0cd95827"
]
]
},
{
"id": "bf47991b0cd95827",
"type": "link out",
"z": "ff9704678e3a4b61",
"g": "1678f3c7ab967e39",
"name": "Send to uibuilder node",
"mode": "link",
"links": [
"8ce7dd9a5d97b83b"
],
"x": 395,
"y": 1320,
"wires": []
}
]