
Security News
Crates.io Users Targeted by Phishing Emails
The Rust Security Response WG is warning of phishing emails from rustfoundation.dev targeting crates.io users.
node-red-contrib-ui-contextmenu
Advanced tools
A Node-RED widget node to show a popup contextmenu in a Node-RED dashboard
A Node-RED node to display a popup contextmenu in the Node-RED dashboard
Special thanks to Stephen McLaughlin, my partner in crime for this node!
Run the following npm command in your Node-RED user directory (typically ~/.node-red):
npm install node-red-contrib-ui-contextmenu
It is advised to use Dashboard version 2.19.4 or above, to make sure the contextmenu doesn't appear automatically after deploy or refresh.
Although this node can display a context menu on top of any other dashboard widget, in fact we implemented this node to be used in combination with our node-red-contrib-ui-svg node.
Therefore the demo will explain how both nodes can be combined to show a context menu on top of a vector graphics drawing in the Node-RED dashboard:
msg.position
which contains the X/Y position of the mouse click)!msg.position
. Remark: it would make more sense to determine the list of context menu items, based on the msg.topic
which contains the information about which SVG element has been clicked).! CAUTION: The context menu will only appear when the dashboard group (see config screen) is currently visible !
A short demo to demonstrate the result:
The font size of the menu items
Specify how the position of the context menu on the screen will be specified:
Message Based: The input message must contain a msg.position.x
and a msg.position.y
field, which allows dynamic positions.
Fixed: Two input fields will be displayed (X Coordinate and Y Coordinate), to enter the fixed coordinates.
Specify where the payload output from clicking a menu item should appear in the msg
.
NOTE: for a msg based menu, this can be set per menu item via the property outputField
(see Message Based example below)
Specify how the menu items of the context menu will be specified:
Message Based: when selected, the input message must contain a msg.menu
field which holds the array of menu items.
An example input message:
"menu": [
{
"text": "Options",
"icon": "fa-list",
"sub": [
{
"text": "Edit",
"icon": "fa-edit",
"topic": "edit",
"payload": [ 1, 2, 3, 4, 5 ],
"payloadType": "JSON",
"outputField" : "editArray"
},
{
"text": "Cut",
"icon": "fa-cut",
"enabled": true,
"topic": "cut",
"payload": "true",
"payloadType": "bool"
}
]
},
{
"text": "---"
},
{
"text": "Delete",
"icon": "fa-trash",
"enabled": true,
"payload": "12",
"payloadType": "num"
},
{
"text": "---"
},
{
"text": "Quit",
"icon": "fa-times",
"enabled": false
}
]
Example flow with nested sub-menu:
[{"id":"fd05877e.cb0588","type":"ui_svg_graphics","z":"60ad596.8120ba8","group":"9f5b4cff.15cd3","order":1,"width":"14","height":"10","svgString":"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:svg=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" preserveAspectRatio=\"none\" x=\"0\" y=\"0\" viewBox=\"0 0 900 710\" width=\"100%\" height=\"100%\">\n <rect id=\"svgEditorBackground\" x=\"0\" y=\"0\" width=\"900\" height=\"710\" style=\"fill:none;stroke:none;\" />\n <image width=\"889\" height=\"703\" id=\"background\" xlink:href=\"https://www.roomsketcher.com/wp-content/uploads/2016/10/1-Bedroom-Floor-Plans.jpg\" />\n <circle id=\"mycircle\" cx=\"182.901\" cy=\"91.4841\" style=\"fill:rosybrown;stroke:black;stroke-width:1px;\" r=\"48\" /></svg>","clickableShapes":[{"targetId":"#mycircle","action":"click","payload":"camera_living","payloadType":"str","topic":"camera_living"}],"smilAnimations":[],"bindings":[{"selector":"#banner","bindSource":"payload.title","bindType":"text","attribute":""},{"selector":"#camera_living","bindSource":"payload.position.x","bindType":"attr","attribute":"x"},{"selector":"#camera_living","bindSource":"payload.camera.colour","bindType":"attr","attribute":"fill"}],"showCoordinates":false,"autoFormatAfterEdit":false,"outputField":"","editorUrl":"http://drawsvg.org/drawsvg.html","directory":"","name":"","x":920,"y":120,"wires":[["a4c84c93.c001d"]]},{"id":"c65edd5a.1c031","type":"ui_context_menu","z":"60ad596.8120ba8","group":"9f5b4cff.15cd3","order":5,"width":0,"height":-1,"fontSize":16,"position":"msg","outputField":"payload","xCoordinate":50,"yCoordinate":50,"menu":"msg","menuItems":[],"colors":"native","textColor":"#000000","backgroundColor":"#ffffff","borderColor":"#626262","name":"","x":1360,"y":120,"wires":[[]]},{"id":"a4c84c93.c001d","type":"change","z":"60ad596.8120ba8","name":"","rules":[{"t":"set","p":"menu","pt":"msg","to":"[{\"text\":\"Options\",\"icon\":\"fa-list\",\"sub\":[{\"text\":\"Edit\",\"icon\":\"fa-edit\",\"topic\":\"edit\",\"payload\":[1,2,3,4,5],\"payloadType\":\"JSON\",\"outputField\":\"editArray\"},{\"text\":\"Cut\",\"icon\":\"fa-cut\",\"enabled\":true,\"topic\":\"cut\",\"payload\":\"true\",\"payloadType\":\"bool\"}]},{\"text\":\"---\"},{\"text\":\"Delete\",\"icon\":\"fa-trash\",\"enabled\":true,\"payload\":\"12\",\"payloadType\":\"num\"},{\"text\":\"---\"},{\"text\":\"Quit\",\"icon\":\"fa-times\",\"enabled\":false}]","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":1140,"y":120,"wires":[["c65edd5a.1c031"]]},{"id":"9f5b4cff.15cd3","type":"ui_group","z":"","name":"Floorplan test","tab":"dabfe25b.13bc1","disp":true,"width":"14","collapse":false},{"id":"dabfe25b.13bc1","type":"ui_tab","z":"","name":"SVG","icon":"dashboard","disabled":false,"hidden":false}]
msg.menu
msg.topic
that will be send in the output message. If left empty, topic
will default the the path
of this menu item.msg.payload
that will be send in the output message. If left empty, message
will default the the text
of this menu item.msg.payload
. Allowable types are 'JSON', 'str', 'bool', 'num'. payload
will be converted to this type.payload
to be send to an alternative property of msg
Fixed: A table will be displayed, to enter the menu items. The following properties can be set for every menu item:
msg.topic
that will be send in the output message.msg.payload
that will be send in the output message. NOTE: if the "Output to" field is set to something other than "payload", then the output will appear in that property of msg
The message-based approach has the advantage that it offers nested menu items, which is currently not available in the config screen!
The label an icon are both optional. This means you can use both or only one of them, to achieve various effects.
0
the context menu will stay visible, until a menu item is selected or outside the menu is being clicked.3 seconds
this means that the context menu will automatically disappear when the context menu is out of focus during at least 3 seconds.
Demo of auto hide in 3 seconds (notice the timer status in the console):
Specify how the colors of the context menu should look like:
Native: The default CSS colors of this node will be used.
Match dashboard theme: The colors of the currently selected dashboard theme will be used.
Custom: Three color pickers will be displayed, which allow you to specify your custom colors.
Demo for the dashboard's built-in dark theme (menu1=custom, menu2=theme, menu2=native):
Demo for the dashboard's built-in light theme (menu1=custom, menu2=theme, menu2=native):
As soon as a menu item has been clicked, an output message will be send. It is up to the next nodes in the flow, to determine how the menu item should be handled.
The output message will contain following fields:
msg
. This can also be overriden per menu item by setting outputField
in the menu itemdsaul whose menu this node is based on https://github.com/dsaul/contextmenujs/
FAQs
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
The Rust Security Response WG is warning of phishing emails from rustfoundation.dev targeting crates.io users.
Product
Socket now lets you customize pull request alert headers, helping security teams share clear guidance right in PRs to speed reviews and reduce back-and-forth.
Product
Socket's Rust support is moving to Beta: all users can scan Cargo projects and generate SBOMs, including Cargo.toml-only crates, with Rust-aware supply chain checks.