Node-red-contrib-ui-svg click and dblclick in same element

Good Morning.
I'm making my dashboard and I need to have both click and doubleclick events on the same element.
With the click it changes some elements.
With the active doubleclick, it is possible to zoom in on a layer.
How can I distinguish between the two?

Many thanks



Suppose I have a circle:

<svg x="0" y="0" height="100" viewBox="0 0 100 100" width="100" xmlns="" xmlns:svg="" xmlns:xlink="">
  <circle id="mycircle" cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />

Then you can add multiple event handlers to the same shape:

As you can see, you can e.g. give each event handler its own topic.

That way the output messages will get those topics:


Based on the topic, you can execute actions in your flow...




This solution work for external comunication, but it fier the single click first.

I need to:
-When I do single click I need to toogle between map and objective.
-When I do double click I need to modify buttons to activate zoom.

The problem is that single click can't occur when double click occurs.

What happens if you put the double click first?

It has the same behavior

Ok I indeed see the problem now:

  1. If you only apply a double click handler on a shape, you get correctly a double click event:


  2. If you only apply a single click handler on a shape, you get correctly a single click event:


  3. But if you apply both a single click and double click handler on a shape, you get incorrectly 3 events instead of only 1 double click event:


In case of a click event I need to start a timer and only send that event if no second click event has arrived during that time interval (e.g. 400 ms). Otherwise I should consider both click events as one double click event.

There are two disadvantages of this approach:

  • All the single click events will get a delay of that time interval (e.g. 400 msec).
  • I don't know if this change will break existing flows: perhaps people want two separate successive click events, instead of a single click event ...

For both reasons I am now wondering whether I should add a checkbox on the config screen to activate this behaviour explicit (default disabled). Because I assume most people will use only single click events, and they don't want such an extra delay...

Anyway I will try to find some time this weekend to fix this...

1 Like

hopefully you would only need to add the delay IF the double click behaviour was added. If not enabled then single clicks should work as is.

1 Like

Hey Dave,
I was also thinking about that. Thanks for confirming my thoughts!

@BartButenaers I only have this problem because I have 2 functionalities to the same button.
How can I make the timer in the javascript code? How can I set a global var for entier code?

Sorry can't give you a code example now. I'm on my way to a BBQ with my team, where I will see my collegues again in 3D for the first time since 1.5 years ...


Bart, I don't think this is something ui-svg should handle. It is actually how it is with SVG click and double click handlers work.

The recommended solution is not to use both (single and double click) events on the same control.

If you do then you should be prepared to work around it.

Hey Steve,
you are right that this might not be our job to handle it.
But I can imagine in this kind of use cases that it might be useful to handle both event types on a single shape. For example you double click on a device's icon in a floorplan, and you want to execute different actions on a single click or double click.
Therefore I have implemented a fix. But it only becomes active if both event handler types are being specified on a single shape, to avoid that all single click events become delayed.

@samuelbras: if I have implemented the fix on Github, both for normal events and Js events. You can install it directly from the Github repository via this command (executed within your .node-red folder):

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

It would be nice if you could do some tests, before I publish it on NPM.

1 Like

Here is a simple example flow, which displays a red circle and a green circle:

[{"id":"ab3a4e6a9e4dbcbe","type":"ui_svg_graphics","z":"3e329e777a5729f1","group":"28cdac6db4804909","order":3,"width":0,"height":0,"svgString":"<svg x=\"0\" y=\"0\" height=\"100\" viewBox=\"0 0 100 100\" width=\"100\" xmlns=\"\" xmlns:svg=\"\" xmlns:xlink=\"\">\n  <circle id=\"red_circle\" cx=\"25\" cy=\"30\" r=\"20\" stroke=\"none\" stroke-width=\"3\" fill=\"red\">\n  </circle>\n  <circle id=\"green_circle\" cx=\"75\" cy=\"30\" r=\"20\" stroke=\"none\" stroke-width=\"3\" fill=\"green\">\n  </circle>\n</svg>","clickableShapes":[{"targetId":"#red_circle","action":"dblclick","payload":"#red_circle","payloadType":"str","topic":"DOUBLE_CLICK"},{"targetId":"#red_circle","action":"click","payload":"#red_circle","payloadType":"str","topic":"SINGLE_CLICK"}],"javascriptHandlers":[{"selector":"#green_circle","action":"click","sourceCode":"$scope.send({topic:\"JS_SINGLE_CLICK\"})"},{"selector":"#green_circle","action":"dblclick","sourceCode":"$scope.send({topic:\"JS_DOUBLE_CLICK\"})"}],"smilAnimations":[],"bindings":[],"showCoordinates":false,"autoFormatAfterEdit":false,"showBrowserErrors":false,"showBrowserEvents":false,"enableJsDebugging":false,"sendMsgWhenLoaded":false,"outputField":"payload","editorUrl":"//","directory":"","panning":"disabled","zooming":"disabled","panOnlyWhenZoomed":false,"doubleClickZoomEnabled":false,"mouseWheelZoomEnabled":false,"dblClickZoomPercentage":150,"name":"","x":410,"y":620,"wires":[["b56c29126796965e"]]},{"id":"b56c29126796965e","type":"debug","z":"3e329e777a5729f1","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"topic","targetType":"msg","statusVal":"","statusType":"auto","x":600,"y":620,"wires":[]},{"id":"28cdac6db4804909","type":"ui_group","name":"External SVG file demo","tab":"3667e211.c08f0e","order":1,"disp":true,"width":"10","collapse":false},{"id":"3667e211.c08f0e","type":"ui_tab","name":"Showcase","icon":"dashboard","order":1,"disabled":false,"hidden":false}]
  • The red circle has both a click and a double-click event listener:


  • The green circle has both a (client side) Javascript click and a double-click event listener:


The following demo shows what happens when I first (single) click both circles, and afterwards double click both circles:


1 Like

Nice work Bart.

However it is now non standard compared to DOM events. What if someone actually wants the click and double click events?

Tbh, I would have provided an example flow using a trigger/delay to differentiate click & double click.

Hi @BartButenaers

On monday I will do the test and leave feedback about it.
Thanks for this quick response.

@Steve-Mcl I understand your point, but when you have a limit number os buttons, you need to include 2 handlers in one button. In my case I can only have 3 buttons for all functionalities.

That was initially my reason to add a checkbox in the settings tabsheet, to require explicit activation of this behaviour. I haven't added it yet, but I should implement it. And deselect it by default, to make sure standard DOM behaviour is offered by default

Can you explain that a bit in detail? Not sure what you mean...

By default the single click events/messages won't be suppressed anymore. The new behaviour should be enabled explicit:


The documentation on the readme pages has been updated.

1 Like

I would argue that you don't need to add this extra complication until someone actually requests it (with a real need).

Sure. What I was trying to convey Bart is, this is easy to handle by the user without a src modification that changes the standard DOM events & I would have instead put a demo flow in the examples for import (via CTRL+I) for the users to try out.

e.g. something like this...

But now it is done, no worries - its not a big issue. Baking it in as you have is more user friendly after all.

Hey Dave,
Indeed that would be another way to tackle it. But I was now completely submerged into this code snippet, so wanted to avoid having to start digging again in the near future perhaps...

Ah ok. Thanks for the clarification and demo flow!