Custom Dashboard node without md-card - possible?

Hi folks,

Steve ( @Steve-Mcl ) and I are developing node-red-contrib-ui-contextmenu.

This ui node generates a simple “div” and “ul” element, which is filled and styled afterwards as soon, when a context menu needs to be showed somewhere in the Node-RED dashboard.

var html = String.raw`
            <style>
                …
            </style>
            <div …>
                <ul class="menu-options">
                </ul>
            </div>
`;

This works fine. However the dashboard generates a wrapping “md-card” element, which uses some empty space in the dashboard.

That is however not what we want, since our contextmenu widget won't be displayed there...
Does anybody knows how we can solve this?

P.S. If I’m not mistaken, the dashboard’s audio widget also doesn’t take any space??

Thanks a lot!!
Bart

But how do you know where they will be displayed ? Have you consider using CSS pseudo elements Like ::before ::after ?

Hei Andrei,
We developed the contextmenu node to support popup menus in our svg-node: when an svg shape is clicked, we send an output message which contains the click coordinates. Our users can - if they want - wire that message to our contextmenu node, which displays an appropriate context menu at that location. There will be - most probably - other use cases for the contextmenu node, but that is how we use it at this moment.

But it is annoying that it uses space at a location in the dashboard, since we will never show the menu at that location. So hopefully somebody has a solution...

@BartButenaers

The ui_template node has an option "add to head" that doesnt take up any space on the dashboard.

I wonder is it possible that if we set templateScope to "global" would we be able to insert items into <body> and would the send() & $scope functionality still work?

What you guys are doing is awesome. I am subscribed to the github notifications and find astonish how fast you are moving (faster than I can follow up). Assuming that there is no way to add the node without adding extra space (which I believe it is the case for the Dashboard), can´t you consider another possibilities ? Perhaps something along the lines of below snippet ? In such case the context menu would be code doing CSS manipulations basically. Again, this is just a shot in the dark, I had no time to stop to read what you have already done.

[{"id":"6c1b6c44.995624","type":"ui_template","z":"58634fa3.16dc6","group":"3dfd1195.df4f4e","name":"","order":5,"width":"6","height":"12","format":"<!DOCTYPE html>\n<html>\n<head>\n<style> \n\n.dropdown {\n  position: relative;\n  display: inline-block;\n}\n\n.dropdown-content {\n  display: none;\n  position: absolute;\n  min-width: 200px;\n  background-color: #ff0000;\n  z-index: 1;\n}\n\n.dropdown-content li {\n  color: black;\n\n}\n\n\n</style>\n\n</head>\n\n<body>\n\n<div class=\"dropdown\">\n\n<svg  width=\"200\" height=\"50\" onclick=\"myFunction()\">\n    <rect x=\"0\" y=\"0\"  width=\"200\" height=\"50\" fill=\"white\"/>\n    <text x=\"10\" y=\"25\" fill=\"red\">This is an SVG element</text>\n</svg>\n\n\n  <div class=\"dropdown-content\" id=\"myDIV\">\n<ul >\n  <li>Coffee</li>\n  <li>Tea</li>\n  <li>Milk</li>\n</ul>\n</div>\n\n\n</div>\n\n<script>\nfunction myFunction() {\n  var x = document.getElementById('myDIV');\n  if (x.style.display === 'none') {\n    x.style.display = 'block';\n  } else {\n    x.style.display = 'none';\n  }\n}\n</script>\n\n</body>\n</html>\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":580,"y":120,"wires":[[]]},{"id":"3dfd1195.df4f4e","type":"ui_group","z":"","name":"T1","tab":"d50effcd.c6b68","disp":false,"width":"16","collapse":false},{"id":"d50effcd.c6b68","type":"ui_tab","z":"","name":"Test","icon":"dashboard","order":9}]
3 Likes

Hi Andrei, thanks for taking the time to assist. I will look at what you are proposing when I get a minute.

Perhaps an image may help...
menu

We add the context menu to the body of the document from within our custom node. Upon a msg, we call its function to show it. The md-card is pretty much unused but is still present on the page taking up space.

If the dashboard has a way of letting a custom node add to the page (head and body) without generating the md-card (perhaps zero width/zero height) & still permits the ability to send() a msg - this is what we are looking for. NOTE: zero height/width doesnt work :frowning:

I suspect it isnt currently possible but hope we find a way.




For anyone insterested in the graphic - the camera, apple, ambulance etc are all font-awsome icons in svg <text> elements. The fly out box with pencil, star and circle are an SVG <g> group animated to show/hide by our nodes animation capabilities. The context menu is HTML and can be built statically or dynamically (by msg.menu). The SVG node has a list of actions that feed a msg to the contextmenu node to make it appear.

2 Likes

Ah - I missed that comment

I'll take a look at that later (beer time :beers:)

Sadly the audio node is a core widget. Extra widgets are all baed around the template widget and that detects if there is any html inside itself and assumes that if there is then it must be added to the screen. We use 0 to mean automatic so by default that then defaults to one unit height.

Thanks for taking the time to reply. Appreciated.

Have you any thoughts on how we might achieve this?

Cheers.

Given that I default it to 1 unit high in a hacky way - I can also add a hacky way to set it to 0 - but it would not be in existing dashboards etc... so not ideal (in many ways).

That would help for new users.

Perhaps -1 would equate to no md-card? Or undefined?

I would appreciate it as we have ideas for other similar functioning nodes.

Please let us know either way.

Properties with negative values for width and height will be just ignored

Hi,

Sorry if I wasnt clear, I meant if when the widget is initialised and -1 or undefined is specified then the same funky workaround @dceejayusee for the audio UI widget could possibly be applied. (of course this depends on the workaround be added to dashboard).

OK -have pushed to master - if config.height == -1 then it should set it to 0 height...

1 Like

Thanks a lot Dave!!!!
We will test that this weekend.
And for existing dashboards, we will mention in our readme file: "if you upgrade to dashboard version xx, the empty space problem will be solved".

well - we don't know it works yet...

I'm already positive, based on extrapolation of the quality of your fixes in the past :lying_face: :rofl:

1 Like

Hah. If I wrote it properly in the first place I wouldn’t need to fix it !

5 Likes

Thank you so much. Will test tomorrow (hopefully) and let you know.

Ps, on a related note, I noticed the audio node still appears in the layout editor (even though you can't set the size of the audio node) would it be something you could handle - e.g if height/width is zero, don't show it in the dashboard layout? No Biggie, just for completeness.

Allmost forgotten ...
In case anybody ever needs this feature, Dave (@dceejay) has been so kind to fix this last week in dashboard version 2.16.3.

We only had to do the following changes to our UI contribution node, to get a height of 0 in the dashboard:

  1. We had to remove the "Size" property from our config screen:

    image
    By removing simply this part from our html:

    <div class="form-row" id="template-row-size">
         <label><i class="fa fa-object-group"></i> Size</span></label>
         <input type="hidden" id="node-input-width">
         <input type="hidden" id="node-input-height">
         <button class="editor-button" id="node-input-size"></button>
    </div>
    
  2. The accompanying popup dialog (with the size selector) could also be removed from the oneditprepare function:

    $("#node-input-size").elementSizer({
       width: "#node-input-width",
       height: "#node-input-height",
       group: "#node-input-group"
    });
    
  3. And the height had to be set to -1:

    defaults: {
       ...
       height: {value: -1},
       ...
    },
    

As a result Dave's fix even doesn't generate an md-card element in the dashboard, so it takes no space at all...

3 Likes