I am fairly new to CSS, HTML and Node-Red and only recently started using these tools. I have read and looked at many examples trying to figure this all out. I am using the dashboard and it works very well, but I would like a separate web page (that is not part of the dashboard) since the display format will be quite different. I have started looking into UIBuilder (it looks very promising) and I was able to add and display some JSON data in the “Normal Messages”, but I need to better understand Vue.js. I also looked at the Lego “Front-end Website with Node-RED: Example Form” which uses AJAX but I understand that even less.
I have a simple HTML template that I developed for formatting emails using the Mustache template, which is working (although I am not sure why there are extra line breaks when it is displayed in Office365 mail?). For the purposes of testing, I am trying to use the same template for a web page. Please see the attached code (Note that I have removed the email address).
[{"id":"8abc961a.097828","type":"http in","z":"d934eba.5ef7618","name":"","url":"/hello","method":"get","upload":false,"swaggerDoc":"","x":140,"y":220,"wires":[["6412a186.6b94a"]]},{"id":"6412a186.6b94a","type":"template","z":"d934eba.5ef7618","name":"page","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<html>\n <head></head>\n <body>\n <h1>Hello World!</h1>\n </body>\n</html>","x":670,"y":220,"wires":[["3217a9ba.41bb26"]]},{"id":"3217a9ba.41bb26","type":"http response","z":"d934eba.5ef7618","name":"","statusCode":"","headers":{},"x":910,"y":220,"wires":[]},{"id":"dafb8629.ba1a18","type":"template","z":"d934eba.5ef7618","name":"HTTP Template","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<style> \n \n p {\n background-color: yellow;\n color:black;\n display: inline;\n margin: 0,0,0,0;\n height: 12px;\n }\n \n .txtcolor {\n color: {{payload.data.color}}; \n };\n \n</style>\n\n<HTML>\n {{payload.data.color}}\n {{payload.data.val}}\n <br> <br>\n <p> The value is:</p> <p class=\"txtcolor\">{{payload.data.val}}</p>\n <p> The color is:</p> <p class=\"txtcolor\">{{payload.data.color}}</p>\n</HTML>","output":"str","x":700,"y":400,"wires":[["730ff254.6c1a2c","9072fba8.7c66e8"]]},{"id":"730ff254.6c1a2c","type":"http response","z":"d934eba.5ef7618","name":"HttpResponse","statusCode":"","headers":{},"x":940,"y":360,"wires":[]},{"id":"730a2966.a7b028","type":"inject","z":"d934eba.5ef7618","name":"","topic":"","payload":"inc","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":620,"wires":[["dca904b4.74e0a8"]]},{"id":"fc896279.1b11","type":"function","z":"d934eba.5ef7618","name":"Prepare HTML","func":"\n\nvar val;\nvar color;\n\nif (context.get(\"val\") === undefined) {\n val = 5;\n context.set(\"val\",val);\n}\n\n\nif (msg.payload === \"inc\") {\n val = context.get(\"val\") + 1;\n context.set(\"val\",val);\n}\n\nif (msg.payload === \"dec\") {\n val = context.get(\"val\") - 1;\n context.set(\"val\",val);\n}\n\nif (val > 5) {\n color = 'red';\n} else { \n color = 'green';\n}\n\nmsg.payload = {\n \"data\": {\n \"val\": val,\n \"color\": color\n }\n};\n\nmsg.url = \"/myData\";\nreturn msg;","outputs":1,"noerr":0,"x":320,"y":400,"wires":[["dafb8629.ba1a18","4a3d0f41.53458"]]},{"id":"e1f508dd.0a1368","type":"inject","z":"d934eba.5ef7618","name":"","topic":"","payload":"dec","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":660,"wires":[["dca904b4.74e0a8"]]},{"id":"415c4742.0d6228","type":"http in","z":"d934eba.5ef7618","name":"","url":"/myData","method":"get","upload":false,"swaggerDoc":"","x":110,"y":380,"wires":[["fc896279.1b11"]]},{"id":"9072fba8.7c66e8","type":"debug","z":"d934eba.5ef7618","name":"Http_Debug2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":930,"y":400,"wires":[]},{"id":"a1d1eb0c.044328","type":"e-mail","z":"d934eba.5ef7618","server":"smtp.gmail.com","port":"465","secure":true,"tls":false,"name":"","dname":"Send Email","x":930,"y":620,"wires":[]},{"id":"dca904b4.74e0a8","type":"function","z":"d934eba.5ef7618","name":"Prepare Test Email","func":"// Prepare the color & value payload\nvar val;\nvar color;\n\nif (context.get(\"val\") === undefined) {\n val = 5;\n context.set(\"val\",val);\n}\n\n\nif (msg.payload === \"inc\") {\n val = context.get(\"val\") + 1;\n context.set(\"val\",val);\n}\n\nif (msg.payload === \"dec\") {\n val = context.get(\"val\") - 1;\n context.set(\"val\",val);\n}\n\nif (val > 5) {\n color = 'red';\n} else { \n color = 'green';\n}\n\nmsg.payload = {\n \"data\": {\n \"val\": val,\n \"color\": color\n }\n};\n\n\n// Add the msg info information for email\nmsg.to = \"FName.LName@gmail.com\";\nmsg.from = \"Me\"; \nmsg.topic = \"Email Test\";\n\n\nreturn msg;\n","outputs":1,"noerr":0,"x":430,"y":620,"wires":[["63c87554.d3bbec","4a905567.448d3c","dafb8629.ba1a18"]]},{"id":"5a48c159.3527f","type":"debug","z":"d934eba.5ef7618","name":"Email Debug2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":940,"y":660,"wires":[]},{"id":"63c87554.d3bbec","type":"template","z":"d934eba.5ef7618","name":"eMial Template","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<style> \n \n p {\n background-color: yellow;\n color:black;\n display: inline;\n margin: 0,0,0,0;\n height: 12px;\n }\n \n .txtcolor {\n color: {{payload.data.color}}; \n };\n \n</style>\n\n<HTML>\n {{payload.data.color}}\n {{payload.data.val}}\n <br> <br>\n <p> The value is:</p> <p class=\"txtcolor\">{{payload.data.val}}</p>\n <p> The color is:</p> <p class=\"txtcolor\">{{payload.data.color}}</p>\n</HTML>","output":"str","x":700,"y":620,"wires":[["a1d1eb0c.044328","5a48c159.3527f"]]},{"id":"4a905567.448d3c","type":"debug","z":"d934eba.5ef7618","name":"Email Debug1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":700,"y":580,"wires":[]},{"id":"4a3d0f41.53458","type":"debug","z":"d934eba.5ef7618","name":"Http Debug1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":690,"y":480,"wires":[]},{"id":"e418ff5a.96aee","type":"inject","z":"d934eba.5ef7618","name":"","topic":"","payload":"inc","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":440,"wires":[["fc896279.1b11"]]},{"id":"4413081b.8d6d58","type":"inject","z":"d934eba.5ef7618","name":"","topic":"","payload":"dec","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":480,"wires":[["fc896279.1b11"]]}]
The first time I deploy Node-Red and refresh the web page (/myData), it looks the way I expect it to look.
When I refresh the web page, the “val=5” disappears? Why?
For the purpose of the example I have created an Inc / Dec Inject node. It increments / decrements the val to simulate a changing payload. If val > 5 the color should be red and if val <=5 the color should be green. The plan is to continuously update the payload (approx. every 3s - not shown for the purpose of this example) and use this data with the Mustache Template to populate the web page.
There seem to be some “conditions” that are causing it to work the very first time when Node-Red is first deployed (Restart Flows), so is there something that I could do / add that would simulate this behavior? (I guess the first time it loads, it publishes the static web page which has the mustache payload data loaded. I am assuming that after the first time, the mustache payload data becomes null, although I don’t understand why “green” is still there?). In other words, as the payload val is changed, can it “update” the web page with the new payload data? Would this require a $scope.watch or some AJAX stuff? Examples would be greatly appreciated. Thank you.