I created a template node for a custom Toggle switch (based on a standard checkbox) and when the switch is toggled, I'm using the scope object to send a message payload with the new toggle switch state. However, if I have more than one toggle on the same tab, then the others receive the message and get checked/unchecked too (even though they are not connected to each other in the flow).
I also use the ng-checked property to bind the msg.payload to the checkbox checked state and I'm wondering if this might have something to do with it. Here's the code I have so far (inside the template node):
<!-- Script to handle toggle switch events -->
<script type="text/javascript">
var theScope = scope;
function handleChange(e) {
const {checked} = e.target;
theScope.send({payload:checked}) // send back to NR
}
</script>
<center class="toggle-widget"><input type="checkbox" class="toggle" onchange="handleChange(event)" ng-checked="msg.payload"></center>
In case it is relevant, this is the CSS I have for them in a global template node:
<style>
/*--- Toggle Switch CSS --- */
/* Settings */
:root{
/* Standard Toggle */
--tog-scale: 1;
--tog-height: 42px;
--tog-width: 84px;
--tog-knob-diameter: 36px;
--tog-background-inactive: rgb(182, 182, 182);
--tog-background-active: rgb(127, 180, 210);
--tog-knob-color-inactive: rgb(130, 130, 130);
--tog-knob-color-active: rgb(0, 107, 165);
--tog-text-color-inactive: black;
--tog-text-color-active: black;
--tog-text-size: 1rem;
--tog-transition-speed: 0.15s;
/* Power Toggle */
--pwr-tog-scale: 1;
--pwr-tog-height: 42px;
--pwr-tog-width: 84px;
--pwr-tog-knob-diameter: 36px;
--pwr-tog-background-inactive: rgb(182, 182, 182);
--pwr-tog-background-active: rgb(248, 154, 154);
--pwr-tog-knob-color-inactive: rgb(130, 130, 130);
--pwr-tog-knob-color-active: rgb(130, 130, 130); /*rgb(237, 24, 24);*/
--pwr-tog-knob-icon-color-active: orange;
--pwr-tog-knob-icon-color-inactive: lightgray;
--pwr-tog-text-color-inactive: black;
--pwr-tog-text-color-active: black;
--pwr-tog-text-size: 1rem;
--pwr-tog-transition-speed: 0.15s;
}
/* CSS Selector for toggle-widget settings */
.toggle-widget {
display: block;
padding: 0;
}
/* Standard Toggle switch body */
.toggle{
display: block;
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
width: var(--tog-width);
height: var(--tog-height);
background: var(--tog-background-inactive);
border-radius: calc(var(--tog-height) / 2);
position: relative;
transform: scale(var(--tog-scale));
transition-property: background;
transition-duration: var(--tog-transition-speed);
align-self: center;
vertical-align: center !important;
margin: 0px !important;
}
/* Standard Toggle switch knob */
.toggle:before{
content: "";
background: var(--tog-knob-color-inactive);
height: var(--tog-knob-diameter);
width: var(--tog-knob-diameter);
position: absolute;
border-radius: 50%;
top: calc((var(--tog-height) - var(--tog-knob-diameter)) / 2);
left: calc((var(--tog-height) - var(--tog-knob-diameter)) / 2);
transition: all var(--tog-transition-speed);
z-index: 2;
}
/* Standard Toggle switch inactive text */
.toggle:after{
content: "OFF";
position: absolute;
font-size: var(--tog-text-size);
color: var(--tog-text-color-inactive);
font-weight: bold;
top: 50%;
left: 50%;
transform: translate(8%, -43%);
z-index: 1;
}
/* Standard Toggle switch checked state */
.toggle:checked{
background: var(--tog-background-active);
}
/* Standard Toggle Switch Knob offset */
.toggle:checked::before{
background: var(--tog-knob-color-active);
left: calc((var(--tog-height) - var(--tog-knob-diameter)) / 2 + var(--tog-width) - var(--tog-height));
}
/* Standard Toggle Switch Active Text */
.toggle:checked::after{
content: "ON";
left: 5%;
color: var(--tog-text-color-active);
}
/* --- Power Toggle CSS --- */
/* Power Toggle switch body */
.toggle-pwr{
display: block;
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
width: var(--pwr-tog-width);
height: var(--pwr-tog-height);
background: var(--pwr-tog-background-inactive);
border-radius: calc(var(--pwr-tog-height) / 2);
position: relative;
transform: scale(var(--pwr-tog-scale));
transition-property: background;
transition-duration: var(--pwr-tog-transition-speed);
align-self: center;
vertical-align: center !important;
margin: 0px !important;
}
/* Power Toggle switch knob */
.toggle-pwr:before{
display: flex;
align-items: center;
justify-content: center;
font-family: "Material Icons";
content: "\e8ac";
font-size: 2rem;
color: var(--pwr-tog-knob-icon-color-inactive);
/* transition: color .35s ease; */
background: var(--pwr-tog-knob-color-inactive);
height: var(--pwr-tog-knob-diameter);
width: var(--pwr-tog-knob-diameter);
position: absolute;
border-radius: 50%;
top: calc((var(--pwr-tog-height) - var(--pwr-tog-knob-diameter)) / 2);
left: calc((var(--pwr-tog-height) - var(--pwr-tog-knob-diameter)) / 2);
transition: all var(--pwr-tog-transition-speed);
z-index: 2;
}
/* Power Toggle switch inactive text */
.toggle-pwr:after{
content: "OFF";
position: absolute;
font-size: var(--pwr-tog-text-size);
color: var(--pwr-tog-text-color-inactive);
font-weight: bold;
top: 50%;
left: 50%;
transform: translate(8%, -43%);
z-index: 1;
}
/* Power Toggle cwitch checked state */
.toggle-pwr:checked{
background: var(--pwr-tog-background-active);
}
/* Power Toggle Switch Knob offset */
.toggle-pwr:checked::before{
color: var(--pwr-tog-knob-icon-color-active);
/*text-shadow: 0 0 3px var(--pwr-tog-knob-icon-color-active);*/
/*text-shadow: 0 0 2px #fff, 0 0 4px #fff, 0 0 6px #e60073, 0 0 8px #e60073, 0 0 10px #e60073, 0 0 12px #e60073, 0 0 14px #e60073;*/
text-shadow: 0 0 2px var(--pwr-tog-knob-icon-color-active), 0 0 4px var(--pwr-tog-knob-icon-color-active), 0 0 6px #e60073, 0 0 8px #e60073, 0 0 10px #e60073, 0 0 12px #e60073, 0 0 14px #e60073;
background: var(--pwr-tog-knob-color-active);
left: calc((var(--pwr-tog-height) - var(--pwr-tog-knob-diameter)) / 2 + var(--pwr-tog-width) - var(--pwr-tog-height));
}
/* Power Toggle Switch Active Text */
.toggle-pwr:checked::after{
content: "ON";
left: 5%;
color: var(--pwr-tog-text-color-active);
}
</style>
Here's an example flow that illustrates the problem I'm having (also includes the CSS For styling the toggle:
[{"id":"7c16e4a8142cb94d","type":"ui_template","z":"3cf810a76675ef6e","group":"c982fbb8.1deb38","name":"Global Styles","order":2,"width":"0","height":"0","format":"<style>\n /*--- Toggle Switch CSS --- */\n\n /* Settings */\n :root{\n /* Standard Toggle */\n --tog-scale: 1;\n --tog-height: 42px;\n --tog-width: 84px;\n --tog-knob-diameter: 36px;\n --tog-background-inactive: rgb(182, 182, 182);\n --tog-background-active: rgb(127, 180, 210);\n --tog-knob-color-inactive: rgb(130, 130, 130);\n --tog-knob-color-active: rgb(0, 107, 165);\n --tog-text-color-inactive: black;\n --tog-text-color-active: black;\n --tog-text-size: 1rem;\n --tog-transition-speed: 0.15s;\n \n /* Power Toggle */\n --pwr-tog-scale: 1;\n --pwr-tog-height: 42px;\n --pwr-tog-width: 84px;\n --pwr-tog-knob-diameter: 36px;\n --pwr-tog-background-inactive: rgb(182, 182, 182);\n --pwr-tog-background-active: rgb(248, 154, 154);\n --pwr-tog-knob-color-inactive: rgb(130, 130, 130);\n --pwr-tog-knob-color-active: rgb(130, 130, 130); /*rgb(237, 24, 24);*/\n --pwr-tog-knob-icon-color-active: orange;\n --pwr-tog-knob-icon-color-inactive: lightgray;\n --pwr-tog-text-color-inactive: black;\n --pwr-tog-text-color-active: black;\n --pwr-tog-text-size: 1rem;\n --pwr-tog-transition-speed: 0.15s;\n }\n\n /* CSS Selector for toggle-widget settings */\n .toggle-widget {\n display: block;\n padding: 0;\n }\n\n /* Standard Toggle switch body */\n .toggle{\n display: block;\n appearance: none;\n -webkit-appearance: none;\n -moz-appearance: none;\n width: var(--tog-width);\n height: var(--tog-height);\n background: var(--tog-background-inactive);\n border-radius: calc(var(--tog-height) / 2);\n position: relative;\n transform: scale(var(--tog-scale));\n transition-property: background;\n transition-duration: var(--tog-transition-speed);\n align-self: center;\n vertical-align: center !important;\n margin: 0px !important;\n }\n \n /* Standard Toggle switch knob */\n .toggle:before{\n content: \"\";\n background: var(--tog-knob-color-inactive);\n height: var(--tog-knob-diameter);\n width: var(--tog-knob-diameter);\n position: absolute;\n border-radius: 50%;\n top: calc((var(--tog-height) - var(--tog-knob-diameter)) / 2);\n left: calc((var(--tog-height) - var(--tog-knob-diameter)) / 2);\n transition: all var(--tog-transition-speed);\n z-index: 2;\n }\n \n /* Standard Toggle switch inactive text */\n .toggle:after{\n content: \"OFF\";\n position: absolute;\n font-size: var(--tog-text-size);\n color: var(--tog-text-color-inactive);\n font-weight: bold;\n top: 50%;\n left: 50%;\n transform: translate(8%, -43%);\n z-index: 1;\n }\n \n /* Standard Toggle switch checked state */\n .toggle:checked{\n background: var(--tog-background-active);\n }\n \n /* Standard Toggle Switch Knob offset */\n .toggle:checked::before{\n background: var(--tog-knob-color-active);\n left: calc((var(--tog-height) - var(--tog-knob-diameter)) / 2 + var(--tog-width) - var(--tog-height));\n }\n \n /* Standard Toggle Switch Active Text */\n .toggle:checked::after{\n content: \"ON\";\n left: 5%;\n color: var(--tog-text-color-active);\n }\n\n /* --- Power Toggle CSS --- */\n\n /* Power Toggle switch body */\n .toggle-pwr{\n display: block;\n appearance: none;\n -webkit-appearance: none;\n -moz-appearance: none;\n width: var(--pwr-tog-width);\n height: var(--pwr-tog-height);\n background: var(--pwr-tog-background-inactive);\n border-radius: calc(var(--pwr-tog-height) / 2);\n position: relative;\n transform: scale(var(--pwr-tog-scale));\n transition-property: background;\n transition-duration: var(--pwr-tog-transition-speed);\n align-self: center;\n vertical-align: center !important;\n margin: 0px !important;\n }\n \n /* Power Toggle switch knob */\n .toggle-pwr:before{\n display: flex;\n align-items: center;\n justify-content: center;\n font-family: \"Material Icons\";\n content: \"\\e8ac\";\n font-size: 2rem;\n color: var(--pwr-tog-knob-icon-color-inactive);\n /* transition: color .35s ease; */\n background: var(--pwr-tog-knob-color-inactive);\n height: var(--pwr-tog-knob-diameter);\n width: var(--pwr-tog-knob-diameter);\n position: absolute;\n border-radius: 50%;\n top: calc((var(--pwr-tog-height) - var(--pwr-tog-knob-diameter)) / 2);\n left: calc((var(--pwr-tog-height) - var(--pwr-tog-knob-diameter)) / 2);\n transition: all var(--pwr-tog-transition-speed);\n z-index: 2;\n }\n \n /* Power Toggle switch inactive text */\n .toggle-pwr:after{\n content: \"OFF\";\n position: absolute;\n font-size: var(--pwr-tog-text-size);\n color: var(--pwr-tog-text-color-inactive);\n font-weight: bold;\n top: 50%;\n left: 50%;\n transform: translate(8%, -43%);\n z-index: 1;\n }\n \n /* Power Toggle cwitch checked state */\n .toggle-pwr:checked{\n background: var(--pwr-tog-background-active);\n }\n \n /* Power Toggle Switch Knob offset */\n .toggle-pwr:checked::before{\n color: var(--pwr-tog-knob-icon-color-active);\n /*text-shadow: 0 0 3px var(--pwr-tog-knob-icon-color-active);*/\n /*text-shadow: 0 0 2px #fff, 0 0 4px #fff, 0 0 6px #e60073, 0 0 8px #e60073, 0 0 10px #e60073, 0 0 12px #e60073, 0 0 14px #e60073;*/\n text-shadow: 0 0 2px var(--pwr-tog-knob-icon-color-active), 0 0 4px var(--pwr-tog-knob-icon-color-active), 0 0 6px #e60073, 0 0 8px #e60073, 0 0 10px #e60073, 0 0 12px #e60073, 0 0 14px #e60073;\n background: var(--pwr-tog-knob-color-active);\n left: calc((var(--pwr-tog-height) - var(--pwr-tog-knob-diameter)) / 2 + var(--pwr-tog-width) - var(--pwr-tog-height));\n }\n \n /* Power Toggle Switch Active Text */\n .toggle-pwr:checked::after{\n content: \"ON\";\n left: 5%;\n color: var(--pwr-tog-text-color-active);\n }\n</style>\n","storeOutMessages":false,"fwdInMessages":false,"resendOnRefresh":false,"templateScope":"global","className":"","x":270,"y":120,"wires":[[]]},{"id":"c3c49383f852db25","type":"ui_template","z":"3cf810a76675ef6e","group":"329fde9ce45e135e","name":"Toggle Switch","order":14,"width":2,"height":1,"format":"<!-- Script to handle toggle switch events -->\n<script type=\"text/javascript\">\n var theScope = scope;\n\n function handleChange(e) {\n const {checked} = e.target;\n \n //console.log(selected)\n theScope.send({payload:checked}) // send back to NR \n }\n</script>\n\n<center class=\"toggle-widget\"><input type=\"checkbox\" class=\"toggle\" onchange=\"handleChange(event)\" ng-checked=\"msg.payload\"></center>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","className":"toggle-widget","x":340,"y":160,"wires":[["42c1cf91acbc7629"]],"icon":"font-awesome/fa-toggle-on"},{"id":"1688ccbd207675cc","type":"ui_template","z":"3cf810a76675ef6e","group":"329fde9ce45e135e","name":"Power Toggle Switch","order":16,"width":2,"height":1,"format":"<!-- Script to handle toggle switch events -->\n<script type=\"text/javascript\">\n var theScope = scope;\n\n function handleChange(e) {\n const {checked} = e.target;\n \n //console.log(selected)\n theScope.send({payload:checked}) // send back to NR \n }\n</script>\n\n<center><input type=\"checkbox\" class=\"toggle-pwr\" onchange=\"handleChange(event)\" ng-checked=\"msg.payload\"></center>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","className":"toggle-widget","x":360,"y":200,"wires":[["605ebcc899c55a08"]],"icon":"font-awesome/fa-toggle-on"},{"id":"42c1cf91acbc7629","type":"debug","z":"3cf810a76675ef6e","name":"Debug 1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":600,"y":160,"wires":[]},{"id":"605ebcc899c55a08","type":"debug","z":"3cf810a76675ef6e","name":"Debug 2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":600,"y":200,"wires":[]},{"id":"336d4e5a4af5da57","type":"inject","z":"3cf810a76675ef6e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":130,"y":160,"wires":[["c3c49383f852db25"]]},{"id":"39f2422320332f70","type":"inject","z":"3cf810a76675ef6e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"false","payloadType":"bool","x":130,"y":200,"wires":[["c3c49383f852db25"]]},{"id":"c982fbb8.1deb38","type":"ui_group","name":"hidden_group","tab":"7c447e96.4b96a","order":1,"disp":false,"width":"6","collapse":false},{"id":"329fde9ce45e135e","type":"ui_group","name":"Group 1","tab":"8d72c2dc8ebb3926","order":1,"disp":true,"width":6},{"id":"7c447e96.4b96a","type":"ui_tab","name":"Zooland Sys","icon":"home","order":35,"disabled":false,"hidden":false},{"id":"8d72c2dc8ebb3926","type":"ui_tab","z":"36608fa567377833","name":"tab2","icon":"dashboard"}]
In this example, the second toggle is somehow getting the message from the first toggle and switching even though I don't have them connect to each other in the flow. Is there a more appropriate way to do this?