Another topic talked about buttons in ui-builder which I don’t use, but I liked the buttons so I stole the code from @Paul-Reed github page and tried to adapt to DB2. Got pretty far but the buttons don’t respond to input changes. After a heated exchange with chatgpt I am asking for a little help. Flow below. I should note at this point it’s trying to see what I can learn but if I can get this working I’d like to make some changes to my dashboards.
Thanks
[
{
"id": "08632d912a50eeea",
"type": "function",
"z": "0c10944b4a49d66c",
"name": "set flow array",
"func": "\n//Mode 0 random, 1 off, 2 on\n\nif (msg.topic == \"light1\"){\n flow.set(\"light1\",msg.payload);\n}\nif (msg.topic == \"light2\") {\n flow.set(\"light2\",msg.payload);\n}\nif (msg.topic == \"light3\") {\n flow.set(\"light3\", msg.payload);\n}\n\nmsg={};\n\n\n\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 630,
"y": 100,
"wires": [
[]
]
},
{
"id": "ab7b770d7439735f",
"type": "ui-template",
"z": "0c10944b4a49d66c",
"group": "eab230110ad3b180",
"page": "",
"ui": "",
"name": "Timer1",
"order": 5,
"width": "3",
"height": "2",
"head": "",
"format": "<template>\n <main>\n <v-col>\n <v-row>\n <!-- Light 1 -->\n <section class=\"wrap-row\">\n <button class=\"status-button\" @click=\"light1\">\n <div class=\"indicator\" :style=\"{ backgroundColor: indicatorColor1 }\"></div>\n <span>{{ isOn1 ? 'Light1 On' : 'Light1 Off' }}</span>\n </button>\n </section>\n\n <!-- Light 2 -->\n <section class=\"wrap-row\">\n <button class=\"status-button\" @click=\"light2\">\n <div class=\"indicator\" :style=\"{ backgroundColor: indicatorColor2 }\"></div>\n <span>{{ isOn2 ? 'Light2 On' : 'Light2 Off' }}</span>\n </button>\n </section>\n\n <!-- Light 3 -->\n <section class=\"wrap-row\">\n <button class=\"status-button\" @click=\"light3\">\n <div class=\"indicator\" :style=\"{ backgroundColor: indicatorColor3 }\"></div>\n <span>{{ isOn3 ? 'Light3 On' : 'Light3 Off' }}</span>\n </button>\n </section>\n </v-row>\n </v-col>\n </main>\n</template>\n\n<script>\nexport default {\n data() {\n return {\n isOn1: false,\n isOn2: false,\n isOn3: false,\n msg: {} // placeholder for external updates\n };\n },\n computed: {\n indicatorColor1() {\n return this.isOn1 ? 'limegreen' : 'blue';\n },\n indicatorColor2() {\n return this.isOn2 ? 'limegreen' : 'blue';\n },\n indicatorColor3() {\n return this.isOn3 ? 'limegreen' : 'blue';\n }\n },\n watch: {\n msg: {\n deep: true,\n handler(newVal) {\n if (!newVal || !newVal.topic) return;\n \n if (newVal.topic === \"light1\") {\n this.isOn1 = !!newVal.payload; // force boolean\n this.send({ topic: \"light1\", payload: this.isOn1 });\n }\n if (newVal.topic === \"light2\") {\n this.isOn2 = !!newVal.payload;\n }\n if (newVal.topic === \"light3\") {\n this.isOn3 = !!newVal.payload;\n }\n },\n },\n },\n\n\n methods: {\n light1() {\n this.isOn1 = !this.isOn1;\n this.send({ topic: \"light1\", payload: this.isOn1 });\n },\n\n light2() {\n this.isOn2 = !this.isOn2;\n this.send({ topic: \"light2\", payload: this.isOn2 });\n },\n\n light3() {\n this.isOn3 = !this.isOn3;\n this.send({ topic: \"light3\", payload: this.isOn3 });\n },\n },\n};\n</script>\n\n<style scoped>\n.status-button {\n display: flex;\n align-items: center;\n background-color: var(--surface4);\n border: 1px solid var(--text3);\n border-radius: var(--border-radius);\n padding: 6px 10px;\n margin-right: 0.3em;\n font-family: var(--font-family);\n color: black;\n height: var(--control-height);\n width: fit-content;\n cursor: pointer;\n transition: box-shadow 0.4s, transform 0.2s;\n}\n\n.status-button:active {\n transform: scale(0.98);\n box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);\n}\n\n.indicator {\n width: 0.5em;\n height: 2em;\n margin-right: 0.5em;\n border-radius: 0.5em;\n transition: background-color 0.3s;\n}\n\n.wrap-row {\n display: flex;\n flex-wrap: wrap;\n gap: 0.2em;\n align-items: flex-start;\n justify-content: flex-start;\n}\n\n:root {\n --control-height: 3em;\n --surface4: #f0f0f0;\n --text3: #ccc;\n --border-radius: 0.5em;\n --font-family: Arial, sans-serif;\n --text-color: #333;\n --font-size-base: 1rem;\n}\n</style>\n",
"storeOutMessages": true,
"passthru": false,
"resendOnRefresh": true,
"templateScope": "local",
"className": "",
"x": 430,
"y": 80,
"wires": [
[
"08632d912a50eeea",
"d7a2d9a92aaf2133"
]
]
},
{
"id": "06acf90d0ab38e63",
"type": "ui-template",
"z": "0c10944b4a49d66c",
"group": "",
"page": "1e8c695c2252935b",
"ui": "",
"name": "",
"order": 0,
"width": 0,
"height": 0,
"head": "",
"format": "\n\n<style>\n .root {}\n\n .container {\n display: flex;\n justify-content: center;\n align-items: center;\n width: 90px;\n height: 80px;\n /* Adjust height as needed */\n background-color: black;\n border-top: 3px solid #6689a1;\n border-bottom: 3px solid #6689a1;\n border-left: 3px solid #6689a1;\n border-right: 3px solid #6689a1;\n }\n\n .containerTop {\n display: flex;\n justify-content: center;\n align-items: center;\n width: 270px;\n height: 25px;\n /* Adjust height as needed */\n background-color: black;\n color: white;\n font-size: 12px;\n text-align: center;\n border-bottom: 2px solid #dd7f00;\n border-top: 3px solid #6689a1;\n border-left: 3px solid #6689a1;\n border-right: 3px solid #6689a1;\n }\n\n .containerTopTwo {\n display: flex;\n justify-content: center;\n align-items: center;\n width: 135px;\n height: 25px;\n /* Adjust height as needed */\n background-color: black;\n color: white;\n font-size: 12px;\n text-align: center;\n border-bottom: 2px solid #dd7f00;\n border-top: 3px solid #6689a1;\n border-left: 3px solid #6689a1;\n border-right: 3px solid #6689a1;\n }\n\n .containerTopThree {\n display: flex;\n justify-content: center;\n align-items: center;\n width: 90px;\n height: 25px;\n /* Adjust height as needed */\n background-color: black;\n color: white;\n font-size: 12px;\n text-align: center;\n border-bottom: 2px solid #dd7f00;\n border-top: 3px solid #6689a1;\n border-left: 3px solid #6689a1;\n border-right: 3px solid #6689a1;\n }\n\n .containerBottom {\n display: flex;\n justify-content: center;\n align-items: center;\n width: 270px;\n color: white;\n font-size: 12px;\n text-align: center;\n height: 25px;\n /* Adjust height as needed */\n background-color: black;\n border-top: 3px solid #6689a1;\n border-bottom: 3px solid #6689a1;\n border-left: 3px solid #6689a1;\n border-right: 3px solid #6689a1;\n }\n\n .containerOne {\n display: flex;\n justify-content: center;\n align-items: center;\n width: 270px;\n height: 40px;\n /* Adjust height as needed */\n background-color: black;\n border-top: 3px solid #6689a1;\n border-bottom: 3px solid #6689a1;\n border-left: 3px solid #6689a1;\n border-right: 3px solid #6689a1;\n //font-size: 40px;\n font-family: \"Times New Roman\", Times, serif;\n font-style: normal;\n }\n\n .containerTwo {\n display: flex;\n justify-content: center;\n align-items: center;\n width: 135px;\n height: 80px;\n /* Adjust height as needed */\n background-color: black;\n border-top: 3px solid #6689a1;\n border-bottom: 3px solid #6689a1;\n border-left: 3px solid #6689a1;\n border-right: 3px solid #6689a1;\n }\n\n .containerTime {\n display: flex;\n justify-content: center;\n align-items: center;\n width: 270px;\n height: 40px;\n /* Adjust height as needed */\n background-color: black;\n border-top: 3px solid #dd7f00;\n border-bottom: 3px solid #dd7f00;\n border-left: 3px solid #dd7f00;\n border-right: 3px solid #dd7f00;\n }\n\n .containerTimeOne {\n display: flex;\n justify-content: center;\n align-items: center;\n width: 270px;\n height: 40px;\n /* Adjust height as needed */\n background-color: black;\n border-top: 3px solid #6689a1;\n border-bottom: 3px solid #6689a1;\n border-left: 3px solid #6689a1;\n border-right: 3px solid #6689a1;\n font-size: 80em;\n font-family: \"Times New Roman\", Times, serif;\n font-style: normal;\n }\n\n .box {\n width: 25px;\n /* Adjust box width as needed */\n height: 80px;\n /* Adjust box height as needed */\n display: flex;\n justify-content: center;\n align-items: center;\n }\n\n .centered-button {\n padding: 10px 20px;\n color: white;\n font-size: 16px;\n cursor: pointer;\n }\n\n .button {\n display: flex;\n width: 75px;\n padding-top: 2px;\n border-top: 5px;\n background-color: grey;\n /* Default background color */\n color: white;\n font-size: 12px;\n border: none;\n cursor: pointer;\n }\n\n .active {\n background-color: green;\n /* Changed background color when active */\n }\n\n .a1 {\n background-color: black;\n justify-content: center;\n text-align: center;\n height: 25px !important;\n width: 140px !important;\n margin-top: 5px;\n margin-bottom: 1px;\n margin-left: 5px;\n margin-right: 5px;\n font-size: 16px;\n color: #6689a1;\n padding-bottom: 4px;\n border-bottom: 2px solid #dd7f00;\n border-top: 2px solid #6689a1;\n border-left: 2px solid #6689a1;\n border-right: 2px solid #6689a1;\n }\n\n .a2 {\n background-color: grey;\n justify-content: center;\n align-items: center;\n text-align: center;\n height: 50px !important;\n width: 100px !important;\n margin-top: 1px;\n margin-bottom: 5px;\n margin-left: 5px;\n margin-right: 5px;\n font-size: 16px;\n color: #6689a1;\n padding-bottom: 2px;\n border-bottom: 2px solid #6689a1;\n border-top: 2px solid #6689a1;\n border-left: 2px solid #6689a1;\n border-right: 2px solid #6689a1;\n }\n</style>",
"storeOutMessages": true,
"passthru": false,
"resendOnRefresh": true,
"templateScope": "page:style",
"className": "",
"x": 430,
"y": 40,
"wires": [
[]
]
},
{
"id": "d7a2d9a92aaf2133",
"type": "debug",
"z": "0c10944b4a49d66c",
"name": "debug 1",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "true",
"targetType": "full",
"statusVal": "payload",
"statusType": "auto",
"x": 620,
"y": 40,
"wires": []
},
{
"id": "367664da6938bc0a",
"type": "inject",
"z": "0c10944b4a49d66c",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "light1",
"payload": "true",
"payloadType": "bool",
"x": 100,
"y": 80,
"wires": [
[
"ab7b770d7439735f",
"e4a19c927380d807"
]
]
},
{
"id": "e4a19c927380d807",
"type": "debug",
"z": "0c10944b4a49d66c",
"name": "debug 2",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "true",
"targetType": "full",
"statusVal": "payload",
"statusType": "auto",
"x": 280,
"y": 120,
"wires": []
},
{
"id": "eab230110ad3b180",
"type": "ui-group",
"name": "3 state",
"page": "1e8c695c2252935b",
"width": 6,
"height": 1,
"order": -1,
"showTitle": true,
"className": "",
"visible": "true",
"disabled": "false",
"groupType": "default"
},
{
"id": "1e8c695c2252935b",
"type": "ui-page",
"name": "New Buttons",
"ui": "929358b9b68de19a",
"path": "/page3",
"icon": "home",
"layout": "grid",
"theme": "a539e4afb8f63f3f",
"breakpoints": [
{
"name": "Default",
"px": "0",
"cols": "3"
},
{
"name": "Tablet",
"px": "576",
"cols": "6"
},
{
"name": "Small Desktop",
"px": "768",
"cols": "9"
},
{
"name": "Desktop",
"px": "1024",
"cols": "12"
}
],
"order": -1,
"className": "",
"visible": "true",
"disabled": "false"
},
{
"id": "929358b9b68de19a",
"type": "ui-base",
"name": "My Dashboard",
"path": "/dashboard",
"appIcon": "",
"includeClientData": true,
"acceptsClientConfig": [
"ui-notification",
"ui-control"
],
"showPathInSidebar": false,
"headerContent": "page",
"navigationStyle": "default",
"titleBarStyle": "default",
"showReconnectNotification": true,
"notificationDisplayTime": 1,
"showDisconnectNotification": true,
"allowInstall": true
},
{
"id": "a539e4afb8f63f3f",
"type": "ui-theme",
"name": "Default Theme",
"colors": {
"surface": "#000000",
"primary": "#000000",
"bgPage": "#000000",
"groupBg": "#000000",
"groupOutline": "#ffffff"
},
"sizes": {
"density": "default",
"pagePadding": "12px",
"groupGap": "12px",
"groupBorderRadius": "4px",
"widgetGap": "12px"
}
},
{
"id": "90bc21fd4342754b",
"type": "global-config",
"env": [],
"modules": {
"@flowfuse/node-red-dashboard": "1.24.2"
}
}
]