Get input to HTML,CSS,JS Webpage

Hi i got help Recently to get an output from my Node Red Webpage.

Now i try to find a Solution to get an Input from Node Red to my Homepage to change my Nav Bar Position.

On my Webpage when i click for example at "Home" i get an output to Node Red "m-home"

Now i try to send for example "m-favorites" and let the Nav Bar jump to "Favorites" may someone know how i could do that?

[
    {
        "id": "8ad58918.ee8168",
        "type": "http in",
        "z": "b90548eaef2af54d",
        "name": "",
        "url": "/mysite",
        "method": "get",
        "upload": false,
        "swaggerDoc": "",
        "x": 810,
        "y": 300,
        "wires": [
            [
                "4c783328.03dc2c"
            ]
        ]
    },
    {
        "id": "7a857226.0a6bec",
        "type": "http in",
        "z": "b90548eaef2af54d",
        "name": "",
        "url": "/mysitepost",
        "method": "post",
        "upload": false,
        "swaggerDoc": "",
        "x": 820,
        "y": 500,
        "wires": [
            [
                "ae61b4ee683c34a4",
                "20480b13.afdb94"
            ]
        ]
    },
    {
        "id": "20480b13.afdb94",
        "type": "debug",
        "z": "b90548eaef2af54d",
        "name": "mysitepost",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1070,
        "y": 800,
        "wires": []
    },
    {
        "id": "2a90cbb3.d07964",
        "type": "http response",
        "z": "b90548eaef2af54d",
        "name": "",
        "statusCode": "",
        "headers": {},
        "x": 1470,
        "y": 500,
        "wires": []
    },
    {
        "id": "e9a9f9c6.f8ce08",
        "type": "template",
        "z": "b90548eaef2af54d",
        "name": "CSS",
        "field": "payload.style",
        "fieldType": "msg",
        "format": "html",
        "syntax": "mustache",
        "template": ":root {\n\t--icon: #b0bfd8;\n}\n\nbody {\n\twidth: 100%;\n\theight: 100vh;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\toverflow: hidden;\n\tmargin: 0;\n\tbackground-color: #e3efe8;\n\tbackground-image: linear-gradient(315deg, #e3efe8 0%, #96a7cf 74%);\n}\n\n\nnav.menu {\n\tdisplay: flex;\n\tjustify-content: space-between;\n\tposition: relative;\n\theight: 150px;\n\tpadding: 0 29px 10px;\n\tbackground: #fff0;\n\talign-items: flex-end;\n\twidth: 700px;\n}\n\nnav.menu:before {\n\tcontent: \"\";\n\twidth: 100%;\n\theight: 150px;\n\tbackground: #181818;\n\tposition: absolute;\n\tleft: 0;\n\tbottom: 0;\n\tborder-radius: 20px;\n\tz-index: -1;\n\tbox-shadow: 1px 1px 2px 0px #fff;\n}\n\ninput { display: none; }\n\n.break {\n  flex-basis: 100%;\n  height: 0;\n}\n\nlabel {\n\ttext-decoration: none;\n\tfont-family: sans-serif;\n\ttext-transform: uppercase;\n\tfont-size: 14px;\n\tmin-width: 100px;\n\theight: 100px;\n\tmargin: 10px 10px 20px;\n\ttext-align: center;\n\tdisplay: inline-grid;\n\talign-items: end;\n\tcolor: #b0bfd8;\n\tposition: relative;\n\ttransition: all 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55) 0s;\n\tcursor: pointer;\n}\n\nlabel:hover {\n\tcolor: #fff;\n\ttext-shadow: 0 0 5px #fff, 0 0 10px #fff;\n}\n\ninput:checked + label {\n\tcolor: #fff;\n\theight: 130px;\n}\n\n.selector {\n\t--hole: #2196f3;\n\tbackground: \n\t\tradial-gradient(circle at 50% 50%, #fff8 30px, #fff0 45px, #fff 50px, #fff0 50px 100%), \n\t\tradial-gradient(circle at 50% 50%, var(--hole) 0 45px, #fff0 50px 100%),\n\t\tradial-gradient(circle at 50% 75px, #181818 0 70px, #fff0 71px 100%);\n\twidth: 95px;\n\theight: 95px;\n\tposition: absolute;\n\tbottom: 47px;\n\tleft: 0;\n\tz-index: -1;\n\ttransition: all 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55) 0s;\n\tborder: 19px solid #181818;\n\tborder-radius: 100%;\n}\n\n#m-home:checked ~ .selector {\n\tleft: 23px;\n}\n\n#m-search:checked ~ .selector {\n\tleft: 143px;\n\tfilter: hue-rotate(535deg);\n}\n\n#m-notification:checked ~ .selector {\n\tleft: 263px;\n\tfilter: hue-rotate(950deg);\n}\n\n#m-favorites:checked ~ .selector {\n\tleft: 383px;\n\tfilter: hue-rotate(1580deg);\n}\n\n#m-profile:checked ~ .selector {\n\tleft: 502px;\n\tfilter: hue-rotate(1850deg);\n}\n\n#m-profile2:checked ~ .selector {\n\tleft: 621px;\n\tfilter: hue-rotate(1850deg);\n}\n\n.selector:after {\n\tcontent: \"\";\n\tposition: absolute;\n\tbottom: -80px;\n\twidth: 80px;\n\theight: 10px;\n\tbackground: #181818;\n\tleft: calc(50% - 40px);\n\tborder-radius: 5px 5px 15px 15px;\n}\n\ninput:checked ~ .selector:after {\n\tbox-shadow: 0 -17px 35px 8px var(--hole);\n}\n\n\n\n\n\n\n\n/*** ICONS ***/\nlabel:before,\nlabel:after {\n\tcontent: \"\";\n\tposition: absolute;\n\tbox-sizing: border-box;\n\ttransition: all 0.5s ease 0s;\n}\n\nlabel:hover:before,\nlabel:hover:after {\n\tfilter: brightness(1.5) drop-shadow(0px 0px 4px #fff);\n\ttransition: all 0.5s ease 0s;\n}\n\ninput:checked + label:before, \ninput:checked + label:after {\n\tfilter: brightness(1.5) drop-shadow(0px 0px 2px var(--sel));\n\ttransition: all 0.5s ease 0s;\n}\n\n\nlabel[for=m-home]:before {\n\twidth: 40px;\n\theight: 40px;\n\tleft: 30px;\n\ttop: 30px;\n\ttransition: all 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55) 0s;\n\tborder-radius: 2px;\n\tbackground: \n\t\tconic-gradient(from 90deg at 65% 60%, var(--icon) 0 25%, #fff0 0 100%),\n\t\tconic-gradient(from 180deg at 35% 60%, var(--icon) 0 25%, #fff0 0 100%),\n\t\tconic-gradient(from 135deg at 50% 0%, var(--icon) 0 25%, #fff0 0 100%);\n\tbackground-repeat: no-repeat;\n\tbackground-size: 100% 100%, 100% 100%, 100% 27px;\n}\n\nlabel[for=m-home]:after {\n\twidth: 40px;\n\theight: 40px;\n\tleft: 30px;\n\ttop: 24px;\n\tborder: 6px solid var(--icon);\n\tborder-right-width: 0;\n\tborder-bottom-width: 0;\n\ttransform: rotate(45deg);\n\tborder-radius: 5px;\n\ttransition: all 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55) 0s;\n}\n\n\nlabel[for=m-search]:before {\n\twidth: 40px;\n\theight: 40px;\n\tleft: 20px;\n\ttop: 17px;\n\tborder: 6px solid var(--icon);\n\tborder-radius: 100%;\n\ttransition: all 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55) 0s;\n}\n\nlabel[for=m-search]:after {\n\twidth: 22px;\n\theight: 9px;\n\tleft: 60px;\n\ttop: 50px;\n\ttransition: all 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55) 0s;\n\tbackground: var(--icon);\n\ttransform-origin: left top;\n\ttransform: rotate(45deg);\n\tborder-radius: 0 10px 10px 0;\n}\n\n\nlabel[for=m-notification]:before {\n\twidth: 50px;\n\theight: 42px;\n\tleft: 25px;\n\ttop: 20px;\n\tz-index: 1;\n\tborder-radius: 30px 30px 0 0;\n\ttransition: all 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55) 0s;\n\tbackground: \n\t\tlinear-gradient(90deg, #fff0 0 6px, var(--icon) 0 calc(100% - 6px), #fff0 calc(100% - 6px) 100%), \n\t\tconic-gradient(from 135deg at 50% 33%, var(--icon) 0 25%, #fff0 0 100%);\n}\n\nlabel[for=m-notification]:after {\n\twidth: 10px;\n\theight: 57px;\n\tleft: 45px;\n\ttop: 14px;\n\tz-index: 0;\n\ttransition: all 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55) 0s;\n\tbackground: radial-gradient(circle at 50% 6px, var(--icon) 3px, #fff0 4px 100%), #fff0;\n\ttransform-origin: left top;\n\tborder-bottom: 6px solid var(--icon);\n\tborder-radius: 5px;\n}\n\n\nlabel[for=m-favorites]:before {\n\twidth: 50px;\n\theight: 50px;\n\tleft: 18px;\n\ttop: -9px;\n\ttransition: all 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55) 0s;\n\tbackground: \n\t\tradial-gradient(circle at 16px 16px, var(--icon) 0 16px, #fff0 calc(16px + 1px) 100%), \n\t\tradial-gradient(circle at 34px 34px, var(--icon) 0 16px, #fff0 calc(16px + 1px) 100%), \n\t\tlinear-gradient(45deg, var(--icon) 0 37px, #fff0 38px 100%);\n\tborder-radius: 17px 22px 17px 4px;\n\ttransform: rotate(-45deg);\n\ttransform-origin: center right;\n}\n\n\nlabel[for=m-profile]:before {\n\twidth: 50px;\n\theight: 54px;\n\ttop: 16px;\n\tbackground: \n\t\tradial-gradient(circle at 50% 15px, var(--icon) 0 12px, #fff0 13px 100%),\n\t\tradial-gradient(circle at 50% 100%, var(--icon) 0 22px, #fff0 23px 100%);\n\tleft: 25px;\n\tborder-radius: 8px;\n}\n\nlabel[for=m-profile2]:before {\n\twidth: 50px;\n\theight: 54px;\n\ttop: 16px;\n\tbackground: \n\t\tradial-gradient(circle at 50% 15px, var(--icon) 0 12px, #fff0 13px 100%),\n\t\tradial-gradient(circle at 50% 100%, var(--icon) 0 22px, #fff0 23px 100%);\n\tleft: 25px;\n\tborder-radius: 8px;\n}\n\n\ninput:checked + label {\n\tcolor: var(--sel);\n\ttext-shadow: 0 0 5px var(--sel), 0 0 10px var(--sel);\n}\t\n\ninput:checked + label[for=m-home] {\n\t--sel: #39a1f4;\n}\n\ninput:checked + label[for=m-search] {\n\t--sel:  #f48d4e;\n}\n\ninput:checked + label[for=m-notification] {\n\t--sel:  #84a91c;\n}\n\ninput:checked + label[for=m-favorites] {\n\t--sel:  #ff6275;\n\theight: 125px;\n}\n\ninput:checked + label[for=m-profile] {\n\t--sel:  #9d74ff;\n}\n\ninput:checked + label[for=m-profile2] {\n\t--sel:  #9d74ff;\n}\n\n@media only screen and (orientation: portrait) {\n\tlabel { color: transparent !important; text-shadow: none !important;}\n}",
        "x": 1390,
        "y": 400,
        "wires": [
            [
                "6d0947c7.d0d4d8"
            ]
        ]
    },
    {
        "id": "61dbe146.63894",
        "type": "template",
        "z": "b90548eaef2af54d",
        "name": "JavaScript",
        "field": "payload.script",
        "fieldType": "msg",
        "format": "javascript",
        "syntax": "plain",
        "template": "const menu = document.getElementById('m');\nconst items =[\"m-home\", \"m-search\", \"m-notification\", \"m-favorites\", \"m-profile\", \"m-profile2\"];\n\nconst listener = async function(evt){\n    if(items.includes(evt.target.id)){\n        let obj;\n        const url = origin + '/mysitepost';\n        fetch(url, {\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/json',\n            },\n            body: JSON.stringify({\"item\":evt.target.id}),\n        })\n        .then(res => res.json())\n        .then(data => obj = data)\n        .then(() => {\n            document.getElementById('log').innerHTML = obj.content;\n            console.log(obj);\n        })\n        .catch(err => console.error(err))\n    }\n}\n\nmenu.addEventListener('click', e => listener(e), false);\n\n\n\n",
        "x": 1210,
        "y": 400,
        "wires": [
            [
                "e9a9f9c6.f8ce08"
            ]
        ]
    },
    {
        "id": "c96f4682.70c4f8",
        "type": "http response",
        "z": "b90548eaef2af54d",
        "name": "",
        "statusCode": "",
        "headers": {},
        "x": 1690,
        "y": 400,
        "wires": []
    },
    {
        "id": "6d0947c7.d0d4d8",
        "type": "template",
        "z": "b90548eaef2af54d",
        "name": "HTML",
        "field": "payload",
        "fieldType": "msg",
        "format": "handlebars",
        "syntax": "mustache",
        "template": "<html>\n  <head>\n\n    <style>{{{payload.style}}}</style>\n </head>\n <body>\n<div>\n<div style=\"flex-direction: column;\">\n<nav class=\"menu\" id=\"m\">\n\n\t<input type=\"radio\" name=\"nav-item\" id=\"m-home\" checked><label for=\"m-home\">Home</label>\n\t<input type=\"radio\" name=\"nav-item\" id=\"m-search\"><label for=\"m-search\">Search</label>\n\t<input type=\"radio\" name=\"nav-item\" id=\"m-notification\"><label for=\"m-notification\">Notification</label>\n\t<input type=\"radio\" name=\"nav-item\" id=\"m-favorites\"><label for=\"m-favorites\">Favorites</label>\n\t<input type=\"radio\" name=\"nav-item\" id=\"m-profile\"><label for=\"m-profile\">Profile</label>\n\t\t<input type=\"radio\" name=\"nav-item\" id=\"m-profile2\"><label for=\"m-profile2\">Profile2</label>\n\n\t<div class=\"selector\"></div>\n</nav>\n</div>\n\n<div id=\"log\"><br>initial content</div>\n</div>\n<script>{{{payload.script}}}</script>\n</body>",
        "x": 1550,
        "y": 400,
        "wires": [
            [
                "c96f4682.70c4f8"
            ]
        ]
    },
    {
        "id": "4c783328.03dc2c",
        "type": "function",
        "z": "b90548eaef2af54d",
        "name": "msg.url = \"mysitepost\";",
        "func": "msg.url = \"mysitepost\";\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 1060,
        "y": 300,
        "wires": [
            [
                "61dbe146.63894"
            ]
        ]
    },
    {
        "id": "ae61b4ee683c34a4",
        "type": "function",
        "z": "b90548eaef2af54d",
        "name": "return msg.payload to client",
        "func": "msg.payload.message = \"The included data was submitted and available in the msg.payload!\";\nmsg.payload.content = '<br>Some ' + msg.payload.item + ' content!';\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1080,
        "y": 500,
        "wires": [
            [
                "20480b13.afdb94",
                "2a90cbb3.d07964"
            ]
        ]
    }
]

This is my Flow this creates the Web page at localhost:1880/mysite

Thx for Help

I recommend installing node-red-contrib-uibuilder
here is some more info about it: node-red-contrib-uibuilder (node) - Node-RED

You can do so much more with it, than the way your flow is set up now.

1 Like

your problem is that the normal http-communication is always triggered by the browser client. To get messages triggered by the server you need to instantiate a websocket. Here is your code extended by a websocket. But be careful, because to send messages to a special browser you need to use its socket id (watch the results from the debug node).

[
    {
        "id": "ca3e3633fc572ae8",
        "type": "tab",
        "label": "Flow 2",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "8ad58918.ee8168",
        "type": "http in",
        "z": "ca3e3633fc572ae8",
        "name": "",
        "url": "/mysite",
        "method": "get",
        "upload": false,
        "swaggerDoc": "",
        "x": 790,
        "y": 360,
        "wires": [
            [
                "4c783328.03dc2c"
            ]
        ]
    },
    {
        "id": "7a857226.0a6bec",
        "type": "http in",
        "z": "ca3e3633fc572ae8",
        "name": "",
        "url": "/mysitepost",
        "method": "post",
        "upload": false,
        "swaggerDoc": "",
        "x": 780,
        "y": 460,
        "wires": [
            [
                "ae61b4ee683c34a4"
            ]
        ]
    },
    {
        "id": "2a90cbb3.d07964",
        "type": "http response",
        "z": "ca3e3633fc572ae8",
        "name": "",
        "statusCode": "",
        "headers": {},
        "x": 1730,
        "y": 460,
        "wires": []
    },
    {
        "id": "e9a9f9c6.f8ce08",
        "type": "template",
        "z": "ca3e3633fc572ae8",
        "name": "CSS",
        "field": "payload.style",
        "fieldType": "msg",
        "format": "html",
        "syntax": "mustache",
        "template": ":root {\n\t--icon: #b0bfd8;\n}\n\nbody {\n\twidth: 100%;\n\theight: 100vh;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\toverflow: hidden;\n\tmargin: 0;\n\tbackground-color: #e3efe8;\n\tbackground-image: linear-gradient(315deg, #e3efe8 0%, #96a7cf 74%);\n}\n\n\nnav.menu {\n\tdisplay: flex;\n\tjustify-content: space-between;\n\tposition: relative;\n\theight: 150px;\n\tpadding: 0 29px 10px;\n\tbackground: #fff0;\n\talign-items: flex-end;\n\twidth: 700px;\n}\n\nnav.menu:before {\n\tcontent: \"\";\n\twidth: 100%;\n\theight: 150px;\n\tbackground: #181818;\n\tposition: absolute;\n\tleft: 0;\n\tbottom: 0;\n\tborder-radius: 20px;\n\tz-index: -1;\n\tbox-shadow: 1px 1px 2px 0px #fff;\n}\n\ninput { display: none; }\n\n.break {\n  flex-basis: 100%;\n  height: 0;\n}\n\nlabel {\n\ttext-decoration: none;\n\tfont-family: sans-serif;\n\ttext-transform: uppercase;\n\tfont-size: 14px;\n\tmin-width: 100px;\n\theight: 100px;\n\tmargin: 10px 10px 20px;\n\ttext-align: center;\n\tdisplay: inline-grid;\n\talign-items: end;\n\tcolor: #b0bfd8;\n\tposition: relative;\n\ttransition: all 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55) 0s;\n\tcursor: pointer;\n}\n\nlabel:hover {\n\tcolor: #fff;\n\ttext-shadow: 0 0 5px #fff, 0 0 10px #fff;\n}\n\ninput:checked + label {\n\tcolor: #fff;\n\theight: 130px;\n}\n\n.selector {\n\t--hole: #2196f3;\n\tbackground: \n\t\tradial-gradient(circle at 50% 50%, #fff8 30px, #fff0 45px, #fff 50px, #fff0 50px 100%), \n\t\tradial-gradient(circle at 50% 50%, var(--hole) 0 45px, #fff0 50px 100%),\n\t\tradial-gradient(circle at 50% 75px, #181818 0 70px, #fff0 71px 100%);\n\twidth: 95px;\n\theight: 95px;\n\tposition: absolute;\n\tbottom: 47px;\n\tleft: 0;\n\tz-index: -1;\n\ttransition: all 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55) 0s;\n\tborder: 19px solid #181818;\n\tborder-radius: 100%;\n}\n\n#m-home:checked ~ .selector {\n\tleft: 23px;\n}\n\n#m-search:checked ~ .selector {\n\tleft: 143px;\n\tfilter: hue-rotate(535deg);\n}\n\n#m-notification:checked ~ .selector {\n\tleft: 263px;\n\tfilter: hue-rotate(950deg);\n}\n\n#m-favorites:checked ~ .selector {\n\tleft: 383px;\n\tfilter: hue-rotate(1580deg);\n}\n\n#m-profile:checked ~ .selector {\n\tleft: 502px;\n\tfilter: hue-rotate(1850deg);\n}\n\n#m-profile2:checked ~ .selector {\n\tleft: 621px;\n\tfilter: hue-rotate(1850deg);\n}\n\n.selector:after {\n\tcontent: \"\";\n\tposition: absolute;\n\tbottom: -80px;\n\twidth: 80px;\n\theight: 10px;\n\tbackground: #181818;\n\tleft: calc(50% - 40px);\n\tborder-radius: 5px 5px 15px 15px;\n}\n\ninput:checked ~ .selector:after {\n\tbox-shadow: 0 -17px 35px 8px var(--hole);\n}\n\n\n\n\n\n\n\n/*** ICONS ***/\nlabel:before,\nlabel:after {\n\tcontent: \"\";\n\tposition: absolute;\n\tbox-sizing: border-box;\n\ttransition: all 0.5s ease 0s;\n}\n\nlabel:hover:before,\nlabel:hover:after {\n\tfilter: brightness(1.5) drop-shadow(0px 0px 4px #fff);\n\ttransition: all 0.5s ease 0s;\n}\n\ninput:checked + label:before, \ninput:checked + label:after {\n\tfilter: brightness(1.5) drop-shadow(0px 0px 2px var(--sel));\n\ttransition: all 0.5s ease 0s;\n}\n\n\nlabel[for=m-home]:before {\n\twidth: 40px;\n\theight: 40px;\n\tleft: 30px;\n\ttop: 30px;\n\ttransition: all 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55) 0s;\n\tborder-radius: 2px;\n\tbackground: \n\t\tconic-gradient(from 90deg at 65% 60%, var(--icon) 0 25%, #fff0 0 100%),\n\t\tconic-gradient(from 180deg at 35% 60%, var(--icon) 0 25%, #fff0 0 100%),\n\t\tconic-gradient(from 135deg at 50% 0%, var(--icon) 0 25%, #fff0 0 100%);\n\tbackground-repeat: no-repeat;\n\tbackground-size: 100% 100%, 100% 100%, 100% 27px;\n}\n\nlabel[for=m-home]:after {\n\twidth: 40px;\n\theight: 40px;\n\tleft: 30px;\n\ttop: 24px;\n\tborder: 6px solid var(--icon);\n\tborder-right-width: 0;\n\tborder-bottom-width: 0;\n\ttransform: rotate(45deg);\n\tborder-radius: 5px;\n\ttransition: all 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55) 0s;\n}\n\n\nlabel[for=m-search]:before {\n\twidth: 40px;\n\theight: 40px;\n\tleft: 20px;\n\ttop: 17px;\n\tborder: 6px solid var(--icon);\n\tborder-radius: 100%;\n\ttransition: all 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55) 0s;\n}\n\nlabel[for=m-search]:after {\n\twidth: 22px;\n\theight: 9px;\n\tleft: 60px;\n\ttop: 50px;\n\ttransition: all 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55) 0s;\n\tbackground: var(--icon);\n\ttransform-origin: left top;\n\ttransform: rotate(45deg);\n\tborder-radius: 0 10px 10px 0;\n}\n\n\nlabel[for=m-notification]:before {\n\twidth: 50px;\n\theight: 42px;\n\tleft: 25px;\n\ttop: 20px;\n\tz-index: 1;\n\tborder-radius: 30px 30px 0 0;\n\ttransition: all 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55) 0s;\n\tbackground: \n\t\tlinear-gradient(90deg, #fff0 0 6px, var(--icon) 0 calc(100% - 6px), #fff0 calc(100% - 6px) 100%), \n\t\tconic-gradient(from 135deg at 50% 33%, var(--icon) 0 25%, #fff0 0 100%);\n}\n\nlabel[for=m-notification]:after {\n\twidth: 10px;\n\theight: 57px;\n\tleft: 45px;\n\ttop: 14px;\n\tz-index: 0;\n\ttransition: all 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55) 0s;\n\tbackground: radial-gradient(circle at 50% 6px, var(--icon) 3px, #fff0 4px 100%), #fff0;\n\ttransform-origin: left top;\n\tborder-bottom: 6px solid var(--icon);\n\tborder-radius: 5px;\n}\n\n\nlabel[for=m-favorites]:before {\n\twidth: 50px;\n\theight: 50px;\n\tleft: 18px;\n\ttop: -9px;\n\ttransition: all 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55) 0s;\n\tbackground: \n\t\tradial-gradient(circle at 16px 16px, var(--icon) 0 16px, #fff0 calc(16px + 1px) 100%), \n\t\tradial-gradient(circle at 34px 34px, var(--icon) 0 16px, #fff0 calc(16px + 1px) 100%), \n\t\tlinear-gradient(45deg, var(--icon) 0 37px, #fff0 38px 100%);\n\tborder-radius: 17px 22px 17px 4px;\n\ttransform: rotate(-45deg);\n\ttransform-origin: center right;\n}\n\n\nlabel[for=m-profile]:before {\n\twidth: 50px;\n\theight: 54px;\n\ttop: 16px;\n\tbackground: \n\t\tradial-gradient(circle at 50% 15px, var(--icon) 0 12px, #fff0 13px 100%),\n\t\tradial-gradient(circle at 50% 100%, var(--icon) 0 22px, #fff0 23px 100%);\n\tleft: 25px;\n\tborder-radius: 8px;\n}\n\nlabel[for=m-profile2]:before {\n\twidth: 50px;\n\theight: 54px;\n\ttop: 16px;\n\tbackground: \n\t\tradial-gradient(circle at 50% 15px, var(--icon) 0 12px, #fff0 13px 100%),\n\t\tradial-gradient(circle at 50% 100%, var(--icon) 0 22px, #fff0 23px 100%);\n\tleft: 25px;\n\tborder-radius: 8px;\n}\n\n\ninput:checked + label {\n\tcolor: var(--sel);\n\ttext-shadow: 0 0 5px var(--sel), 0 0 10px var(--sel);\n}\t\n\ninput:checked + label[for=m-home] {\n\t--sel: #39a1f4;\n}\n\ninput:checked + label[for=m-search] {\n\t--sel:  #f48d4e;\n}\n\ninput:checked + label[for=m-notification] {\n\t--sel:  #84a91c;\n}\n\ninput:checked + label[for=m-favorites] {\n\t--sel:  #ff6275;\n\theight: 125px;\n}\n\ninput:checked + label[for=m-profile] {\n\t--sel:  #9d74ff;\n}\n\ninput:checked + label[for=m-profile2] {\n\t--sel:  #9d74ff;\n}\n\n@media only screen and (orientation: portrait) {\n\tlabel { color: transparent !important; text-shadow: none !important;}\n}",
        "x": 1430,
        "y": 360,
        "wires": [
            [
                "6d0947c7.d0d4d8"
            ]
        ]
    },
    {
        "id": "61dbe146.63894",
        "type": "template",
        "z": "ca3e3633fc572ae8",
        "name": "JavaScript",
        "field": "payload.script",
        "fieldType": "msg",
        "format": "javascript",
        "syntax": "plain",
        "template": "const menu = document.getElementById('m');\nconst items =[\"m-home\", \"m-search\", \"m-notification\", \"m-favorites\", \"m-profile\", \"m-profile2\"];\nconst url = location.host;\nconst incomingUrl = `ws://${url}/ws/receiveMessage`;\nconst outgoingUrl = `ws://${url}/ws/publishMessage`;\nlet socket1;\nlet socket2;\n\nconst listener = async function(evt){\n    if(items.includes(evt.target.id)){\n        let obj;\n        const url = origin + '/mysitepost';\n        fetch(url, {\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/json',\n            },\n            body: JSON.stringify({\"item\":evt.target.id}),\n        })\n        .then(res => res.json())\n        .then(data => obj = data)\n        .then(() => {\n            document.getElementById('log').innerHTML = obj.content;\n            console.log(obj);\n        })\n        .catch(err => console.error(err))\n    }\n}\n\nconst sendMessage = function() {\n   let message = document.getElementById('message_send')\n   let messageRaw = message.textContent\n   console.log(`sending message ${messageRaw}`)\n   socket1.send(messageRaw);\n}\n\nfunction initWS(){\n    socket1 = new WebSocket(incomingUrl);\n    socket2 = new WebSocket(outgoingUrl);\n    socket2.onopen = function() {\n        console.log(\"client connected\")\n        const message = {\n            'cmd': 'Client connected'\n        };\n        socket1.send(JSON.stringify(message));\n    };\n\n    socket2.onclose = function(){\n       console.log('Connection closed');\n    };\n\n    socket2.onerror = function(error) {\n       console.log('Error detected: ' + error);\n    };\n\n    socket2.onmessage = function(e) {\n       const server_message = JSON.parse(e.data);\n       console.log(server_message);\n       switch (server_message.cmd){\n           case 'm-favorites':\n                document.getElementById('m-favorites').click();\n                break;\n            default:\n       }\n    }\n}\n \nwindow.addEventListener(\"load\", initWS, false);\nmenu.addEventListener('click', e => listener(e), false);\n\n\n\n",
        "x": 1250,
        "y": 360,
        "wires": [
            [
                "e9a9f9c6.f8ce08"
            ]
        ]
    },
    {
        "id": "c96f4682.70c4f8",
        "type": "http response",
        "z": "ca3e3633fc572ae8",
        "name": "",
        "statusCode": "",
        "headers": {},
        "x": 1730,
        "y": 360,
        "wires": []
    },
    {
        "id": "6d0947c7.d0d4d8",
        "type": "template",
        "z": "ca3e3633fc572ae8",
        "name": "HTML",
        "field": "payload",
        "fieldType": "msg",
        "format": "handlebars",
        "syntax": "mustache",
        "template": "<html>\n  <head>\n\n    <style>{{{payload.style}}}</style>\n </head>\n <body>\n<div>\n<div style=\"flex-direction: column;\">\n<nav class=\"menu\" id=\"m\">\n\n\t<input type=\"radio\" name=\"nav-item\" id=\"m-home\" checked><label for=\"m-home\">Home</label>\n\t<input type=\"radio\" name=\"nav-item\" id=\"m-search\"><label for=\"m-search\">Search</label>\n\t<input type=\"radio\" name=\"nav-item\" id=\"m-notification\"><label for=\"m-notification\">Notification</label>\n\t<input type=\"radio\" name=\"nav-item\" id=\"m-favorites\"><label for=\"m-favorites\">Favorites</label>\n\t<input type=\"radio\" name=\"nav-item\" id=\"m-profile\"><label for=\"m-profile\">Profile</label>\n\t\t<input type=\"radio\" name=\"nav-item\" id=\"m-profile2\"><label for=\"m-profile2\">Profile2</label>\n\n\t<div class=\"selector\"></div>\n</nav>\n</div>\n\n<div id=\"log\"><br>initial content</div>\n</div>\n<script>{{{payload.script}}}</script>\n</body>",
        "x": 1590,
        "y": 360,
        "wires": [
            [
                "c96f4682.70c4f8"
            ]
        ]
    },
    {
        "id": "4c783328.03dc2c",
        "type": "function",
        "z": "ca3e3633fc572ae8",
        "name": "msg.url = \"mysitepost\";",
        "func": "msg.url = \"mysitepost\";\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 1040,
        "y": 360,
        "wires": [
            [
                "61dbe146.63894"
            ]
        ]
    },
    {
        "id": "ae61b4ee683c34a4",
        "type": "function",
        "z": "ca3e3633fc572ae8",
        "name": "return msg.payload to client",
        "func": "msg.payload.message = \"The included data was submitted and available in the msg.payload!\";\nmsg.payload.content = '<br>Some ' + msg.payload.item + ' content!';\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1060,
        "y": 460,
        "wires": [
            [
                "2a90cbb3.d07964"
            ]
        ]
    },
    {
        "id": "382e192da525fb8b",
        "type": "websocket in",
        "z": "ca3e3633fc572ae8",
        "name": "",
        "server": "ab9d351c2e5d158a",
        "client": "",
        "x": 750,
        "y": 160,
        "wires": [
            [
                "0cbed0282cda8b76",
                "614ee41e5d706905"
            ]
        ]
    },
    {
        "id": "0cbed0282cda8b76",
        "type": "function",
        "z": "ca3e3633fc572ae8",
        "name": "return payload",
        "func": "return {payload: msg.payload};",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1260,
        "y": 160,
        "wires": [
            [
                "f39f29bbf47090ea"
            ]
        ]
    },
    {
        "id": "f39f29bbf47090ea",
        "type": "websocket out",
        "z": "ca3e3633fc572ae8",
        "name": "",
        "server": "c2a3b843be6cfc41",
        "client": "",
        "x": 1790,
        "y": 160,
        "wires": []
    },
    {
        "id": "c6deb5c38d60876a",
        "type": "inject",
        "z": "ca3e3633fc572ae8",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{\"cmd\":\"m-favorites\"}",
        "payloadType": "json",
        "x": 770,
        "y": 60,
        "wires": [
            [
                "0cbed0282cda8b76"
            ]
        ]
    },
    {
        "id": "614ee41e5d706905",
        "type": "debug",
        "z": "ca3e3633fc572ae8",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 970,
        "y": 220,
        "wires": []
    },
    {
        "id": "ab9d351c2e5d158a",
        "type": "websocket-listener",
        "path": "/ws/receiveMessage",
        "wholemsg": "false"
    },
    {
        "id": "c2a3b843be6cfc41",
        "type": "websocket-listener",
        "path": "/ws/publishMessage",
        "wholemsg": "false"
    }
]

As already recommended by "HaroldPetersInskipp" you perhaps should use node-red-contrib-uibuilder to build up complex things.

1 Like

Thx for your Help again! I will look at thie Ui Builder and try it out.

1 Like

Just give a shout if anything isn't clear.

Ok one last Question, this works really well for me with "Radio Buttons" where every state has an own Id.

Can i do the same for a Toggle Button? To send "Toggle" and for Example "Toggle Checked"
That when ic would press the button over an app for example that i canupdate the status on my Dashboard

[{"id":"45775c3a.3fde84","type":"http in","z":"92082f42.fa96e","name":"","url":"/mysite","method":"get","upload":false,"swaggerDoc":"","x":370,"y":800,"wires":[["a678f791.e3ac28"]]},{"id":"dc841cf3.8b21","type":"http in","z":"92082f42.fa96e","name":"","url":"/mysitepost","method":"post","upload":false,"swaggerDoc":"","x":360,"y":900,"wires":[["4ffad378.2b850c"]]},{"id":"8526d21b.88e63","type":"http response","z":"92082f42.fa96e","name":"","statusCode":"","headers":{},"x":1310,"y":900,"wires":[]},{"id":"7537aa59.b558d4","type":"template","z":"92082f42.fa96e","name":"CSS","field":"payload.style","fieldType":"msg","format":"html","syntax":"mustache","template":"*, *:before, *:after {\n\tborder: 0;\n\tbox-sizing: border-box;\n\tmargin: 0;\n\tpadding: 0;\n}\nbody {\n\tbackground: linear-gradient(#fff,#ccc);\n\tdisplay: flex;\n\theight: 100vh;\n\t--on: #88e661;\n\t--off: #f0f0f0;\n\t--transDur: 0.6s;\n}\ninput {\n\tposition: fixed;\n\ttransform: translateX(-100%);\n}\n.toy-toggle {\n\tbackground:\n\t\tradial-gradient(at top left,#fff 10%,#fff0 20%),\n\t\tradial-gradient(at top right,#fff 20%,#e4e4e4 35%);\n\tborder-radius: 6em;\n\tbox-shadow:\n\t\t0 0 0.25em #0002,\n\t\t0 3em 1.5em 0.5em #0002;\n\tcursor: pointer;\n\tdisplay: block;\n\tfont-size: 12px;\n\tposition: relative;\n\tmargin: auto;\n\twidth: 20em;\n\theight: 12em;\n\t-webkit-tap-highlight-color: transparent;\n}\n.toy-toggle span {\n\tdisplay: block;\n\tposition: absolute;\n}\n.toy-toggle > span {\n\ttop: 50%;\n\tleft: 50%;\n}\n.toy-toggle > span:not(.handle) {\n\ttransform: translate(-50%,-50%);\n}\n.border1 {\n\tbackground: #f0f0f0;\n\tborder-radius: 5.5em;\n\tbox-shadow: 0 0 0.2em 0.1em #f0f0f0;\n\twidth: 19em;\n\theight: 11em;\n}\n.border2 {\n\tbackground: linear-gradient(0deg,#fff 33%,#ccc 45%);\n\tborder-radius: 4.75em;\n\tbox-shadow: 0 0 0.2em 0.3em #f0f0f0 inset;\n\twidth: 16.5em;\n\theight: 9.5em;\n}\n.border3, .handle {\n\tbackground: linear-gradient(90deg, var(--on) 50%, var(--off) 0);\n}\n.border3 {\n\tbackground-position: 75% 0;\n\tbackground-size: 200% 100%;\n\tborder-radius: 4.25em;\n\tbox-shadow:\n\t\t0 0 0.1em 0.1em #ddd inset,\n\t\t0 1.5em 1.5em 1em #0004 inset,\n\t\t0 0 0 4.25em #0002 inset;\n\twidth: 15.5em;\n\theight: 8.5em;\n\ttransition: background-position var(--transDur) ease-in-out;\n}\n.handle {\n\tborder-radius: 50%;\n\tbox-shadow: 0 0 0.5em 0 #0007;\n\twidth: 8.5em;\n\theight: 8.5em;\n\ttransform: translate(-90%,-50%);\n\ttransition: transform var(--transDur) ease-in-out;\n\tz-index: 0;\n}\n.handle:before {\n\tbackground:\n\t\tradial-gradient(2em 1.5em at 50% 35%,#fff6 15%,#fff0),\n\t\tradial-gradient(1.5em 2.5em at 75% 40%,#fff6 15%,#fff0),\n\t\tradial-gradient(100% 100% at 50% 33%,#0000 25%,#0003 50%);\n\tborder-radius: 50%;\n\tbox-shadow: 0 0 0.3em 0.1em #0003 inset;\n\tcontent: \"\";\n\tdisplay: block;\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\twidth: 100%;\n\theight: 100%;\n\tz-index: 3;\n}\n.handle-off, .handle-on {\n\twidth: 50%;\n\theight: 100%;\n\ttransition: transform calc(var(--transDur)/2);\n\tz-index: 2;\n}\n.handle-off {\n\tbackground: var(--off);\n\tborder-radius: 100% 0 0 100% / 50% 50% 50% 50%;\n\tright: 50%;\n\ttransform-origin: 100% 50%;\n\ttransition-delay: calc(var(--transDur)/2);\n\ttransition-timing-function: ease-out;\n}\n.handle-on {\n\tbackground: var(--on);\n\tborder-radius: 0 100% 100% 0 / 50% 50% 50% 50%;\n\tleft: 50%;\n\ttransform: scaleX(0);\n\ttransform-origin: 0 50%;\n\ttransition-timing-function: ease-in;\n}\n\n/* On */\ninput:checked + .toy-toggle .border3 {\n\tbackground-position: 25% 0;\n}\ninput:checked + .toy-toggle .handle {\n\ttransform: translate(-10%,-50%);\n}\ninput:checked + .toy-toggle .handle-off {\n\ttransform: scaleX(0);\n\ttransition-delay: 0s;\n\ttransition-timing-function: ease-in;\n}\ninput:checked + .toy-toggle .handle-on {\n\ttransform: scaleX(1);\n\ttransition-delay: calc(var(--transDur)/2);\n\ttransition-timing-function: ease-out;\n}","x":1010,"y":800,"wires":[["523fe11a.a2e62"]]},{"id":"e2472e24.ca15b","type":"template","z":"92082f42.fa96e","name":"JavaScript","field":"payload.script","fieldType":"msg","format":"javascript","syntax":"plain","template":"const menu = document.getElementById('m');\nconst items =[\"toggle\", \"switch_2\", \"switch_3\", \"m-favorites\", \"m-profile\", \"m-profile2\"];\nconst url = location.host;\nconst incomingUrl = `ws://${url}/ws/receiveMessage`;\nconst outgoingUrl = `ws://${url}/ws/publishMessage`;\nlet socket1;\nlet socket2;\n\nconst listener = async function(evt){\n    if(items.includes(evt.target.id)){\n        let obj;\n        const url = origin + '/mysitepost';\n        fetch(url, {\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/json',\n            },\n            body: JSON.stringify({\"item\":evt.target.id}),\n        })\n        .then(res => res.json())\n        .then(data => obj = data)\n        .then(() => {\n            document.getElementById('log').innerHTML = obj.content;\n            console.log(obj);\n        })\n        .catch(err => console.error(err))\n    }\n}\n\nconst sendMessage = function() {\n   let message = document.getElementById('message_send')\n   let messageRaw = message.textContent\n   console.log(`sending message ${messageRaw}`)\n   socket1.send(messageRaw);\n}\n\nfunction initWS(){\n    socket1 = new WebSocket(incomingUrl);\n    socket2 = new WebSocket(outgoingUrl);\n    socket2.onopen = function() {\n        console.log(\"client connected\")\n        const message = {\n            'cmd': 'Client connected'\n        };\n        socket1.send(JSON.stringify(message));\n    };\n\n    socket2.onclose = function(){\n       console.log('Connection closed');\n    };\n\n    socket2.onerror = function(error) {\n       console.log('Error detected: ' + error);\n    };\n\n    socket2.onmessage = function(e) {\n       const server_message = JSON.parse(e.data);\n       console.log(server_message);\n       switch (server_message.cmd){\n           case 'toggle':\n                document.getElementById('toggle').click();\n                break;\n            default:\n       }\n    }\n\n\n}\n\n\n\n \nwindow.addEventListener(\"load\", initWS, false);\nmenu.addEventListener('click', e => listener(e), false);\n\n","x":830,"y":800,"wires":[["7537aa59.b558d4"]]},{"id":"3c823358.a9771c","type":"http response","z":"92082f42.fa96e","name":"","statusCode":"","headers":{},"x":1310,"y":800,"wires":[]},{"id":"523fe11a.a2e62","type":"template","z":"92082f42.fa96e","name":"HTML","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<html>\n  <head>\n\n    <style>{{{payload.style}}}</style>\n </head>\n <body>\n<div>\n<div style=\"flex-direction: column;\">\n<nav class=\"menu\" id=\"m\">\n\n\n<input type=\"checkbox\" checked id=\"toggle\" name=\"toggle\" value=\"is_on\">\n\n\n\n<label for=\"toggle\" class=\"toy-toggle\">\n\t<span class=\"border1\"></span>\n\t<span class=\"border2\"></span>\n\t<span class=\"border3\"></span>\n\t<span class=\"handle\">\n\t\t<span class=\"handle-off\"></span>\n\t\t<span class=\"handle-on\"></span>\n\t</span>\n</label>\n\n<div id=\"log\"><br>initial content</div>\n</div>\n<script>{{{payload.script}}}</script>\n</body>","x":1170,"y":800,"wires":[["3c823358.a9771c"]]},{"id":"a678f791.e3ac28","type":"function","z":"92082f42.fa96e","name":"msg.url = \"mysitepost\";","func":"msg.url = \"mysitepost\";\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":620,"y":800,"wires":[["e2472e24.ca15b"]]},{"id":"4ffad378.2b850c","type":"function","z":"92082f42.fa96e","name":"return msg.payload to client","func":"msg.payload.message = \"The included data was submitted and available in the msg.payload!\";\nmsg.payload.content = '<br>Some ' + msg.payload.item + ' content!';\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":640,"y":900,"wires":[["8526d21b.88e63","f07d6a34.0df698"]]},{"id":"f07d6a34.0df698","type":"debug","z":"92082f42.fa96e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":720,"y":1040,"wires":[]},{"id":"d557e0d5.cab4f","type":"websocket in","z":"92082f42.fa96e","name":"","server":"a58f8cb9.e0fd1","client":"","x":370,"y":680,"wires":[["f72f49a4.147478","5779cfe9.5f768"]]},{"id":"f72f49a4.147478","type":"function","z":"92082f42.fa96e","name":"return payload","func":"return {payload: msg.payload};","outputs":1,"noerr":0,"initialize":"","finalize":"","x":640,"y":680,"wires":[["41ec1ac7.e75944"]]},{"id":"41ec1ac7.e75944","type":"websocket out","z":"92082f42.fa96e","name":"","server":"dd0f6365.c6c18","client":"","x":1270,"y":680,"wires":[]},{"id":"e2cefca8.391a7","type":"inject","z":"92082f42.fa96e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"cmd\":\"toggle\"}","payloadType":"json","x":360,"y":600,"wires":[["f72f49a4.147478"]]},{"id":"5779cfe9.5f768","type":"debug","z":"92082f42.fa96e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":590,"y":740,"wires":[]},{"id":"a58f8cb9.e0fd1","type":"websocket-listener","path":"/ws/receiveMessage","wholemsg":"false"},{"id":"dd0f6365.c6c18","type":"websocket-listener","path":"/ws/publishMessage","wholemsg":"false"}]

Thats my Toggle Button/Switch.

[
    {
        "id": "ca3e3633fc572ae8",
        "type": "tab",
        "label": "Flow 2",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "45775c3a.3fde84",
        "type": "http in",
        "z": "ca3e3633fc572ae8",
        "name": "",
        "url": "/mysite",
        "method": "get",
        "upload": false,
        "swaggerDoc": "",
        "x": 410,
        "y": 320,
        "wires": [
            [
                "a678f791.e3ac28"
            ]
        ]
    },
    {
        "id": "dc841cf3.8b21",
        "type": "http in",
        "z": "ca3e3633fc572ae8",
        "name": "",
        "url": "/mysitepost",
        "method": "post",
        "upload": false,
        "swaggerDoc": "",
        "x": 400,
        "y": 420,
        "wires": [
            [
                "4ffad378.2b850c"
            ]
        ]
    },
    {
        "id": "8526d21b.88e63",
        "type": "http response",
        "z": "ca3e3633fc572ae8",
        "name": "",
        "statusCode": "",
        "headers": {},
        "x": 1350,
        "y": 420,
        "wires": []
    },
    {
        "id": "7537aa59.b558d4",
        "type": "template",
        "z": "ca3e3633fc572ae8",
        "name": "CSS",
        "field": "payload.style",
        "fieldType": "msg",
        "format": "html",
        "syntax": "mustache",
        "template": "*, *:before, *:after {\n\tborder: 0;\n\tbox-sizing: border-box;\n\tmargin: 0;\n\tpadding: 0;\n}\nbody {\n\tbackground: linear-gradient(#fff,#ccc);\n\tdisplay: flex;\n\theight: 100vh;\n\t--on: #88e661;\n\t--off: #f0f0f0;\n\t--transDur: 0.6s;\n}\ninput {\n\tposition: fixed;\n\ttransform: translateX(-100%);\n}\n.toy-toggle {\n\tbackground:\n\t\tradial-gradient(at top left,#fff 10%,#fff0 20%),\n\t\tradial-gradient(at top right,#fff 20%,#e4e4e4 35%);\n\tborder-radius: 6em;\n\tbox-shadow:\n\t\t0 0 0.25em #0002,\n\t\t0 3em 1.5em 0.5em #0002;\n\tcursor: pointer;\n\tdisplay: block;\n\tfont-size: 12px;\n\tposition: relative;\n\tmargin: auto;\n\twidth: 20em;\n\theight: 12em;\n\t-webkit-tap-highlight-color: transparent;\n}\n.toy-toggle span {\n\tdisplay: block;\n\tposition: absolute;\n}\n.toy-toggle > span {\n\ttop: 50%;\n\tleft: 50%;\n}\n.toy-toggle > span:not(.handle) {\n\ttransform: translate(-50%,-50%);\n}\n.border1 {\n\tbackground: #f0f0f0;\n\tborder-radius: 5.5em;\n\tbox-shadow: 0 0 0.2em 0.1em #f0f0f0;\n\twidth: 19em;\n\theight: 11em;\n}\n.border2 {\n\tbackground: linear-gradient(0deg,#fff 33%,#ccc 45%);\n\tborder-radius: 4.75em;\n\tbox-shadow: 0 0 0.2em 0.3em #f0f0f0 inset;\n\twidth: 16.5em;\n\theight: 9.5em;\n}\n.border3, .handle {\n\tbackground: linear-gradient(90deg, var(--on) 50%, var(--off) 0);\n}\n.border3 {\n\tbackground-position: 75% 0;\n\tbackground-size: 200% 100%;\n\tborder-radius: 4.25em;\n\tbox-shadow:\n\t\t0 0 0.1em 0.1em #ddd inset,\n\t\t0 1.5em 1.5em 1em #0004 inset,\n\t\t0 0 0 4.25em #0002 inset;\n\twidth: 15.5em;\n\theight: 8.5em;\n\ttransition: background-position var(--transDur) ease-in-out;\n}\n.handle {\n\tborder-radius: 50%;\n\tbox-shadow: 0 0 0.5em 0 #0007;\n\twidth: 8.5em;\n\theight: 8.5em;\n\ttransform: translate(-90%,-50%);\n\ttransition: transform var(--transDur) ease-in-out;\n\tz-index: 0;\n}\n.handle:before {\n\tbackground:\n\t\tradial-gradient(2em 1.5em at 50% 35%,#fff6 15%,#fff0),\n\t\tradial-gradient(1.5em 2.5em at 75% 40%,#fff6 15%,#fff0),\n\t\tradial-gradient(100% 100% at 50% 33%,#0000 25%,#0003 50%);\n\tborder-radius: 50%;\n\tbox-shadow: 0 0 0.3em 0.1em #0003 inset;\n\tcontent: \"\";\n\tdisplay: block;\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\twidth: 100%;\n\theight: 100%;\n\tz-index: 3;\n}\n.handle-off, .handle-on {\n\twidth: 50%;\n\theight: 100%;\n\ttransition: transform calc(var(--transDur)/2);\n\tz-index: 2;\n}\n.handle-off {\n\tbackground: var(--off);\n\tborder-radius: 100% 0 0 100% / 50% 50% 50% 50%;\n\tright: 50%;\n\ttransform-origin: 100% 50%;\n\ttransition-delay: calc(var(--transDur)/2);\n\ttransition-timing-function: ease-out;\n}\n.handle-on {\n\tbackground: var(--on);\n\tborder-radius: 0 100% 100% 0 / 50% 50% 50% 50%;\n\tleft: 50%;\n\ttransform: scaleX(0);\n\ttransform-origin: 0 50%;\n\ttransition-timing-function: ease-in;\n}\n\n/* On */\ninput:checked + .toy-toggle .border3 {\n\tbackground-position: 25% 0;\n}\ninput:checked + .toy-toggle .handle {\n\ttransform: translate(-10%,-50%);\n}\ninput:checked + .toy-toggle .handle-off {\n\ttransform: scaleX(0);\n\ttransition-delay: 0s;\n\ttransition-timing-function: ease-in;\n}\ninput:checked + .toy-toggle .handle-on {\n\ttransform: scaleX(1);\n\ttransition-delay: calc(var(--transDur)/2);\n\ttransition-timing-function: ease-out;\n}",
        "x": 1050,
        "y": 320,
        "wires": [
            [
                "523fe11a.a2e62"
            ]
        ]
    },
    {
        "id": "e2472e24.ca15b",
        "type": "template",
        "z": "ca3e3633fc572ae8",
        "name": "JavaScript",
        "field": "payload.script",
        "fieldType": "msg",
        "format": "javascript",
        "syntax": "plain",
        "template": "const menu = document.getElementById('m');\nconst items =[\"toggle\", \"switch_2\", \"switch_3\", \"m-favorites\", \"m-profile\", \"m-profile2\"];\nconst url = location.host;\nconst incomingUrl = `ws://${url}/ws/receiveMessage`;\nconst outgoingUrl = `ws://${url}/ws/publishMessage`;\nlet socket1;\nlet socket2;\n\nconst listener = async function(evt){\n    if(items.includes(evt.target.id)){\n        let obj;\n        const url = origin + '/mysitepost';\n        fetch(url, {\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/json',\n            },\n            body: JSON.stringify({\"item\":evt.target.id}),\n        })\n        .then(res => res.json())\n        .then(data => obj = data)\n        .then(() => {\n            document.getElementById('log').innerHTML = obj.content;\n            console.log(obj);\n        })\n        .catch(err => console.error(err))\n    }\n}\n\nconst sendMessage = function() {\n   let message = document.getElementById('message_send')\n   let messageRaw = message.textContent\n   console.log(`sending message ${messageRaw}`)\n   socket1.send(messageRaw);\n}\n\nfunction initWS(){\n    socket1 = new WebSocket(incomingUrl);\n    socket2 = new WebSocket(outgoingUrl);\n    socket2.onopen = function() {\n        console.log(\"client connected\")\n        const message = {\n            'cmd': 'Client connected'\n        };\n        socket1.send(JSON.stringify(message));\n    };\n\n    socket2.onclose = function(){\n       console.log('Connection closed');\n    };\n\n    socket2.onerror = function(error) {\n       console.log('Error detected: ' + error);\n    };\n\n    socket2.onmessage = function(e) {\n       const server_message = JSON.parse(e.data);\n       console.log(server_message);\n       switch (server_message.cmd){\n           case 'toggle on':\n                document.getElementById('toggle').checked = true;\n                break;\n            case 'toggle off':\n                document.getElementById('toggle').checked = false;\n                break;\n            default:\n       }\n    }\n\n\n}\n\n\n\n \nwindow.addEventListener(\"load\", initWS, false);\nmenu.addEventListener('click', e => listener(e), false);\n\n",
        "x": 870,
        "y": 320,
        "wires": [
            [
                "7537aa59.b558d4"
            ]
        ]
    },
    {
        "id": "3c823358.a9771c",
        "type": "http response",
        "z": "ca3e3633fc572ae8",
        "name": "",
        "statusCode": "",
        "headers": {},
        "x": 1350,
        "y": 320,
        "wires": []
    },
    {
        "id": "523fe11a.a2e62",
        "type": "template",
        "z": "ca3e3633fc572ae8",
        "name": "HTML",
        "field": "payload",
        "fieldType": "msg",
        "format": "handlebars",
        "syntax": "mustache",
        "template": "<html>\n  <head>\n\n    <style>{{{payload.style}}}</style>\n </head>\n <body>\n<div>\n<div style=\"flex-direction: column;\">\n<nav class=\"menu\" id=\"m\">\n\n\n<input type=\"checkbox\" checked id=\"toggle\" name=\"toggle\" value=\"is_on\">\n\n\n\n<label for=\"toggle\" class=\"toy-toggle\">\n\t<span class=\"border1\"></span>\n\t<span class=\"border2\"></span>\n\t<span class=\"border3\"></span>\n\t<span class=\"handle\">\n\t\t<span class=\"handle-off\"></span>\n\t\t<span class=\"handle-on\"></span>\n\t</span>\n</label>\n\n<div id=\"log\"><br>initial content</div>\n</div>\n<script>{{{payload.script}}}</script>\n</body>",
        "x": 1210,
        "y": 320,
        "wires": [
            [
                "3c823358.a9771c"
            ]
        ]
    },
    {
        "id": "a678f791.e3ac28",
        "type": "function",
        "z": "ca3e3633fc572ae8",
        "name": "msg.url = \"mysitepost\";",
        "func": "msg.url = \"mysitepost\";\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 660,
        "y": 320,
        "wires": [
            [
                "e2472e24.ca15b"
            ]
        ]
    },
    {
        "id": "4ffad378.2b850c",
        "type": "function",
        "z": "ca3e3633fc572ae8",
        "name": "return msg.payload to client",
        "func": "msg.payload.message = \"The included data was submitted and available in the msg.payload!\";\nmsg.payload.content = '<br>Some ' + msg.payload.item + ' content!';\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 680,
        "y": 420,
        "wires": [
            [
                "8526d21b.88e63",
                "f07d6a34.0df698"
            ]
        ]
    },
    {
        "id": "f07d6a34.0df698",
        "type": "debug",
        "z": "ca3e3633fc572ae8",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 760,
        "y": 560,
        "wires": []
    },
    {
        "id": "d557e0d5.cab4f",
        "type": "websocket in",
        "z": "ca3e3633fc572ae8",
        "name": "",
        "server": "a58f8cb9.e0fd1",
        "client": "",
        "x": 410,
        "y": 200,
        "wires": [
            [
                "f72f49a4.147478",
                "5779cfe9.5f768"
            ]
        ]
    },
    {
        "id": "f72f49a4.147478",
        "type": "function",
        "z": "ca3e3633fc572ae8",
        "name": "return payload",
        "func": "return {payload: msg.payload};",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 680,
        "y": 200,
        "wires": [
            [
                "41ec1ac7.e75944"
            ]
        ]
    },
    {
        "id": "41ec1ac7.e75944",
        "type": "websocket out",
        "z": "ca3e3633fc572ae8",
        "name": "",
        "server": "dd0f6365.c6c18",
        "client": "",
        "x": 1310,
        "y": 200,
        "wires": []
    },
    {
        "id": "e2cefca8.391a7",
        "type": "inject",
        "z": "ca3e3633fc572ae8",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{\"cmd\":\"toggle on\"}",
        "payloadType": "json",
        "x": 430,
        "y": 60,
        "wires": [
            [
                "f72f49a4.147478"
            ]
        ]
    },
    {
        "id": "5779cfe9.5f768",
        "type": "debug",
        "z": "ca3e3633fc572ae8",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 630,
        "y": 260,
        "wires": []
    },
    {
        "id": "3ebd216e80e1c3de",
        "type": "inject",
        "z": "ca3e3633fc572ae8",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{\"cmd\":\"toggle off\"}",
        "payloadType": "json",
        "x": 430,
        "y": 120,
        "wires": [
            [
                "f72f49a4.147478"
            ]
        ]
    },
    {
        "id": "a58f8cb9.e0fd1",
        "type": "websocket-listener",
        "path": "/ws/receiveMessage",
        "wholemsg": "false"
    },
    {
        "id": "dd0f6365.c6c18",
        "type": "websocket-listener",
        "path": "/ws/publishMessage",
        "wholemsg": "false"
    }
]
1 Like

Thx , i tryed some things but it never worked, when i see it now it looks so easy and makes sense.

But rly thx a lot with this "examples" i can transfer that scripts to all my use cases now, what i couldnt do by my self.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.