Tuesday, December 12, 2017

Node-RED Dashboard - Button versus Template node

As mentioned in the previous post, Node-RED has a set of nodes to allow one to develop dashboard panels and one of these nodes is the button node.




When used it will produce a standard button on the dashboard. The button design is not very appealing indeed.



While browsing the Node-RED Google group I came across a post that shows how to create a fancier button using another node from the dashboard: the Node Template.


This node allows to format a widget in the dashboard using  HTML, CSS (Cascading Style Sheets), Angular JS directives, SVG directives and therefore requires some specific configuration. The design of your widget will be limited by your imagination and of course your level of knowledge of those technologies.

It will toggle the text (from OPEN to CLOSED) and the colors (from green to red) when clicked.








Below a screenshot of the configuration added to the Template field in the configuration page of the node:





Above screenshot will not show the full configuration so I copy and pasted below:




<md-button class="vibrate filled touched bigfont rounded" style="background-color:#333333" ng-click="send({payload: msg.payload })">


<svg  width="260px" height="90px" version="1.1" viewBox="0 0 800 200">
 <g id="Button_Long">

  <rect fill="#333333" width="800" height="200"/>
  <g ng-style="{fill: (msg.payload || 0) ? 'lime' : 'red'}">
    <rect width="800" height="200" rx="80" ry="80"/>
  </g>

  <rect fill="#333333" x="11" y="10" width="778" height="180" rx="90" ry="90"/>
  <g ng-style="{fill: (msg.payload || 0) ? 'lime' : 'red'}">

    <text x="400" y="125" style="text-anchor:middle"  font-weight="bold" font-size="80" font-family="Arial">{{(msg.payload||0)? " OPEN " : "CLOSED"}} </text>
    </g>
  </g>
</svg>

</md-button>



Now the Node-Red flow. It is very simple. Just a function node to change the payload from true to false and the Template node to format the button in the dashboard.




[{"id":"53c6d477.fca0dc","type":"function","z":"c613eed5.ed874","name":"","func":"msg.payload =!msg.payload; \nreturn msg;\n","outputs":1,"noerr":0,"x":170,"y":80,"wires":[["5a829a9b.a41c64"]]},{"id":"5a829a9b.a41c64","type":"ui_template","z":"c613eed5.ed874","group":"70abbb93.b66df4","name":"OPEN-CLOSED SIGN","order":0,"width":"6","height":"2","format":"<md-button class=\"vibrate filled touched bigfont rounded\" style=\"background-color:#333333\" ng-click=\"send({payload: msg.payload })\"> \n\n\n<svg  width=\"260px\" height=\"90px\" version=\"1.1\" viewBox=\"0 0 800 200\">\n <g id=\"Button_Long\">\n  \n  <rect fill=\"#333333\" width=\"800\" height=\"200\"/>\n  <g ng-style=\"{fill: (msg.payload || 0) ? 'lime' : 'red'}\">\n    <rect width=\"800\" height=\"200\" rx=\"80\" ry=\"80\"/>\n  </g>\n  \n  <rect fill=\"#333333\" x=\"11\" y=\"10\" width=\"778\" height=\"180\" rx=\"90\" ry=\"90\"/>\n  <g ng-style=\"{fill: (msg.payload || 0) ? 'lime' : 'red'}\">\n      \n    <text x=\"400\" y=\"125\" style=\"text-anchor:middle\"  font-weight=\"bold\" font-size=\"80\" font-family=\"Arial\">{{(msg.payload||0)? \" OPEN \" : \"CLOSED\"}} </text>\n    </g>\n  </g>\n</svg>\n\n\n</md-button>\n","storeOutMessages":false,"fwdInMessages":false,"templateScope":"local","x":160,"y":200,"wires":[["53c6d477.fca0dc","925ffb0a.fbb218"]]},{"id":"925ffb0a.fbb218","type":"debug","z":"c613eed5.ed874","name":"","active":true,"console":"false","complete":"false","x":410,"y":200,"wires":[]},{"id":"70abbb93.b66df4","type":"ui_group","z":"","name":"Control Panel","tab":"4ce637e8.4ba768","order":2,"disp":true,"width":"8"},{"id":"4ce637e8.4ba768","type":"ui_tab","z":"","name":"Button Panel","icon":"dashboard"}]

7 comments:

Unknown said...

Happy New Year 2018! Great mod for the standard button! I'd like to use it like the "switch node" with messsges arriving on input but if I tick the "Pass through messages from input." the button goes crazy for a few seconds. Due to the loop I suppose but any tips how I could overcome that behaviour?
Br,
Jussi

Unknown said...

ok, I used it to steer the switch node so not a problem anymore...

Unknown said...

Hello Jussi, indeed you are right. The template node provides a fancy button design but it has a flaw in the initialization of the msg.payload. The code has to be patched in order to fix the erratic behavior. I did that by initializing msg.payload wiht the operator || and letting it to be only true or false. I will update the post later on. Thank you very much. I wish you a great 2018 !

MM said...
This comment has been removed by the author.
MM said...

Hi to all... I got forwarded to this link while seeking on how to create custom templates for node red... I'm not a programmer, nor a CSS stylist so please apologize my ignorance...
I checked the script and hopefully fond a way to fix it...
in the template object just replace the end of raw 1:

ng-click="send({payload: msg.payload })

with

ng-click="send({payload: !msg.payload })

and remove the function.
this way the payload toggle between true and false
hope this would help

Unknown said...

Wonderful tutorial!!
I'm using the button in my application and, in certain condition, I have the need to make invisible the entire button. How can I do?
Thanks in advance

Unknown said...

Hello and thank you. In node-RED (at least in the current version) it is not possible to hide only a single widget (a button for instance). There is a node that allows you to hide the whole group. If you hide the group all the widgets inside that group will be hidden. I have seen people using a trick to be able to hide only a button. Assuming you are using the standard dashboard button from node-RED (not a button customized with a template). Enter the button configuration dialog and set the field "background" to the value #333333 and redeploy the flow and refresh the dashboard. You will see that the button "disappeared". It is still there but having the same background color as the group panel will make it "invisible".