Using the msg.payload to change ui template

#1

I am trying to use the msg.payload to draw circles on an image in the ui template. The image I have got below is not how its gonna look to its a basic concept. If I get data that says 'step 1' for example, I want a circle to turn green maybe at the top left corner, and if the msg.payload is 'step 2' I want another portion of the screen to turn green green while the previous one turns red. I have got it to work while using just variables in the script and then manually changing them.Right now, I am trying to change it based on the msg.payload coming in but this isn't working that is my code and my flow below... please any help would be much appreciated

[{"id":"8e1bd91f.0351b8","type":"inject","z":"60c4f4eb.03d874","name":"","topic":"","payload":"hey","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":390,"y":240,"wires":[["5a85126b.bb1f34"]]},{"id":"5a85126b.bb1f34","type":"ui_template","z":"60c4f4eb.03d874","group":"6e5e2fd4.bea84","name":"","order":1,"width":"23","height":"23","format":"<!DOCTYPE
html>\n\n<html>\n    \n<body>\n<div
ng-bind-html=\"msg.payload\"></div>\n<p>Image to use:</p>\n\n<img
id=\"scream\" width=\"900\" height=\"800\"\nsrc=\"/route.png\"
alt=\"The Scream\">\n\n<p>Canvas:</p>\n\n<canvas id=\"myCanvas\"
width=\"1000\" height=\"950\"\nstyle=\"border:1px solid
#d3d3d3;\">\n\n</canvas>\n<script>\n\nvar canvas =
document.getElementById(\"myCanvas\")\nvar ctx =
canvas.getContext(\"2d\")\nvar img =
document.getElementById(\"scream\")\n\nctx.drawImage(img,0,0);\n\nif(msg.payload
== 'hey'){\n ctx.beginPath();\n ctx.arc(30,30,30,0,2*Math.PI);\n
ctx.fillStyle = \"red\";\nctx.fill();\n
ctx.stroke();\n}\n</script>\n</body>\n</html>","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":720,"y":300,"wires":[["b283a520.d76fe"]]},{"id":"b283a520.d76fe","type":"debug","z":"60c4f4eb.03d874","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":900,"y":200,"wires":[]},{"id":"6e5e2fd4.bea84","type":"ui_group","z":"","name":"Route","tab":"f540ef38.3110e","disp":true,"width":"23","collapse":false},{"id":"f540ef38.3110e","type":"ui_tab","z":"","name":"Route","icon":"dashboard","order":2}]
0 Likes

#2

May you surround your code with 3 backticks ``` so as we can import and try it ? Also a screenshot of your results will be helpful as we will not have how to test with the very same image you are using.

0 Likes

#3

image1%20(5)

Basically, the circle in the top left corner, I need that to appear when a specific payload comes in, and for it to be hidden when another payload comes in, I can get it to work by creating variables and inside the ui template node and forcing a value in, but I want to replace it with msg.payload instead. At the moment, when I use msg.payload, for the if function variable, nothing happens.

Also I'm not sure what you mean by the backticks, i think if you copy and paste the flow from the clipboard, it works

0 Likes

#4

image

0 Likes

#5

Done. Is that better?

0 Likes

#6

Sorry - no - my fault :frowning:

Re-edit - delete orig paste

Then re-export from Node-RED - paste -then BEFORE you save - do the selection and press that button

Sorry for duff gen

Simon

0 Likes

#7

I have done that just now, it looks the exact same, is that working now?

0 Likes

#8

mm - its not - at least I can't import it

Can you paste it to pastebin and give us the url to it?

0 Likes

#9
[{"id":"8e1bd91f.0351b8","type":"inject","z":"60c4f4eb.03d874","name":"","topic":"dolly","payload":"hey","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":300,"y":240,"wires":[["5a85126b.bb1f34"]]},{"id":"5a85126b.bb1f34","type":"ui_template","z":"60c4f4eb.03d874","group":"6e5e2fd4.bea84","name":"","order":1,"width":"23","height":"23","format":"<!DOCTYPE
 html>\n\n<html>\n \n<body>\n<div 
ng-bind-html=\"msg.payload\"></div>\n<p>Image to 
use:</p>\n\n<img id=\"scream\" width=\"900\" 
height=\"800\"\nsrc=\"/route.png\" alt=\"The 
Scream\">\n\n<p>Canvas:</p>\n\n<canvas id=\"myCanvas\"
 width=\"1000\" height=\"950\"\nstyle=\"border:1px solid 
#d3d3d3;\">\n\n</canvas>\n<script>\nvar shawty = 
'hey'\nvar canvas = document.getElementById(\"myCanvas\")\nvar ctx = 
canvas.getContext(\"2d\")\nvar img = 
document.getElementById(\"scream\")\n\nctx.drawImage(img,0,0);\n\nif(shawty
 === \"hey\"){\n ctx.beginPath();\n ctx.arc(30,30,30,0,2*Math.PI);\n 
ctx.fillStyle = \"red\";\nctx.fill();\n ctx.stroke();\n}\n</script>\n</body>\n</html>","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":540,"y":160,"wires":[["b283a520.d76fe"]]},{"id":"b283a520.d76fe","type":"debug","z":"60c4f4eb.03d874","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":810,"y":220,"wires":[]},{"id":"6e5e2fd4.bea84","type":"ui_group","z":"","name":"Route","tab":"f540ef38.3110e","disp":true,"width":"23","collapse":false},{"id": "f540ef38.3110e","type":"ui_tab","z":"","name":"Route","icon":"dashboard","order":2}]
0 Likes

#10

If you try that one, I think it works now

0 Likes

#11

@kebebs I have edited your post to fix the formatting. You must put three-backtick characters on new lines before and after the pasted flow:

```
[{"id":"8e1bd91f.0351b8","type":"inject","z" ...
```

That will ensure the formatting is preserved.

1 Like

#12

thank you for that, does the code work for you now please?

0 Likes

#13

It's still not importing for me :frowning:

image

0 Likes

#14

i have put back the original post before knolleary changed it... that one works, please try the flow after you asked for the url

0 Likes

#15

I'm not entirely sure what edit you made, but your flow now has extra line breaks in it which means it cannot be imported.

0 Likes

#16

If you mean this one

then it doesn't work for me

None of them work for me

  1. Are you selecting your flow and then exporting via the menu - export-clipboard method ?

  2. Can you try the pastebin method - just to eliminate this forum as the source of the error?

Simon

0 Likes

#17

Looks like there are trailing back-tics in the pasted flow... it might work if you remove those.

0 Likes

#18

Is the import flow text box using the ace editor? If not, how hard would it be to add it, like the other JSON editors?

There are times when I want to paste in a flow and edit it before the import happens -- having the JSON errors highllighted, and the ability to "format" the text would make that much easier. Since it has already been implemented elsewhere in the editor, I could probably retro-fit it, if you would entertain a PR...

0 Likes

#19

I edited manually the flow in order to try to understand the issue at hand.

<!DOCTYPE html>
<html>

<body>
    <div ng-bind-html="msg.payload"></div>
    <p>Image to use:</p>
    <img id="scream" width="900" height="800" src="/route.png" alt="The Scream">
    <p>Canvas:</p>
    <canvas id="myCanvas" width="1000" height="950" style="border:1px solid #d3d3d3;"> </canvas>
    <script>  
        var canvas = document.getElementById("myCanvas");
        var ctx = canvas.getContext("2d");
        var img = document.getElementById("scream");
        ctx.drawImage(img, 0, 0);
        if (msg.payload == 'hey') {
            ctx.beginPath(); ctx.arc(30, 30, 30, 0, 2 * Math.PI);
            ctx.fillStyle = "red";
            ctx.fill();
            ctx.stroke();
        } 
    </script>
</body>

</html>

The question seems to boils down to : How to read msg.payload property inside the script tag in an UI template node.

I guess the solution is to make use of scope.$watch

Have a look on below link:

https://internet-of-things.blog/en/accessing-node-red-msg-object-in-the-browser/

1 Like