Node-red-contrib-ui-svg execute js from message

Hi @BartButenaers!!

How can i click the button by message input?

I need to execute a js function by input message. I thought I'd add a hidden button and click it by message.
How can i make this feature?

Best Regards

Samuel Brás

@samuelbras,
That is something I don't support yet. Will need to add it as a new feature.
Can you create a public question from this?
Then others can follow our discussion.
Bart

Hi @BartButenaers the topic is public.

I have to do somting to try solve the problem.

Ok thanks!
I will have a look tonight whether I can easily add such a feature ...

Hi @samuelbras,

I have implemented a proposal of this feature request on Github. You can install it (from within your .node-red folder) like this:

npm install bartbutenaers/node-red-contrib-ui-svg

This is how it would work:

  1. Apply a JS event handler of type "Input msg":

    image

    Note: Since the element selector is not relevant in this case, the field will automatically become disabled.

  2. As you can see (in the above screenshot), we convert the input message to json and show it in an alert popup message.

    Note: the msg input message object is available in these kind of event handlers.

  3. When I now inject a message, the "input msg" event javascript handler will be triggered. This means the input message will be displayed in the alert popup dialog:

    image

Would be nice if you could test this and give me feedback!

Hi @BartButenaers

I will test your solution this week.

1 Like

Hi @BartButenaers

I have updated my node-red to the latest version and update with your version but I don't have that option input msg available.

Have you refreshed your browser window?

yes, I have also restared the computer

I have reinstalled it from Github again, it here it is displayed correctly:

image

Did you execute the npm install bartbutenaers/node-red-contrib-ui-svg within your .node-red folder? Otherwise you have two different versions installed, and you will be running the old version...

And otherwise do you see any errors in your browser console log (where you are displaying the flow editor)? If not, then I give up...

Hi @BartButenaers you can't give up :slight_smile:

I have do the comand again and it work. Tomorrow I will do my tests

1 Like

Hi @BartButenaers
I have encountred one problem.
If I have the option Don't send click events in case of a double click event, this button ony done the double click.

Other problem is the alert message only occurs when I click in any button.
I have to make a sample to try.

My sugestion is to define a message type do fier this kind of events, because I can have lots os input message, and only need / want to execute if a specific message arrive. In my case, I need only if is a GPS message.

Also If the message is of type databind it not fier.

@samuelbras,
Can you please add a 'simple' example flow, and explain the steps I need to do to reproduce the issues?

Can you please give an example, to make sure I understand you correctly?
Thanks!

This is now hopefully fixed on Github. More details here

Would be nice if you could explain (clearly) what the problem is, because your issues prevent me from releasing major 2.3.0 release of the SVG node...

That should also be fixed on Github. So would be nice if you could test that again...

Hi @BartButenaers

I have been out, sorry
I will make a example today.

Hi @BartButenaers

[{"id":"795769ff.1d2ab8","type":"ui_svg_graphics","z":"e9e5c0eb.489de","group":"8d3148e0.0eee88","order":2,"width":"24","height":"14","svgString":"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:drawsvg=\"http://www.drawsvg.org\" id=\"svgMap\" x=\"0\" y=\"0\" viewBox=\"0 0 1920 1200\" width=\"100%\" height=\"100%\" preserveAspectRatio=\"xMidYMid meet\">\n\n<!-- Add here your SVG shapes (circles, rectangles, ...) -->\n<!-- Or remove everything, if you want to paste an entire drawing (<svg...>...</svg>).-->\n<g id=\"group1\" style=\"display:block\" x=\"0\" y=\"0\" width=\"1642\" height=\"1040\">\n        <text id=\"topicPos100\" class=\"gridElement \" transform=\"translate(72 64)\">index</text>\n        <text id=\"topicDesc100\" class=\"gridElement \" transform=\"translate(171 64)\" style=\"font-weight:bold\">\n           This is the group one</text>\n        <line id=\"line100\" class=\"cls-objectiveSeparator 100\"  x2=\"1600\" transform=\"translate(20 100)\">\n</g>\n<text id=\"btngroupChange\" x=\"0\" y=\"300\" class=\"material-icons cls-Grey noselect\" \n        style=\"font-size:128px;\">swap_horizontal_circle</text>\n<style>\n.cls-objectiveSeparator {\n        stroke: #e5e5e5;\n        stroke-width: 3px;\n      }\n      </style>\n</svg>","clickableShapes":[],"javascriptHandlers":[{"selector":"#btngroupChange","action":"click","sourceCode":"//toggle map to objective\nalert('one click');\n"},{"selector":"#btngroupChange","action":"dblclick","sourceCode":"//toggle map to objective\nalert('double click');"}],"smilAnimations":[],"bindings":[],"showCoordinates":false,"autoFormatAfterEdit":false,"showBrowserErrors":false,"showBrowserEvents":false,"enableJsDebugging":false,"sendMsgWhenLoaded":false,"noClickWhenDblClick":true,"outputField":"payload","editorUrl":"//drawsvg.org/drawsvg.html","directory":"","panning":"disabled","zooming":"disabled","panOnlyWhenZoomed":false,"doubleClickZoomEnabled":false,"mouseWheelZoomEnabled":false,"dblClickZoomPercentage":150,"cssString":"div.ui-svg svg{\n    color: var(--nr-dashboard-widgetColor);\n    fill: currentColor !important;\n}\ndiv.ui-svg path {\n    fill: inherit !important;\n}","name":"","x":1120,"y":840,"wires":[[]]},{"id":"8d3148e0.0eee88","type":"ui_group","name":"7Shield","tab":"1a3b3b7a.dfdbf5","order":1,"disp":false,"width":"24","collapse":false},{"id":"1a3b3b7a.dfdbf5","type":"ui_tab","name":"Home","icon":"dashboard","disabled":false,"hidden":true}]

I added a button with the two events, click and doubleClick. each sends a message. The problem is that only doubleclick works.

Evening @samuelbras,
Thanks for the example!

I assume you don't mean an output message, but a simple alert popup message?

Here it works as I expect. You have enabled this option:
image

And it behaves like this:

  • When I single click the button, the I get a popup message with the text "single click".
  • When I double click the button, the I get a popup message with the text "double click".

Seems ok to me ...

Have you installed my fix from Github yesterday (and refreshed your browser window)?? Because otherwise I can imagine you still have the same problem ...

Hi @BartButenaers

I've already installed your Github version and the click and doubleclick are working as expected.

Now the msg input doesn't work as I expected. In other words, the event is only triggered when clicking on the screen or an svg button and not when the message arrives.

[{"id":"b9b3ef06.04792","type":"ui_svg_graphics","z":"e9e5c0eb.489de","group":"8d3148e0.0eee88","order":2,"width":"24","height":"14","svgString":"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:drawsvg=\"http://www.drawsvg.org\" id=\"svgMap\" x=\"0\" y=\"0\" viewBox=\"0 0 1920 1200\" width=\"100%\" height=\"100%\" preserveAspectRatio=\"xMidYMid meet\">\n\n<!-- Add here your SVG shapes (circles, rectangles, ...) -->\n<!-- Or remove everything, if you want to paste an entire drawing (<svg...>...</svg>).-->\n<g id=\"group1\" style=\"display:block\" x=\"0\" y=\"0\" width=\"1642\" height=\"1040\">\n        <text id=\"topicPos100\" class=\"gridElement \" transform=\"translate(72 64)\">index</text>\n        <text id=\"topicDesc100\" class=\"gridElement \" transform=\"translate(171 64)\" style=\"font-weight:bold\">\n           This is the group one</text>\n        <line id=\"line100\" class=\"cls-objectiveSeparator 100\"  x2=\"1600\" transform=\"translate(20 100)\">\n</g>\n<text id=\"btngroupChange\" x=\"0\" y=\"300\" class=\"material-icons cls-Grey noselect\" \n        style=\"font-size:128px;\">swap_horizontal_circle</text>\n<style>\n.cls-objectiveSeparator {\n        stroke: #e5e5e5;\n        stroke-width: 3px;\n      }\n      </style>\n</svg>","clickableShapes":[],"javascriptHandlers":[{"selector":"#btngroupChange","action":"click","sourceCode":"//toggle map to objective\nalert('one click');\n"},{"selector":"#btngroupChange","action":"dblclick","sourceCode":"//toggle map to objective\nalert('double click');"},{"selector":"","action":"msg","sourceCode":"alert('input message')"}],"smilAnimations":[],"bindings":[],"showCoordinates":false,"autoFormatAfterEdit":false,"showBrowserErrors":false,"showBrowserEvents":false,"enableJsDebugging":false,"sendMsgWhenLoaded":false,"noClickWhenDblClick":true,"outputField":"payload","editorUrl":"//drawsvg.org/drawsvg.html","directory":"","panning":"disabled","zooming":"disabled","panOnlyWhenZoomed":false,"doubleClickZoomEnabled":false,"mouseWheelZoomEnabled":false,"dblClickZoomPercentage":150,"cssString":"div.ui-svg svg{\n    color: var(--nr-dashboard-widgetColor);\n    fill: currentColor !important;\n}\ndiv.ui-svg path {\n    fill: inherit !important;\n}","name":"","x":1120,"y":1000,"wires":[[]]},{"id":"791c9664.98d078","type":"inject","z":"e9e5c0eb.489de","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[{\"command\":\"add_element\",\"elementType\":\"text\",\"elementId\":\"top140\",\"elementAttributes\":{\"class\":\"gridElement\"},\"elementStyleAttributes\":{},\"textContent\":\"77\"},{\"command\":\"add_element\",\"elementType\":\"text\",\"elementId\":\"topicPos140\",\"elementAttributes\":{\"class\":\"gridElement\"},\"elementStyleAttributes\":{},\"textContent\":\"4/5\"},{\"command\":\"add_element\",\"elementType\":\"text\",\"elementId\":\"text140\",\"elementAttributes\":{\"class\":\"gridElement \"},\"elementStyleAttributes\":{},\"textContent\":\"Text\"},{\"command\":\"add_element\",\"elementType\":\"line\",\"elementAttributes\":{\"class\":\"cls-objectiveSeparator \",\"x2\":\"1600\"}}]","payloadType":"json","x":910,"y":1000,"wires":[["b9b3ef06.04792"]]},{"id":"8d3148e0.0eee88","type":"ui_group","name":"7Shield","tab":"1a3b3b7a.dfdbf5","order":1,"disp":false,"width":"24","collapse":false},{"id":"1a3b3b7a.dfdbf5","type":"ui_tab","name":"Home","icon":"dashboard","disabled":false,"hidden":true}]

Is it possible to filter by msg input type? It's just that I have a lot of msg input but it only matters when the message is of a type.
For example, when a message changes the element's color, I want to take an action. Is it possible to do this?

No that is NOT true. If you should add a debugger statement in your code and open the developer tools, then you will automatically arrive at that breakpoint as soon as you inject a message. So the event handler is called but the browser requires to have the focus, which means it will only display the alert afterwards as soon as you click the browser window:

demo_msg_js_event_alert

When you change your alert statement to e.g. $("#btngroupChange").css("color", "red"); then you will see that your input message triggers your js event handler immediately:

demo_msg_js_event

  • The 'normal' js event handlers are being triggered when you execute an action on an SVG shape, e.g. you click it. But then you are already busy in the same window as where you want to show the alert, so the window has already focus.
  • The input msg triggered js event handlers is to do some background stuff. But now you want to use it to show an alert, which browsers don't like. That seems very normal to me because people don't like that you start displaying popups in their web app. If you want to find a workaround, please be my guest. But it is not something I am going to digg into.

You can filter the message yourself inside your js event handler, based on the values in the message. I have now added a new feature on Github (which you need to install), to allow you to set the msg.topic to value "custom_msg". In that case the message will not be used for anything else by the SVG node, so you can put in the message whatever data you like.

For example set the color based on the payload value:

custom_msg_demo

I have also added a similar example to the readme page.