Hi all, What a roller coaster. After two days in the plughole of time (otherwise known as CSS) I have emerged with a massive improvement.
I got there by stripping the new css of all except the essential to the basic function of the latching button style using jsfiddle.
I then removed all unessential css in the css header node and gradually added an element at a time. A bit like walking a tightrope blindfold wearing ice skates.
During the process I have lost other working functions like the radio buttons so the code is a bit of a mess but the CSS styling may be useful.
Thanks for all the help so far, any help with the two radio buttons would be most welcome.
[{"id":"5666698b.c679c8","type":"inject","z":"503e64bc.acab6c","name":" disabled, on 11","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"11","payload":"{\"command\":\"toggleClass\",\"value\":\"disabled\"}","payloadType":"json","x":120,"y":360,"wires":[["d63508d7.9bea48"]]},{"id":"c3be9084.fc1fe","type":"inject","z":"503e64bc.acab6c","name":"9:0","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"9","payload":"0","payloadType":"num","x":90,"y":200,"wires":[["d63508d7.9bea48"]]},{"id":"35d1aadc.5941e6","type":"inject","z":"503e64bc.acab6c","name":"9:1","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"9","payload":"1","payloadType":"num","x":90,"y":240,"wires":[["d63508d7.9bea48"]]},{"id":"2f8b4bb4.988a54","type":"debug","z":"503e64bc.acab6c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":330,"y":400,"wires":[]},{"id":"bef9867d.b18028","type":"ui_template","z":"503e64bc.acab6c","group":"c3500612.c24038","name":":r8g1","order":3,"width":"1","height":1,"format":"<!--\n V1\n ==\n//-->\n<div>\n<md-button class=\"md-button ck-button on off small\" \n data-payload=\"1\" \n data-buttontype=\"radio\"\n data-radiogroup='group1'\n data-topic=\"8\"\n >\n <div class=\"ck-button\">\n <label class=\"ck-switch\">\n <input type=\"checkbox\" unchecked>\n <div style=\"background-color:#cc0000\" class=\"on\">btn<br>on</div>\n <div style=\"background-color:#660000\" class=\"off\">btn<br>off</div>\n </label>\n </div>\n</md-button>\n</div>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":false,"templateScope":"local","x":310,"y":160,"wires":[[]]},{"id":"fdb1290a.963198","type":"ui_template","z":"503e64bc.acab6c","group":"c3500612.c24038","name":"CSS only ","order":2,"width":0,"height":0,"format":"/!--\n\n-->\n<style>\n .nr-dashboard-template {\n padding: 0px;\n }\n .md-button {\n border-radius: 10px;\n }\n .md-button:hover {\n border:1px solid red;\n }\n .bigger{\n font-size:1.5em;\n }\n .bold {\n font-weight:bold;\n }\n /* This is for buttons with a lot of text. `font-size:0.7em` */\n /* makes the font 70% normal size */\n .small{\n font-size:0.7em;\n }\n\n\n /* New ck-button */ \n .ck-button.disabled{\n pointer-events: none;\n opacity: 0.5;\n }\n .ck-switch {\n position: relative;\n }\n \n .ck-switch input {\n display: none;\n }\n \n .off {\n position: absolute;\n top: 0px;\n height: 100%;\n width: 100%;\n opacity: 1;\n }\n .on {\n height: 100%;\n }\n .ck-button input:checked + .on {\n opacity: 1;\n }\n .ck-button input:checked + div + .off {\n opacity: 0;\n }\n \n \n .ck-button {\n margin: -6px;\n padding: 6px;\n width: 100%;\n height: 100%;\n overflow: auto;\n }\n \n .ck-button label {\n height: 100%;\n text-align: center;\n float: left;\n width: 100%;\n }\n \n .ck-button label div {\n margin: -6px;\n padding: 6px;\n text-align: center;\n display: block;\n }\n \n .ck-button label input {\n position: absolute;\n top: -20px;\n }\n .ck-button label div {\n/*ok white-space: normal;*/\nwhite-space:pre-wrap;\n word-break: break-word;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n/*\nHTML\n====\n<div>\n<md-button class=\"md-button ck-button ck-switch on off small\" \n data-payload=\"1\" \n data-buttontype=\"radio\"\n data-radiogroup='group1'\n data-topic=\"8\"\n >\n <div class=\"ck-button\">\n <label class=\"ck-switch\">\n <input type=\"checkbox\" unchecked>\n <div style=\"background-color:#00cc00\" class=\"on\">btn<br>on</div>\n <div style=\"background-color:#006600\" class=\"off\">btn<br>off</div>\n </label>\n </div>\n</md-button>\n</div>\n*/\n\n</style>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":false,"templateScope":"global","x":100,"y":40,"wires":[[]]},{"id":"bc2d0de2.d27c8","type":"comment","z":"503e64bc.acab6c","name":"data-buttontype:checkbox","info":"","x":130,"y":80,"wires":[]},{"id":"ee44ef95.2afab","type":"inject","z":"503e64bc.acab6c","name":"disabled, on 9","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"9","payload":"{\"command\":\"toggleClass\",\"value\":\"disabled\"}","payloadType":"json","x":110,"y":160,"wires":[["d63508d7.9bea48"]]},{"id":"d63508d7.9bea48","type":"ui_template","z":"503e64bc.acab6c","group":"c3500612.c24038","name":"script for all buttons with class .remote-button3x","order":14,"width":"0","height":"0","format":"<div>\n<!--diliberately emtpy - only need the script below -->\n</div>\n\n<script>\n\n(function($scope) {\n//debugger\n\n //cause a small delay while things load \n //ideally this would be an init event or on all parts of document loaded\n //(may not be necessary!)\n setTimeout(function() {\n //debugger\n $scope.init();\n },100);\n \n \n //SETTINGS...\n var BUTTON_CLASS = \".ck-button\";\n var SEND_0_FOR_CLEARED_RADIO_BUTTONS = true;\n var SEND_ONLY_STATE_CHANGES_FOR_RADIO_BUTTONS = true;\n \n \n /** \n * Initialise all buttons with class BUTTON_CLASS\n */\n $scope.init = function () {\n //debugger\n console.log(\"$scope.init called. Adding event handlers to all buttons with class '\" + BUTTON_CLASS + \"'.\");\n var clickButtons = $(BUTTON_CLASS + \":not([data-buttontype='repeater'])\") \n// var clickButtons = $(BUTTON_CLASS) \n clickButtons.click(function(e){\n \n var btn = $(this)\n var type = btn.data(\"buttontype\");//get the button type from attribute data-buttontype=\"xxxxx\"\n var topic = btn.data(\"topic\");//get the topic from attribute data-topic=\"xxxxx\"\n var payload = btn.data(\"payload\");//get the payload from attribute data-payload=\"xxxxx\"\n // debugger\n if(type == \"radio\"){\n setRadioButton(btn, true);\n } else if(type == \"toggle\"){\n var state = btn.data(\"state\") || 0;//get the last state payload from attribute data-state=\"n\"\n var newPayload = state == 1 ? 0 : 1;\n setButtonState(btn,newPayload)\n var tm = {\"type\": type, \"topic\":topic,\"payload\":newPayload, \"event\": \"click\"}\n console.log(\"Sending msg for clicked toggle button\", tm)\n $scope.send(tm)\n } else if(type == \"checkbox\"){\n var group = btn.data(\"radiogroup\") || null;\n var state = btn.data(\"state\") || 0;//get the last state payload from attribute data-state=\"n\"\n var newPayload = state == 1 ? 0 : 1;\n if(group) {\n setRadioButton(btn, true);\n } else {\n setButtonState(btn,newPayload)\n var tm = {\"type\": type, \"topic\":topic,\"payload\":newPayload, \"event\": \"click\"}\n console.log(\"Sending msg for clicked checkbox button\", tm)\n $scope.send(tm)\n }\n } else {\n var sm = {\"class\": BUTTON_CLASS, \"new type\": type, \"topic\":topic,\"payload\":payload, \"event\": \"click\"}\n console.log(\"Sending msg for clicked button\", tm)\n $scope.send(sm)\n }\n });\n var repeatButtons = $(BUTTON_CLASS + \"[data-buttontype='repeater']\") \n repeatButtons.on('mousedown touchstart',function(e) {\n e.preventDefault();\n e.stopPropagation();\n console.log(e.type);//remove me after debugging\n var btn = this;\n var $btn = $(btn);\n if(btn._intervalId) return; //already in operation\n btn._topic = $btn.data(\"topic\");//get the topic from attribute data-topic=\"xxxxx\"\n btn._payload = $btn.data(\"payload\");//get the payload from attribute data-payload=\"xxxxx\"\n btn._interval = $btn.data(\"interval\");//get the desired repeat duration\n if(isNumeric(btn._interval) == false || btn._interval < 1) btn._interval = 300;//prevent zero & non numeric timeout value\n var max = $btn.data(\"max\");//get the max repeat count\n if(isNumeric(max) && max > 0) \n btn._max = parseInt(max);\n else\n btn._max = undefined;\n btn._count = 1;\n $scope.send({\"topic\":btn._topic,\"payload\":btn.payload,\"event\":\"down\", \"count\": btn._count})\n btn._lastevent = \"down\";\n //remove any existing timer\n if(btn._intervalId){\n clearInterval(btn._intervalId);\n btn._intervalId = null;\n }\n //start the timer if conditions are ok\n if(!btn._max || (btn._max && btn._count < btn._max)){\n btn._intervalId = setInterval(function() {\n if(btn._max && btn._count >= btn._max){\n clearInterval(btn._intervalId);\n btn._intervalId = null;\n return;\n } \n btn._count = btn._count + 1;\n $scope.send({\"topic\":btn._topic,\"payload\":btn.payload,\"event\":\"down\", \"count\": btn._count})\n },btn._interval); \n }\n }).on('mouseup blur focusout mouseout touchend',function(e) {\n e.preventDefault();\n e.stopPropagation();\n console.log(e.type);//remove me after debugging\n var btn = this;\n var $btn = $(btn);\n \n //next, if data-fireonup == true, then fire up event\n var sendUpEvent = $btn.data(\"fireonup\") == true;\n if(sendUpEvent && btn._lastevent === \"down\"){\n btn._lastevent = \"up\"\n $scope.send({\"topic\":btn._topic,\"payload\":btn._payload,\"event\":\"up\"})\n }\n \n //finally, if the timer id is still valid, clear it (stop repeater)\n if(btn._intervalId){\n clearInterval(btn._intervalId);//stop timer\n btn._intervalId = null;//clear timer id\n }\n }); \n \n };\n\n //watch for node-red msgs\n $scope.$watch('msg', function(msg) {\n //debugger\n if(!msg){ //if no msg \n console.log(\"$scope.$watch('msg', ...) - msg is empty\");\n return;\n }\n if(!msg.topic){ //if no topic set found\n console.log(\"msg.topic is empty - cannot match this to any button\")\n return; //stop processing!\n }\n var buttonSelector = BUTTON_CLASS + \"[data-topic='\" + msg.topic + \"']\" \n var $btn = $(buttonSelector);//get the button\n if(!$btn.length){ //if no button found\n console.log(buttonSelector + \" not found - cannot set state\")\n return; //stop processing!\n }\n\n if($btn.length > 1){ //if MORE than one button found\n console.log(buttonSelector + \" found more than 1 button - is this intended? Do you have the same data-topic set on multiple buttons?\")\n }\n \n //see if this is a command - if so, process the command\n if(typeof msg.payload === \"object\" && msg.payload.command){\n processCommand($btn, msg.payload)\n return;\n } \n \n if($btn.data(\"buttontype\") === \"radio\"){\n setRadioButton($btn, false);\n }\n if($btn.data(\"buttontype\") === \"toggle\"){\n if(msg.payload == \"1\"){\n setButtonState($btn, 1);\n } else if(msg.payload == \"0\"){\n setButtonState($btn, 0);\n } else {\n console.log(\"Invalid toggle value in msg.payload, cannot set \" + buttonSelector + \". Ensure msg.payload is either 0 or 1\") \n }\n }\n//<md-button class=\"md-button remote-button3x bigger\" \n// data-payload=\"1\" \n// data-buttontype=\"checkbox\"\n// data-topic=\"10\"\n// >\n// <label class=\"remote-button3x-switch\">\n// <input type=\"checkbox\" id=\"10\">\n// <div class=\"remote-button3x-slider round\">\n// <span class=\"remote-button3x-on\">O-N</span><span class=\"remote-button3x-off\">O-F-F</span>\n// </div>\n// </label> \n//</md-button> \n if($btn.data(\"buttontype\") === \"checkbox\"){\n var group = $btn.data(\"radiogroup\");\n var groupBtns = $(\"[data-radiogroup='\"+group+\"']\");\n var m = null;\n if(groupBtns.length>0) {\n setRadioButton($btn, false);\n } else {\n var oldState; \n var $chck=$btn.find(\"input[type=checkbox]\");//get the checkbox\n var $state=$chck.is(\":checked\");\n console.log(\"$chck=\" + $state);\n if(msg.payload == \"1\"){\n if(!$state) {\n $chck.prop('checked',true);\n oldState=setButtonState($btn, 1);\n }\n } else if(msg.payload == \"0\"){\n // Not sure if this can happen ?\n // a click on a radio button is always 1\n if($state) {\n $chck.prop('checked',false);\n oldState=setButtonState($btn, 0);\n }\n // setButtonState($btn, 1);\n } else {\n console.log(\"Invalid checkbox value in msg.payload, cannot set \" + buttonSelector + \". Ensure msg.payload is either 0 or 1\") \n }\n }\n setButtonState($btn, 1);\n }\n\n\n }); \n \n /** \n * helper function to set the correct icon & update the \"data-payload\" memory \n */\n function setButtonState($btn, state){\n console.log(\"setButtonState\", $btn[0], state);\n var oldState = $btn.data(\"state\");\n $btn.data(\"state\", state);//set data-payload to new state value (used as a memory)\n \n //determine the opposite state\n var oppositeState;\n if(state == \"1\" || state === 1){\n state = 1; //normalise to a number\n oppositeState = 0;\n } else {\n state = 0; //normalise to a number\n oppositeState = 1;\n }\n \n var $icon = $btn.find(\"i\"); //get the <i> element\n if(!$icon.length){\n var btntype=$btn.data(\"buttontype\");\n if( btntype !== \"checkbox\") {\n $icon = $btn.find(\"span\"); //get the <span> element instead!\n }\n }\n if(!$icon.length && btntype !== \"checkbox\"){\n console.log(\"<i> or <span> not found inside button - cant toggle the icon!\")\n return oldState;//exit this function - nothing to toggle!\n }\n \n //get the old icon and new icon names\n var oldIcon = $btn.data(\"icon\" + oppositeState); //get icon1 or icon2 depending on oppositeState\n var newIcon = $btn.data(\"icon\" + state); //get icon1 or icon2 depending on newPayload\n \n //if we have newIcon and an actual DOM element ($icon) - update it...\n if(newIcon && $icon.length){\n if(newIcon.includes(\"fa-\")){ \n $icon.removeClass(oldIcon).addClass(newIcon); // fontawesome\n } else { \n $icon.text(newIcon); // MDI\n }\n }\n return oldState;\n }\n\n\n /** \n * helper function \n */\n function setRadioButton($btn, sendMsgs){\n// original\n// var state = btn.data(\"state\") || 0;//get the last state payload from attribute data-state=\"n\"\n// var newPayload = state == 1 ? 0 : 1;\n// setButtonState(btn,newPayload)\n// var tm = {\"type\": type, \"topic\":topic,\"payload\":newPayload, \"event\": \"click\"}\n// console.log(\"Sending msg for clicked checkbox button\", tm)\n// $scope.send(tm)\n// checkbox\n// var oldState; \n// var $chck=$btn.find(\"input[type=checkbox]\");//get the checkbox\n// var $state=$chck.is(\":checked\");\n// console.log(\"$chck=\" + $state);\n// if(msg.payload == \"1\"){\n// if(!$state) {$chck.prop('checked',true);}\n// // setButtonState($btn, 1);\n// } else if(msg.payload == \"0\"){\n// if($state) {$chck.prop('checked',false);}\n// // setButtonState($btn, 1);\n// } else {\n// console.log(\"Invalid checkbox value in msg.payload, cannot set \" + buttonSelector + \". Ensure msg.payload is either 0 or 1\") \n// }\n\n\n\n var $chck=$btn.find(\"input[type=checkbox]\");//get the checkbox\n var topic = $btn.data(\"topic\");//get the topic from attribute data-topic=\"xxxxx\"\n var group = $btn.data(\"radiogroup\");\n var groupBtns = $(\"[data-radiogroup='\"+group+\"']\");\n var m = null;\n for(var i = 0; i < groupBtns.length; i++) {\n var oldState;\n var rb = $(groupBtns[i]);\n if(!rb || !rb.length) continue;\n var t = rb.data(\"topic\");\n if(t == topic) continue;//skip clicked button\n oldState = setButtonState(rb,0);\n if(sendMsgs && SEND_0_FOR_CLEARED_RADIO_BUTTONS) {\n if(SEND_ONLY_STATE_CHANGES_FOR_RADIO_BUTTONS && oldState == 0) continue;\n m = {\"type\": \"checkbox\", \"topic\":t,\"payload\":0, \"event\": \"click\"};\n console.log(\"Sending 0 payload for other radio button in group\", m)\n $scope.send(m);\n }\n }\n if(sendMsgs) {\n// var p = $btn.data(\"payload\");//get the payload from attribute data-payload=\"xxxxx\"\n// var m = {\"type\": \"radio\", \"topic\":topic, \"payload\": p, \"event\": \"click\"};\n var m = {\"type\": \"checkbox\", \"topic\":topic, \"payload\": 1, \"event\": \"click\"};\n console.log(\"Sending msg for radio button\", m)\n $scope.send(m);\n }\n setButtonState($btn,1);//set state of this button\n/*\n setTimeout(function(){\n setButtonState($btn,1);//set state of this button \n },200) \n*/\n }\n \n function processCommand($btn, payload){\n //first check payload is correct format...\n //{\"selector\":\".remote-button3x-on\",\"command\":\"setContent\",\"value\":\"HELLO\"}\n if(!payload || !payload.command || !payload.value){\n console.log(\"Cannot process command. Expected a payload object with .command and .value. \")\n }\n var cmd = payload.command.trim();\n switch(cmd){\n case \"addClass\":\n $btn.addClass(payload.value); //this calls the jquery function by name (specified in .command) on the $btn and passes in .value\n break;\n case \"toggleClass\":\n $btn.toggleClass(payload.value); //this calls the jquery function by name (specified in .command) on the $btn and passes in .value\n break;\n case \"setColour\":\n var spanSelector = payload.selector.trim();\n var $span = $btn.find(spanSelector);//get the span\n console.log(\"$spanBefore=\" + $span.text() + \" $spanBefore=\" + payload.value);\n\n $span.css({\"background-color\": payload.value});\n \n//$btn.text(\"Hello world!\");\n // $btn.toggleClass(payload.value); //this calls the jquery function by name (specified in .command) on the $btn and passes in .value\n break;\n case \"setContent\":\n var spanSelector = payload.selector.trim();\n var $span = $btn.find(spanSelector);//get the span\n console.log(\"$spanBefore=\" + $span.text() + \" $spanBefore=\" + payload.value);\n\n $span.text(payload.value);\n \n//$btn.text(\"Hello world!\");\n // $btn.toggleClass(payload.value); //this calls the jquery function by name (specified in .command) on the $btn and passes in .value\n break;\n case \"removeClass\":\n $btn.removeClass(payload.value); //this calls the jquery function by name (specified in .command) on the $btn and passes in .value\n break;\n default:\n console.log(\"command '\" + payload.command + \"' is not supported\")\n }\n } \n \n /** \n * helper function to determine a value is REALLY a number \n */\n function isNumeric(n){\n if(n === \"\") return false;\n if(n === true || n === false) return false;\n return !isNaN(parseFloat(n)) && isFinite(n);\n }\n \n\n})(scope);\n</script>","storeOutMessages":false,"fwdInMessages":true,"resendOnRefresh":false,"templateScope":"local","x":275,"y":400,"wires":[["2f8b4bb4.988a54"]],"l":false},{"id":"2c95dab1.537be6","type":"inject","z":"503e64bc.acab6c","name":"10:0","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"10","payload":"0","payloadType":"num","x":90,"y":400,"wires":[["d63508d7.9bea48"]]},{"id":"b9742854.b0ff28","type":"inject","z":"503e64bc.acab6c","name":"10:1","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"10","payload":"1","payloadType":"num","x":90,"y":440,"wires":[["d63508d7.9bea48"]]},{"id":"2993cfb3.e315b","type":"inject","z":"503e64bc.acab6c","name":".on 9:button\\non 1","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"9","payload":"{\"selector\":\".on\",\"command\":\"setContent\",\"value\":\"button\\non 1\"}","payloadType":"json","x":130,"y":280,"wires":[["d63508d7.9bea48"]]},{"id":"3be9b0e2.b4ef3","type":"inject","z":"503e64bc.acab6c","name":".off 10:off","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"10","payload":"{\"selector\":\".off\",\"command\":\"setContent\",\"value\":\"off\"}","payloadType":"json","x":100,"y":480,"wires":[["d63508d7.9bea48"]]},{"id":"6395717.4416a9","type":"inject","z":"503e64bc.acab6c","name":".on 9:red","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"9","payload":"{\"selector\":\".on\",\"command\":\"setColour\",\"value\":\"#cc0000\"}","payloadType":"json","x":100,"y":320,"wires":[["d63508d7.9bea48"]]},{"id":"c7b32b4c.bf0798","type":"comment","z":"503e64bc.acab6c","name":"ck-button","info":"","x":320,"y":360,"wires":[]},{"id":"1237f7a0.5cace8","type":"ui_template","z":"503e64bc.acab6c","group":"c3500612.c24038","name":":t9","order":3,"width":"2","height":1,"format":"<!--\n V1\n ==\n data-buttontype='radio'\n data-radiogroup='group1' \n//-->\n<div>\n<md-button class=\"md-button ck-button on off\" \n data-payload=\"1\" \n data-buttontype=\"checkbox\"\n data-topic=\"9\"\n >\n <div class=\"ck-button\">\n <label class=\"ck-switch\">\n <input type=\"checkbox\" checked>\n <div style=\"background-color:#00cc00\" class=\"on\">9:1<br>on</div>\n <div style=\"background-color:#006600\" class=\"off\">9:0<br>off</div>\n </label>\n </div>\n</md-button>\n</div>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":false,"templateScope":"local","x":310,"y":200,"wires":[[]]},{"id":"bb33fa8e.a48f68","type":"ui_template","z":"503e64bc.acab6c","group":"c3500612.c24038","name":"c11g1","order":3,"width":"1","height":"3","format":"<!--\n V1\n ==\n//-->\n<div>\n<md-button class=\"md-button ck-button on off small\" \n data-payload=\"1\" \n data-state=\"1\" \n data-buttontype=\"checkbox\"\n data-radiogroup='group1'\n data-topic=\"11\"\n >\n <div class=\"ck-button\">\n <label class=\"ck-switch\">\n <input type=\"checkbox\" unchecked>\n <div style=\"background-color:#097479);\" class=\"on\">radio<br>group1<br><br>btn 11<br>with a lot more text fun<br>on</div>\n <div style=\"background-color:#003333;\" class=\"off\">radio<br>group1<br><br>btn 11<br>off</div>\n </label>\n </div>\n</md-button>\n</div>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":false,"templateScope":"local","x":70,"y":600,"wires":[[]]},{"id":"b856ea19.2280f8","type":"ui_template","z":"503e64bc.acab6c","group":"c3500612.c24038","name":":r10g1","order":3,"width":"2","height":"2","format":"<!--\n V1\n ==\n <div class=\"ck-button\">\n <label class=\"ck-switch\">\n <input type=\"checkbox\">\n <span style=\"background-color:#0000ff\" class=\"on\">11:1</span>\n <span style=\"background-color:#000066\" class=\"off\">11:0</span>\n </label>\n </div>\n \n//-->\n<div>\n<md-button class=\"md-button ck-button on off bigger bold\" \n data-payload=\"1\" \n data-buttontype=\"checkbox\"\n data-topic=\"10\"\n >\n\n <div class=\"ck-button\">\n <label class=\"ck-switch\">\n <input type=\"checkbox\">\n <div style=\"background-color:#0000ff\" class=\"on\">10:1<br>on</div>\n <div style=\"background-color:#000066\" class=\"off\">10:0<br>off</div>\n </label>\n </div>\n</md-button>\n</div>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":false,"templateScope":"local","x":310,"y":240,"wires":[[]]},{"id":"eacf7593.fa2ca8","type":"ui_button","z":"503e64bc.acab6c","name":"","group":"c3500612.c24038","order":6,"width":"2","height":"2","passthru":false,"label":"button","tooltip":"","color":"","bgcolor":"","icon":"","payload":"","payloadType":"str","topic":"","x":310,"y":280,"wires":[[]]},{"id":"b6aa0725.b2a758","type":"ui_template","z":"503e64bc.acab6c","group":"c3500612.c24038","name":"r12g1","order":3,"width":"2","height":"2","format":"<!--\n V1\n ==\n//-->\n<div>\n<md-button class=\"md-button ck-button on off small\" \n data-payload=\"1\" \n data-state=\"1\" \n data-buttontype=\"checkbox\"\n data-radiogroup='group1'\n data-topic=\"12\"\n >\n <div class=\"ck-button\">\n <label class=\"ck-switch\">\n <input type=\"checkbox\" unchecked>\n <div style=\"background-color:#00aaaa\" class=\"on\">radio<br>group1<br><br>btn 12 with a lot morrrrrrrrrrrrrrrrrrrre text fun<br>on</div>\n <div style=\"background-color:#097479\" class=\"off\">radio<br>group1<br><br>btn 12<br>off</div>\n </label>\n </div>\n</md-button>\n</div>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":false,"templateScope":"local","x":210,"y":600,"wires":[[]]},{"id":"b2e90b1c.78bbc8","type":"comment","z":"503e64bc.acab6c","name":"data-buttontype:checkbox group1","info":"","x":150,"y":520,"wires":[]},{"id":"d706e1b9.853eb","type":"inject","z":"503e64bc.acab6c","name":"11:0","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"11","payload":"0","payloadType":"num","x":90,"y":640,"wires":[["d63508d7.9bea48"]]},{"id":"a61d6558.bdbe58","type":"inject","z":"503e64bc.acab6c","name":"11:1","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"11","payload":"1","payloadType":"num","x":90,"y":680,"wires":[["d63508d7.9bea48"]]},{"id":"731bf5a.fa03a0c","type":"inject","z":"503e64bc.acab6c","name":"12:0","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"12","payload":"0","payloadType":"num","x":230,"y":640,"wires":[["d63508d7.9bea48"]]},{"id":"dfbdd891.b006e8","type":"inject","z":"503e64bc.acab6c","name":"12:1","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"12","payload":"1","payloadType":"num","x":230,"y":680,"wires":[["d63508d7.9bea48"]]},{"id":"23ffa11f.b1acfe","type":"comment","z":"503e64bc.acab6c","name":"Disable/enable, change on/off text and on/off colour","info":"","x":210,"y":120,"wires":[]},{"id":"2eaffa84.972856","type":"comment","z":"503e64bc.acab6c","name":"Work in progress","info":"","x":100,"y":560,"wires":[]},{"id":"c3500612.c24038","type":"ui_group","z":"","name":"Btn2","tab":"94f74e9f.6a717","order":1,"disp":true,"width":"4","collapse":false},{"id":"94f74e9f.6a717","type":"ui_tab","z":"503e64bc.acab6c","name":"TEST","icon":"dashboard","order":7,"disabled":false,"hidden":false}]