Hi,
thanks, but sorry need some more help,
I made a template window shutter control in which I want to replace some of the the mdi-icons with local stored modified icons.
The icons change dynamically with the state of the control.
this are the nodes which I use to test the control (includes simulation of the shutter responses)
[
{
"id": "d703d7c03729cecd",
"type": "ui-template",
"z": "be85a1a7964e5e68",
"group": "1b676f206101966b",
"name": "shuttercontrol room1",
"order": 0,
"width": "1",
"height": "1",
"head": "",
"format": "<template>\n <v-btn class=\"button_Shutter\" ref=\"button\" stacked @click=\"clicked\">\n <div class=\"title_Shutter\">{{labellevel}}</div>\n <v-icon class=\"icon_Shutter\" :color=\"iconcolor\" ref=\"icon\">{{shutter_icon}}</v-icon>\n </v-btn>\n</template>\n\n\n<script>\n export default {\n data() {\n return {\n value: \"OFF\",\n label: \"Room1\",\n labellevel: \"Room1\",\n shutter_icon: \"mdi-window-shutter-open\",\n iconcolor: \"yellow\",\n state: \"open\",\n operationState: \"STOPPED\",\n level: 0, // level=0=closed, level=1=open\n shutterstate: \"closed\",\n timerID: 0,\n clicked_mem: false,\n };\n },\n methods: {\n singleclick: function () {\n this.send({ \"log\": \"singleclick\"});\n },\n doubleclick: function () {\n this.send({ \"log\": \"doubleclick\"});\n },\n tofunction: function () {\n this.close_shutter();\n this.clicked_mem=false;\n },\n \n \n clicked: function () \n {\n if(this.operationState==\"MOVING\")\n {\n this.stop_shutter();\n }\n else\n {\n switch(this.shutterstate)\n {\n case \"open\":\n this.close_shutter();\n break;\n case \"closed\":\n this.open_shutter();\n break;\n case \"between\":\n if(this.clicked_mem==false) \n { \n this.timerID=setTimeout(this.tofunction, 1000); \n this.clicked_mem=true;\n }\n else {\n clearTimeout(this.timerID);\n this.clicked_mem=false;\n this.open_shutter();\n }\n break;\n }\n }\n \n },\n close_shutter: function () {\n this.send({ payload: 'close' });\n },\n open_shutter: function () {\n this.send({ payload: 'open' });\n },\n stop_shutter: function () {\n this.send({ payload: 'stop' });\n },\n },\n watch: {\n operationState: function()\n {\n switch(this.operationState)\n {\n case \"STOPPED\":\n if(this.level==1) {\n this.iconcolor=\"yellow\";\n this.shutter_icon = \"mdi-window-shutter-open\";\n this.labellevel=this.label;\n this.shutterstate=\"open\";\n\n }\n else if(this.level==0) {\n this.iconcolor=\"grey\";\n this.shutter_icon = \"mdi-window-shutter\";\n this.labellevel=this.label;\n this.shutterstate=\"closed\";\n }\n else {\n this.iconcolor=\"blue\";\n this.shutter_icon = \"mdi-window-shutter-open\";\n this.labellevel=this.label+\" \"+this.level*100+\"%\";\n this.shutterstate=\"between\";\n }\n this.dirup=false;\n break;\n case \"MOVING\":\n if(this.level==0) // closing\n {\n this.shutter_icon = \"mdi-chevron-double-down\";\n //this.shutter_icon = \"my_icon_2\";\n this.iconcolor=\"orange\"; \n }\n else \n if(this.level==1) // opening\n {\n this.shutter_icon = \"mdi-chevron-double-up\";\n this.iconcolor=\"orange\"; \n }\n \n\n break;\n }\n },\n msg: function(){\n if(this.msg.payload != undefined){\n if(this.msg.payload.state != undefined){\n if(this.msg.payload.state.operationState != undefined){\n this.operationState=this.msg.payload.state.operationState;\n }\n if(this.msg.payload.state.level != undefined){\n this.level=this.msg.payload.state.level;\n \n }\n }\n }\n if(this.msg.label!= undefined)\n {\n this.label=this.msg.label;\n this.labellevel=this.label;\n }\n \n if(this.msg.color!= undefined)\n {\n this.iconcolor=this.msg.color;\n }\n }\n },\n }\n</script>\n\n<style>\n .button_Shutter {\n display: grid;\n margin: auto;\n height: 75px;\n width: 75px;\n background-color: #4F4F4F;\n color: #000000;\n border: 1px solid #000000;\n font-size: 14px;\n border-radius: 12px;\n }\n\n .title_Shutter {\n color: white;\n }\n\n/*\n .icon_Shutter {\n font-size: 40px;\n }\n*/\n\n\n\n /*for all icons define icon url and matching button \nbackground color as css variables.*/\n.my_icon_2{\n /*--icon_src: url(\"/static/button/my_icon.svg\");*/\n --icon_src: url(\"/window-shutter-closing.svg\");\n --button_background:#f4900c;\n}\n\n\n/*change the color of the button to match color of icon. optional*/\n.icon_button button{\n background-color: var(--button_background);\n}\n/*make the text to support multiline, change the layout to grid with 2 columns*/\n/*\n.icon_button .v-btn__content{ \n white-space: normal;\n text-wrap:pretty;\n width:100%;\n gap:0.25em;\n display: grid;\n grid-template-columns: calc(var(--v-btn-height)) 1fr;\n}\n*/\n\n/*add the icon to the button using pseudoelement :: before*/\n/*\n.icon_button .v-btn__content::before{\n content:\"\";\n background-image: var(--icon_src);\n min-height:calc(var(--v-btn-height));\n min-width:calc(var(--v-btn-height));\n}\n*/\n.icon_Shutter .v-icon__content::before{\n content:\"\";\n background-image: var(--icon_src);\n min-height:calc(var(--v-icon-height));\n min-width:calc(var(--v-icon-height));\n}\n\n</style>",
"storeOutMessages": true,
"passthru": false,
"resendOnRefresh": true,
"templateScope": "local",
"className": "",
"x": 620,
"y": 1180,
"wires": [
[
"7018959cbe43ea14",
"d3a73654b65867f2",
"8d23580f59ae66a7"
]
]
},
{
"id": "7018959cbe43ea14",
"type": "debug",
"z": "be85a1a7964e5e68",
"name": "debug 27",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 860,
"y": 1140,
"wires": []
},
{
"id": "d3a73654b65867f2",
"type": "function",
"z": "be85a1a7964e5e68",
"name": "simulate end of movement",
"func": "/*\n{\n \"path\": \"/devices/hdm:ZigBee:6c5cb1fffe7540eb/services/ShutterControl\",\n \"operations\": [\"decrementOpenLevel\", \"incrementOpenLevel\"],\n \"@type\": \"DeviceServiceData\",\n \"id\": \"ShutterControl\",\n \"state\": {\n \"delayCompensationTime\": 0.2, \n \"referenceMovingTimes\": { \"movingTimeBottomToTopInMillis\": 19300, \"movingTimeTopToBottomInMillis\": 19300 },\n \"endPositionAutoDetect\": true, \n \"delayCompensationSupported\": true, \n \"level\": 0,\n \"@type\":\"shutterControlState\",\n \"operationState\": \"MOVING\",\n \"endPositionSupported\": true, \n \"automaticDelayCompensation\": true,\n \"calibrated\": true\n }, \n \"deviceId\": \"hdm:ZigBee:6c5cb1fffe7540eb\"\n}\n*/\n\nif (this.msg.payload == undefined) {\n return;\n}\n\n\n\nvar newMsg = { \"payload\": null };\n//newMsg.payload=\"test\";\n//return newMsg\n\nif (msg.payload == \"stop\") {\n newMsg.reset = true;\n}\nelse {\n\n\n newMsg.payload =\n {\n \"path\": \"/devices/hdm:ZigBee:6c5cb1fffe7540eb/services/ShutterControl\",\n \"operations\": [\"decrementOpenLevel\", \"incrementOpenLevel\"],\n \"@type\": \"DeviceServiceData\",\n \"id\": \"ShutterControl\",\n \"state\": {\n \"delayCompensationTime\": 0.2,\n \"referenceMovingTimes\": { \"movingTimeBottomToTopInMillis\": 19300, \"movingTimeTopToBottomInMillis\": 19300 },\n \"endPositionAutoDetect\": true,\n \"delayCompensationSupported\": true,\n \"level\": 0,\n \"@type\": \"shutterControlState\",\n \"operationState\": \"STOPPED\",\n \"endPositionSupported\": true,\n \"automaticDelayCompensation\": true,\n \"calibrated\": true\n },\n \"deviceId\": \"hdm:ZigBee:6c5cb1fffe7540eb\"\n };\n\n\n if (msg.payload == \"close\") {\n newMsg.payload.state.operationState = \"STOPPED\"\n newMsg.payload.state.level = 0;\n }\n if (msg.payload == \"open\") {\n newMsg.payload.state.operationState = \"STOPPED\"\n newMsg.payload.state.level = 1;\n }\n\n\n}\nreturn newMsg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 920,
"y": 1180,
"wires": [
[
"c2ee16235c4fd8f4"
]
]
},
{
"id": "5305e43c8cd9a32c",
"type": "debug",
"z": "be85a1a7964e5e68",
"name": "debug 28",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 1520,
"y": 1180,
"wires": []
},
{
"id": "8d23580f59ae66a7",
"type": "function",
"z": "be85a1a7964e5e68",
"name": "simulate start of movement",
"func": "/*\n{\n \"path\": \"/devices/hdm:ZigBee:6c5cb1fffe7540eb/services/ShutterControl\",\n \"operations\": [\"decrementOpenLevel\", \"incrementOpenLevel\"],\n \"@type\": \"DeviceServiceData\",\n \"id\": \"ShutterControl\",\n \"state\": {\n \"delayCompensationTime\": 0.2, \n \"referenceMovingTimes\": { \"movingTimeBottomToTopInMillis\": 19300, \"movingTimeTopToBottomInMillis\": 19300 },\n \"endPositionAutoDetect\": true, \n \"delayCompensationSupported\": true, \n \"level\": 0,\n \"@type\":\"shutterControlState\",\n \"operationState\": \"MOVING\",\n \"endPositionSupported\": true, \n \"automaticDelayCompensation\": true,\n \"calibrated\": true\n }, \n \"deviceId\": \"hdm:ZigBee:6c5cb1fffe7540eb\"\n}\n*/\n\n\n\nif(this.msg.payload == undefined){\n return;\n}\n\nvar newMsg={\"payload\":null};\n\nnewMsg.payload=\n{\n \"path\": \"/devices/hdm:ZigBee:6c5cb1fffe7540eb/services/ShutterControl\",\n \"operations\": [\"decrementOpenLevel\", \"incrementOpenLevel\"],\n \"@type\": \"DeviceServiceData\",\n \"id\": \"ShutterControl\",\n \"state\": {\n \"delayCompensationTime\": 0.2,\n \"referenceMovingTimes\": { \"movingTimeBottomToTopInMillis\": 19300, \"movingTimeTopToBottomInMillis\": 19300 },\n \"endPositionAutoDetect\": true,\n \"delayCompensationSupported\": true,\n \"level\": 0,\n \"@type\": \"shutterControlState\",\n \"operationState\": \"MOVING\",\n \"endPositionSupported\": true,\n \"automaticDelayCompensation\": true,\n \"calibrated\": true\n },\n \"deviceId\": \"hdm:ZigBee:6c5cb1fffe7540eb\"\n};\n\nif (msg.payload == \"close\")\n{\n newMsg.payload.state.operationState = \"MOVING\"\n newMsg.payload.state.level=0\n}\nif (msg.payload == \"open\")\n{\n newMsg.payload.state.operationState = \"MOVING\"\n newMsg.payload.state.level=1\n}\nif (msg.payload == \"stop\") {\n newMsg.payload.state.operationState = \"STOPPED\"\n newMsg.payload.state.level=0.5\n}\nreturn newMsg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 920,
"y": 1260,
"wires": [
[
"d703d7c03729cecd",
"1119d61bc3d6ac3e"
]
]
},
{
"id": "c2ee16235c4fd8f4",
"type": "delay",
"z": "be85a1a7964e5e68",
"name": "",
"pauseType": "delay",
"timeout": "5",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": false,
"allowrate": false,
"outputs": 1,
"x": 1140,
"y": 1180,
"wires": [
[
"d703d7c03729cecd",
"1139a83f5c6cd6b3"
]
]
},
{
"id": "bfa7290d568fe058",
"type": "comment",
"z": "be85a1a7964e5e68",
"name": "level=0=closed, level=1=open",
"info": "",
"x": 580,
"y": 1140,
"wires": []
},
{
"id": "1139a83f5c6cd6b3",
"type": "function",
"z": "be85a1a7964e5e68",
"name": "function 137",
"func": "\nvar newMsg = {\n \"payload\":\n {\n \"operationState\": msg.payload.state.operationState,\n \"level\": msg.payload.state.level\n }\n}\n\nreturn newMsg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1350,
"y": 1180,
"wires": [
[
"5305e43c8cd9a32c"
]
]
},
{
"id": "1119d61bc3d6ac3e",
"type": "function",
"z": "be85a1a7964e5e68",
"name": "function 138",
"func": "\nvar newMsg = {\n \"payload\":\n {\n \"operationState\": msg.payload.state.operationState,\n \"level\": msg.payload.state.level\n }\n}\n\nreturn newMsg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1350,
"y": 1260,
"wires": [
[
"e2ddb08a302c4dc2"
]
]
},
{
"id": "e2ddb08a302c4dc2",
"type": "debug",
"z": "be85a1a7964e5e68",
"name": "debug 31",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 1520,
"y": 1260,
"wires": []
},
{
"id": "1b676f206101966b",
"type": "ui-group",
"name": "testgroup2",
"page": "be7dc60180b9862f",
"width": "6",
"height": "1",
"order": 3,
"showTitle": false,
"className": "",
"visible": "true",
"disabled": "false"
},
{
"id": "be7dc60180b9862f",
"type": "ui-page",
"name": "Start",
"ui": "91ac914334bc2f74",
"path": "/pageStart",
"icon": "home",
"layout": "grid",
"theme": "713e504734925435",
"order": 2,
"className": "",
"visible": "true",
"disabled": "false"
},
{
"id": "91ac914334bc2f74",
"type": "ui-base",
"name": "My Dashboard",
"path": "/dashboard",
"includeClientData": true,
"acceptsClientConfig": [
"ui-notification",
"ui-control"
],
"showPathInSidebar": false,
"navigationStyle": "default"
},
{
"id": "713e504734925435",
"type": "ui-theme",
"name": "HN Theme",
"colors": {
"surface": "#5c5c5c",
"primary": "#0094ce",
"bgPage": "#383838",
"groupBg": "#4f4f4f",
"groupOutline": "#858585"
},
"sizes": {
"pagePadding": "12px",
"groupGap": "12px",
"groupBorderRadius": "4px",
"widgetGap": "12px"
}
}
]
but to make it easier, I made an example toggle button, which changes the appended icon with its state.
I added the classes to the button and get a static local stored icon prepended to the button,
but I want to change the appended icons dynamically with local stored icons.
![Screenshot-button-icon](https://global.discourse-cdn.com/business6/uploads/nodered/original/3X/9/2/92b77c7f8f528bbd5360fe44bded0c5dc31267bc.jpeg)
[
{
"id": "8fb5da02a6d1981d",
"type": "ui-button",
"z": "675c06697bd9d35c",
"group": "48fc19d1161f11e6",
"name": "",
"label": "My Icon button (Paul-Reed)",
"order": 3,
"width": "4",
"height": "1",
"emulateClick": false,
"tooltip": "",
"color": "",
"bgcolor": "",
"className": "icon_button my_icon",
"icon": "",
"iconPosition": "left",
"payload": "",
"payloadType": "str",
"topic": "topic",
"topicType": "msg",
"x": 220,
"y": 160,
"wires": [
[]
]
},
{
"id": "fa864cf3c7b14005",
"type": "ui-template",
"z": "675c06697bd9d35c",
"group": "",
"page": "19eb6d108e9275e2",
"ui": "",
"name": "",
"order": 0,
"width": 0,
"height": 0,
"head": "",
"format": "/*for all icons define icon url and matching button \nbackground color as css variables.*/\n.my_icon{\n /*--icon_src: url(\"/static/button/my_icon.svg\");*/\n --icon_src: url(\"/window-shutter-closing.svg\");\n --button_background:#f4900c;\n}\n\n\n/*change the color of the button to match color of icon. optional*/\n.icon_button button{\n background-color: var(--button_background);\n}\n/*make the text to support multiline, change the layout to grid with 2 columns*/\n.icon_button .v-btn__content{ \n white-space: normal;\n text-wrap:pretty;\n width:100%;\n gap:0.25em;\n display: grid;\n grid-template-columns: calc(var(--v-btn-height)) 1fr;\n}\n/*add the icon to the button using pseudoelement :: before*/\n.icon_button .v-btn__content::before{\n content:\"\";\n background-image: var(--icon_src);\n min-height:calc(var(--v-btn-height));\n min-width:calc(var(--v-btn-height));\n}",
"storeOutMessages": true,
"passthru": true,
"resendOnRefresh": true,
"templateScope": "page:style",
"className": "",
"x": 170,
"y": 200,
"wires": [
[]
]
},
{
"id": "459d628e7e182030",
"type": "ui-template",
"z": "675c06697bd9d35c",
"group": "48fc19d1161f11e6",
"name": "my ui-template Button",
"order": 0,
"width": 0,
"height": 0,
"head": "",
"format": "<template>\n <div>\n <v-btn class=\"icon_button my_icon\" :append-icon=\"shutter_icon\" @click=\"onClick()\">my ui-template button</v-btn>\n </div>\n</template>\n\n\n<script>\n// <v-btn class=\"icon_button my_icon\" :append-icon=\"shutter_icon\" @click=\"onClick()\">IconButton</v-btn>\n export default {\n data() {\n // define variables available component-wide\n // (in <template> and component functions)\n return {\n count: 0,\n state: false,\n shutter_icon: \"mdi-window-shutter-open\"\n }\n },\n methods: {\n // expose a method to our <template> and Vue Application\n onClick: function () {\n this.count++\n if(this.state==false)\n {\n this.shutter_icon=\"mdi-window-shutter-open\";\n //this.shutter_icon=\"my_icon\"; \n this.state=true; \n \n }\n else\n {\n this.shutter_icon=\"mdi-window-shutter\";\n this.state=false; \n }\n this.send({payload: this.state});\n }\n },\n }\n</script>\n<style>\n\n</style>",
"storeOutMessages": true,
"passthru": true,
"resendOnRefresh": true,
"templateScope": "local",
"className": "",
"x": 500,
"y": 160,
"wires": [
[
"b089902018dfe292"
]
]
},
{
"id": "b089902018dfe292",
"type": "debug",
"z": "675c06697bd9d35c",
"name": "debug 34",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 720,
"y": 160,
"wires": []
},
{
"id": "48fc19d1161f11e6",
"type": "ui-group",
"name": "Test",
"page": "19eb6d108e9275e2",
"width": "20",
"height": "13",
"order": -1,
"showTitle": true,
"className": "",
"visible": "true",
"disabled": "false"
},
{
"id": "19eb6d108e9275e2",
"type": "ui-page",
"name": "Examples",
"ui": "91ac914334bc2f74",
"path": "/examples",
"icon": "",
"layout": "notebook",
"theme": "a965ccfef139317a",
"order": 5,
"className": "",
"visible": "true",
"disabled": "false"
},
{
"id": "91ac914334bc2f74",
"type": "ui-base",
"name": "My Dashboard",
"path": "/dashboard",
"includeClientData": true,
"acceptsClientConfig": [
"ui-notification",
"ui-control"
],
"showPathInSidebar": false,
"navigationStyle": "default"
},
{
"id": "a965ccfef139317a",
"type": "ui-theme",
"name": "Default",
"colors": {
"surface": "#ffffff",
"primary": "#0094ce",
"bgPage": "#eeeeee",
"groupBg": "#ffffff",
"groupOutline": "#cccccc"
},
"sizes": {
"pagePadding": "12px",
"groupGap": "12px",
"groupBorderRadius": "4px",
"widgetGap": "12px"
}
}
]