# Contextmenu location

**URL:** https://discourse.nodered.org/t/contextmenu-location/22780
**Category:** Developing Nodes
**Created:** [7 March 2020 22:46 UTC](https://discourse.nodered.org/t/contextmenu-location/22780 "2020-03-07T22:46:23Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)
#### Post date: [7 March 2020 22:46 UTC](https://discourse.nodered.org/t/contextmenu-location/22780/1 "2020-03-07T22:46:23Z")

</div>

Hi folks,

Currently the _node-red-ui-contextmenu_ node can be displayed at a location that is specified:

- In the _ **input message** _. For example when you click on an SVG shape, the _node-red-contrib-ui-svg_ node sends the mouse-click coordinates in the output message, which can be used by the contextmenu node to show the menu nicely where the mouse has being clicked.
- In the config screen as a _ **fixed** _ location (x and y coordinates). For example when a dashboard button is being clicked, no coordinates will be available in the output message (so you need to used a fixed location).

@Paul-Reed has a problem with following flow:

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/8/7/87e10d3fec47977d4ef0b904f9abee334830b1e8.png)

```auto
[{"id":"b3e815dc.72d658","type":"ui_context_menu","z":"434e5cf6.9faa04","group":"b6d02685.824a58","order":17,"width":0,"height":0,"fontSize":16,"position":"fixed","outputField":"payload","xCoordinate":"125","yCoordinate":"118","menu":"fixed","menuItems":[{"id":"1","icon":"fa-arrow-right","label":"Realtime Power","topic":"dash","payload":"Realtime Power","payloadType":"str","visible":true,"enabled":true},{"id":"2","icon":"fa-heart","label":"Historical Energy","topic":"dash","payload":"Historical Energy","payloadType":"str","visible":true,"enabled":true}],"colors":"native","textColor":"#000000","backgroundColor":"#ffffff","borderColor":"#626262","intervalLength":"0","intervalUnit":"secs","startTimerAtOpen":true,"startTimerAtLeave":true,"stopTimerAtEnter":true,"name":"Menu","x":670,"y":280,"wires":[[]]},{"id":"721ee856.4907d8","type":"ui_button","z":"434e5cf6.9faa04","name":"","group":"b6d02685.824a58","order":2,"width":2,"height":1,"passthru":false,"label":"","tooltip":"","color":"","bgcolor":"#2A2A2A","icon":"fa-navicon fa-2x","payload":"","payloadType":"str","topic":"","x":510,"y":280,"wires":[["b3e815dc.72d658","e69ef5e8.3eda68"]]},{"id":"1440d7ac.5854a8","type":"ui_button","z":"434e5cf6.9faa04","name":"","group":"b6d02685.824a58","order":4,"width":2,"height":1,"passthru":false,"label":"My button","tooltip":"","color":"","bgcolor":"","icon":"","payload":"","payloadType":"str","topic":"","x":520,"y":240,"wires":[[]]},{"id":"e69ef5e8.3eda68","type":"debug","z":"434e5cf6.9faa04","name":"Coordinate test","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":700,"y":340,"wires":[]},{"id":"b6d02685.824a58","type":"ui_group","z":0,"name":"flowtest","tab":"eb2b42a7.665b9","disp":true,"width":22,"collapse":false},{"id":"eb2b42a7.665b9","type":"ui_tab","z":0,"name":"Test","icon":"dashboard","order":6}]

```

When the button is clicked, a message (_ **without coordinates** _) is being send to the contextmenu node. The contextmenu node shows the menu at a fixed location. But when the screen is resized, the menu is _ **not** _ drawn on top of the button anymore:

![contextmenu_location](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/d/0/d068b0ef311871d5d2c75feb7fc3cc5537ce1169.gif)

I 'think' are two valid solutions for this problem.

1. The _ **contextmenu node** _ [currently](https://github.com/bartbutenaers/node-red-contrib-ui-contextmenu/blob/master/context_menu.js#L304) displays the menu at clientx and clienty:

2. The _ **dashboard button** _ node could send the clicked coordinates (and perhaps if possible the bounding box as suggested in [this](https://discourse.nodered.org/t/announce-node-red-contrib-ui-contextmenu/16211/46) discussion):

> [@\[Announce\] node-red-contrib-ui-contextmenu](https://discourse.nodered.org/t/announce-node-red-contrib-ui-contextmenu/16211/46):
>
> But instead of creating combinations of nodes, " _perhaps_ " a UI node could send:
> 
> - The _clicked coordinates_ (like we currently do)
> - The _bounding box (minX, minY, maxX, maxY) of the element that has been clicked_ .
> 
> Then you can calculate in your flow where you want to show the contextmenu. E.g. when you want to have the contextmenu to appear in the center of a button, then you just calculate the center of the button yourself. (ButtonNode --\> FunctionNode (calculate the location) --\> ContextMenuNode).

I will implement the first solution anyway, but the second solution would be much easier to use. But not sure if our friend @dceejay will agree with this proposal, since his impact analyses are always better than mine ...

Thanks for any suggestions!!  
Bart

---

<div class="post-metadata">

### Author: ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)
#### Post date: [8 March 2020 07:20 UTC](https://discourse.nodered.org/t/contextmenu-location/22780/2 "2020-03-08T07:20:29Z")

</div>

BTW @Christian-Me had also a third solution (see [discussion](https://discourse.nodered.org/t/announce-node-red-contrib-ui-contextmenu/16211/44)):

> [@\[Announce\] node-red-contrib-ui-contextmenu](https://discourse.nodered.org/t/announce-node-red-contrib-ui-contextmenu/16211/44):
>
> Or a general upgrade to the ui-control node to emit x.y coordinates on every mouse press ("Output: mouse events") perhaps here:  
> ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/0/f/0f9a11864bb20196bbd3e83b6f626fbcfd4ee467.png)  
> Than would be "universal" solution and only there if needed

But I have never used the ui\_control node, so I cannot judge about this one ...

---

<div class="post-metadata">

### Author: ![Christian-Me](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/christian-me/32/10774_2.png) [@Christian-Me](https://discourse.nodered.org/u/Christian-Me)
#### Post date: [8 March 2020 09:14 UTC](https://discourse.nodered.org/t/contextmenu-location/22780/3 "2020-03-08T09:14:11Z")

</div>

Verry useful node. Currently emits a message when a client connects or looses a connection to the dashboard. And when the user of the dashboard changes tabs.

For our problem I would wish for another option: message when mouse click left, right, hold, released, clicked, taped (...) containing an object with the absolute and relative coordinates, the coordinates of the widget under the mouse and a widget identifier or the position in the dashboard tree (tab/group/widget)

---

<div class="post-metadata">

### Author: ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)
#### Post date: [8 March 2020 10:17 UTC](https://discourse.nodered.org/t/contextmenu-location/22780/4 "2020-03-08T10:17:24Z")

</div>

As always - Pull Requests are welcome. But all this does sound like an awful lot of extra traffic from front end to back and back again... Most context menu type implementations are front end only.

Admittedly the Node-RED style is that everything goes via the flow on the server - but adding all these events seems like an awful lot of plumbing and traffic for a small use case.

Would it not be possible to add a mouse click listener to the contextmenu node itself so it can handle any right clicks itself - and as a result get accurate co-ordinates.

---

<div class="post-metadata">

### Author: ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)
#### Post date: [8 March 2020 10:30 UTC](https://discourse.nodered.org/t/contextmenu-location/22780/5 "2020-03-08T10:30:46Z")

</div>

> [@dceejay](#):
>
> add a mouse click listener to the contextmenu node itself so it can handle any right clicks itself

Could perhaps do this, but currently they use a standard dashboard button. As soon as they _ **left-mouse** _ (or via touch?) click, the button sends a message to the Node-RED flow. There they can compose a contextmenu structure in a function node, and then have the contextmenu node to show that structure. In my personal opinion, the contextmenu node shouldn't mess up that nice process by intercepting events. But I may be mistaken...

---

<div class="post-metadata">

### Author: ![Christian-Me](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/christian-me/32/10774_2.png) [@Christian-Me](https://discourse.nodered.org/u/Christian-Me)
#### Post date: [8 March 2020 11:18 UTC](https://discourse.nodered.org/t/contextmenu-location/22780/6 "2020-03-08T11:18:31Z")

</div>

Another Idea (and question if this could be feasible)  
Assuming that is a niche application:  
Make ui-control to accept a callback function via `msg.ui_control.onMouseClick=“function (mouseInfo) {.... this.send(...)}”`  
The callback function can filter the relevant data on client side and only emit a message to the backend if useful.  
Basically this is how I did it in my remote-device-table with ui-table/tabulator.

> [@\[Announce\] remote device table (and collaboration wanted)](https://discourse.nodered.org/t/announce-remote-device-table-and-collaboration-wanted/22505):
>
> Hello after a lot of work (perhaps too much work) I like to share my first beta version of a flow to display the status of remote devices on the dashboard. It is always good to have an eye on your sensors and actuators especially when they are connected wireless or battery powered. The flow first developed around my homie-convention-node but soon I decided to make it more versatile because I have devices around the house which not support the homie convention. [teaser] Currently supported are…

This could perhaps keep traffic to a minimum and no confusion options for normal users.

---

<div class="post-metadata">

### Author: ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)
#### Post date: [8 March 2020 11:49 UTC](https://discourse.nodered.org/t/contextmenu-location/22780/7 "2020-03-08T11:49:37Z")

</div>

you mean apart from the security implications of allowing the sending of random bits of javascript into the page ?

---

<div class="post-metadata">

### Author: ![Christian-Me](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/christian-me/32/10774_2.png) [@Christian-Me](https://discourse.nodered.org/u/Christian-Me)
#### Post date: [8 March 2020 14:02 UTC](https://discourse.nodered.org/t/contextmenu-location/22780/8 "2020-03-08T14:02:56Z")

</div>

Yes! I know about the risks ✔- proceed 😉

But you are right I'm always concerned about risks even if I can`t evaluate the consequences in detail. Talking about risks ... I always question my self how can I know if in a nice contrib-node which works great opens a hidden backdoor of some kind or doing some nasty stuff inside the frontend 🤫. I have the same concerns when I install a custom firmware or even use a library/framework in my ESP8266 projects: There is everything available WiFi SSID + password, network access .... And even when it is open source who reads and understand many thousands lines of c-code? 🧐

But if you think there is a real risk and no way to "sandbox" it a way then the answer might be No ❌  
Totally fine with that.

---

<div class="post-metadata">

### Author: ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)
#### Post date: [8 March 2020 17:54 UTC](https://discourse.nodered.org/t/contextmenu-location/22780/9 "2020-03-08T17:54:38Z")

</div>

@BartButenaers so is this "only" a problem about the button widget ? As they are currently the only widgets that register an ng-click handler - I don't want to start adding to others. (OK the switch does but that doesn't make sense in this context).

If we do this then it would have to be a new msg property (msg.click ?) as we can't overload the existing payload without breaking things...

---

<div class="post-metadata">

### Author: ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)
#### Post date: [8 March 2020 19:40 UTC](https://discourse.nodered.org/t/contextmenu-location/22780/10 "2020-03-08T19:40:40Z")

</div>

> [@dceejay](#):
>
> so is this "only" a problem about the button widget

Well, to be honest I will only use the contextmenu myself in combination with the svg node. But I could understand that @Paul-Reed wanted to support a button, since - like you say - it already supports a click handler (so should be doable to send coordinates in e.g. your msg.click field).  
But most probably someone will need a contextmenu in the future on his UI table widget, and so on... Therefore the proposal about the ui-control node made sense for me, since it would offer a general solution for all widgets. But I assume it would be very hard to implement. And like you say, you have to assure that your flow is not going to be overwhelmed with events.  
Personally I think it is better to create a separate implementation for each widget, instead of a general solution:

- We have done it already for the svg node.
- @hotNipi has done it for his state trail node. Advantage is that he calculates and sends information about the clicked timeslice. That kind of information would never be available in a global click handler solution.
- Somebody could do it now or the button node.
- Somebody could do it in the future for the table node. It could e.g. contain the selected row nr and column nr ...
- ...

Summarized I think a separate click handler in each widget could include very specific useful information, which is not available otherwise. So I vote for a simple msg.click on the button node...

---

<div class="post-metadata">

### Author: ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)
#### Post date: [8 March 2020 19:47 UTC](https://discourse.nodered.org/t/contextmenu-location/22780/11 "2020-03-08T19:47:50Z")

</div>

Simple example to explain my statement. The state trail node shows a series of coloured timeslices. But in fact it is a single html element filled with a complex gradient. When you click on it, you want to know which timeslice has been clicked. With a general click handler, you will always get the same single html element (doesn't matter which timeslice is being clicked...). But currently the clicked timeslice is being calculated inside the widget, which is much better info ...

---

<div class="post-metadata">

### Author: ![hotNipi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hotnipi/32/383_2.png) [@hotNipi](https://discourse.nodered.org/u/hotNipi)
#### Post date: [8 March 2020 20:02 UTC](https://discourse.nodered.org/t/contextmenu-location/22780/12 "2020-03-08T20:02:58Z")

</div>

If it will be more widely used, the click metadata property name should be somehow unified.  
I did it that way, but this is me and my already well known not so correct English.  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/8/8/880ac4774bfdb81b30277ed61550e3931edf0ae5.png)

---

<div class="post-metadata">

### Author: ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)
#### Post date: [8 March 2020 20:09 UTC](https://discourse.nodered.org/t/contextmenu-location/22780/13 "2020-03-08T20:09:43Z")

</div>

> [@hotNipi](#):
>
> the click metadata property name should be somehow unified

Yes that would be nice, but then we would already have backwards compatibility issues. Because this is what we currently send for the SVG node:

```auto
"coordinates": {
   x: 195.3749237060547,
   y: 201.20571899414062
}
"elementId": "circle"
"event": "click"
"payload": {
   elementId: "cam3spin",
   status: "start"
}
"position": {x: 854, y: 284}
"selector": undefined
"topic": "circle"

```

P.S. We also send the "event" because we support a whole series of events... And the "elementId" is the id of the clicked element, since an SVG can contain LOT's of elements...

---

<div class="post-metadata">

### Author: ![Paul-Reed](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/paul-reed/32/66906_2.png) [@Paul-Reed](https://discourse.nodered.org/u/Paul-Reed)
#### Post date: [8 March 2020 20:16 UTC](https://discourse.nodered.org/t/contextmenu-location/22780/14 "2020-03-08T20:16:40Z")

</div>

> [@BartButenaers](#):
>
> But I could understand that @Paul-Reed wanted to support a button, since - like you say - it already supports a click handler

To put into context what I'm doing, it's to hide the dashboard's Nav menu, and then navigate by using the contextmenu node.  
The contextmenu node cascades the menu items, and looks IMO much better than the Nav menu.  
It's a work in progress, and not all pages have been built!

 ![example](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/f/6/f6d7b32c8b9d7fe14cba0564821b1f851a9e8513.gif)

---

<div class="post-metadata">

### Author: ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)
#### Post date: [8 March 2020 20:20 UTC](https://discourse.nodered.org/t/contextmenu-location/22780/15 "2020-03-08T20:20:36Z")

</div>

Cool !!!! 👍 👍 👍  
With a button it is simple: there is only one element, and that is being clicked. So a general click handler would also do the job for you. But for most other widgets, it seems to me that you wouldn't have enough information when you know which html element has been clicked. In those cases, you need to get more functional information from the widget about what/where you have clicked.

---

<div class="post-metadata">

### Author: ![Paul-Reed](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/paul-reed/32/66906_2.png) [@Paul-Reed](https://discourse.nodered.org/u/Paul-Reed)
#### Post date: [8 March 2020 20:28 UTC](https://discourse.nodered.org/t/contextmenu-location/22780/16 "2020-03-08T20:28:15Z")

</div>

> [@BartButenaers](#):
>
> So a general click handler would also do the job for you

Yes, but when I view the same tab in different browsers, the menu appears at different screen locations. Example, the same tab on my phone.

 ![phone](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/c/2/c2331b5206d4a1b5ae8b307c603efecd1eea8de8.png)

---

<div class="post-metadata">

### Author: ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)
#### Post date: [8 March 2020 20:56 UTC](https://discourse.nodered.org/t/contextmenu-location/22780/17 "2020-03-08T20:56:26Z")

</div>

So if I add position to the button msg that would help fix that ? But as noted there are now two formats of possible property. I think `clickCoordinates` is more self-explanatory vs the more generic `position`.  
Thoughts

---

<div class="post-metadata">

### Author: ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)
#### Post date: [8 March 2020 21:00 UTC](https://discourse.nodered.org/t/contextmenu-location/22780/18 "2020-03-08T21:00:30Z")

</div>

> [@dceejay](#):
>
> I think `clickCoordinates` is more self-explanatory vs the more generic `position` .

Yes I agree. But I'm not going to change my `position` field, to avoid breaking all flows.

---

<div class="post-metadata">

### Author: ![Paul-Reed](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/paul-reed/32/66906_2.png) [@Paul-Reed](https://discourse.nodered.org/u/Paul-Reed)
#### Post date: [8 March 2020 21:20 UTC](https://discourse.nodered.org/t/contextmenu-location/22780/19 "2020-03-08T21:20:00Z")

</div>

> [@dceejay](#):
>
> So if I add position to the button msg that would help fix that ?

That wasn't my suggestion, I'm just explaining my user case for the `contextmenu` node. The technicalities of a solution is above my pay grade unfortunately 🤔

---

<div class="post-metadata">

### Author: ![Christian-Me](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/christian-me/32/10774_2.png) [@Christian-Me](https://discourse.nodered.org/u/Christian-Me)
#### Post date: [8 March 2020 21:24 UTC](https://discourse.nodered.org/t/contextmenu-location/22780/20 "2020-03-08T21:24:13Z")

</div>

Agree.  
May I ask to include the coordinates of that button too like x1.y1,x2,y2  
Sooner or later somebody (like me) would like to position the menu aligned to the lower left corner regardless of the actual mouse position. Another question: should it respond to right click only or left clicks too? Because a right click on a button (hamburger menu) seems not to be intuitive?

[Next page](https://discourse.nodered.org/t/contextmenu-location/22780.md?page=2)
