The "code" inside your ui_template
node is sent to the dashboard for rendering, and since the node-red dashboard is an Angular v1.x app, you will be able to do a lot of conditional rendering logic -- once you understand the Ng directives (that's Angular's magic elements/attributes/syntax) that are available...
For example, this html <table>
element can be conditionally rendered using the ng-if test to see if there are any rows to display:
<table ng-if="msg.payload.length">
<caption class="nr-dashboard-color">Notification Logs</caption>
<tr>
<th>S.No</th>
<th>Notification No.</th>
<th>Date and Time</th>
<th>Status</th>
<th>Action</th>
</tr>
<tr ng-repeat="row in msg.payload">
<td>{{$index+1}}</td>
<td>{{row.notification}}</td>
<td>{{row.timestamp}}</td>
<td>{{row.status}}</td>
<td>
<button ng-click="send({payload: row.notification});"
ng-if="row.status!=='success'">Retry</button>
</td>
</tr>
</table>
Notice also the use of ng-repeat to iterate over the payload data array, and the ng-if
on the <button>
element in the last column of the table. This way, the button only appears when that row has a status not equal to "success".
Finally, I use the ng-click attribute on the button to get access to the Ng scope, which has the send(...)
method defined for returning data to the node-red flow downstream from my ui_template
node. In this example I am just sending the Notifaction No. back as the msg.payload -- but if you used ng-click="send({ payload: row });"
it would return the entire row as an object.
Once you fall down this rabbit hole of client-side logic and control, trust me you will no longer want to spend a bunch of time trying to build up your html page programatically! I still use the core template
node in mustache mode to do some simple variable substitution and array expansion, but Angular is much more powerful a solution for a use case like yours.