Is there a nicer way to do this with UI_Table


I tagged onto the back of a previous message with Examples about ui_Table, templates etc

What i am trying do i thought would be pretty simple

Essentially my electricity provider gives me 5 minute pricing offset 1 minute past the hour - so 9:01, 9:06, 9:11 in 1/2 hour blocks and then they reset and start again.

I want to present this information in a table that would look something like this


I can understand how to use NG-Repeat to cycle through an array of data and put it in the table, and a crude approach would be to simply have two elements in the array with Price and Time as the first two items in the two array elements, and then add the price and times to the elements as they come in - but this feels rather crude

Is there not a way to have the Headers for a table down the side - rather than across the top ?

I have not worked with Tabulator, Angular and Ng-repeat before so its been an uphill battle to this point.

And here is the example i am playing around with

[{"id":"81b95d62.bfbb1","type":"inject","z":"77c34825.37bd58","name":"Go","repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","payload":"1","payloadType":"str","x":310,"y":140,"wires":[["59dac1d9.b8de6"]]},{"id":"59dac1d9.b8de6","type":"function","z":"77c34825.37bd58","name":"build array (2)","func":"var arr =[[\"Price\",17,24,15,16,16,18],[\"Time\",\"13:01\",\"13:06\",\"13:11\",\"13:16\",\"13:21\",\"13:26\"]];\nmsg.payload = arr;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":480,"y":140,"wires":[["ffa391c5.78cbe"]]},{"id":"44c5693a.086dd8","type":"debug","z":"77c34825.37bd58","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1010,"y":140,"wires":[]},{"id":"ffa391c5.78cbe","type":"ui_template","z":"77c34825.37bd58","group":"6d14f4ec.23f8fc","name":"Two dimension array table","order":1,"width":"6","height":"6","format":"<table id=\"table\" border=\"1\">\n <caption>Caption</caption>\n <tr>\n <th></th>    \n <th>Period 1</th> \n <th>Period 2</th>\n <th>Period 3</th>\n <th>Period 4</th>\n <th>Period 5</th>\n <th>Period 6</th>\n </tr>\n <tbody>\n <tr ng-repeat=\"row in msg.payload\">\n <td ng-repeat=\"item in row\" >{{item}}</td>\n </tr>\n </tbody>\n</table>\n\n","storeOutMessages":false,"fwdInMessages":true,"resendOnRefresh":false,"templateScope":"local","x":700,"y":140,"wires":[["44c5693a.086dd8"]]},{"id":"6d14f4ec.23f8fc","type":"ui_group","name":"Default","tab":"40a21688.635fe8","order":1,"disp":true,"width":"6"},{"id":"40a21688.635fe8","type":"ui_tab","name":"Home","icon":"dashboard","order":9}]

Two issues with this

  1. It seems crude to include the two row names as part of the array
  2. It is dropping my first Row for some reason


It looks like it's the repeating value in your "Price" array. I removed the duplicate "16' and changed it to "19" and it worked.
Screen Shot 2021-07-08 at 9.16.29 AM

Take a look at this thread:
Repeating values in ui_table

Hi @craigcurtin,

the problem aren't the duplicates per se. It's the way Angulars ngRepeat handles arrays by default.
AngularJS logs an error to your browser's JS console in that case.

The solution is to explicitly tell it to use the array index by adding track by $index to your expression.

The following should work with your data:

 <tr ng-repeat="row in msg.payload track by $index">
 <td ng-repeat="item in row track by $index" >{{item}}</td>

See for details.

1 Like

I was going to post the same thing after playing around with it! Quick question just for curiosity - is there any reason to have the "track by $index" in the table row tag? This seems to also work:

<table id="table" border="1">
 <th>Period 1</th> 
 <th>Period 2</th>
 <th>Period 3</th>
 <th>Period 4</th>
 <th>Period 5</th>
 <th>Period 6</th>
 <tr ng-repeat="row in msg.payload">
 <td ng-repeat="item in row track by $index" >{{item}}</td>

Yes, it is, because both inputs are arrays and could contain duplicates, which will lead to the error you've seen.

It's common practice and explained in the official docs I linked to. :wink:


have you took node-red-node-ui-table (aka. Tabulator) into account. The data will have to be formatted slightly different and you will have to define a time formatted column (easy possible via msg.ui_control).

But in the end very versatile with possibility to graphically visualize your the price via a customized progress formatter, filtering sorting and a lot of other things

Let me know if you need any help with that.

msg.payload =[
    }, {
    }, {
    }, {
    }, {
    }, {
return msg;
1 Like

Thanks everyone for the solutions and explaining what i was doing wrong. As i said - new to all of the Tabulator stuff and Ui-table etc - so big learning curve there !!

@Christian-Me - thanks for the kind offer with ui-table and ui-control.

If you could (dunno how much time it would be) knock up this same thing like you have said so i can compare them it would be a good way for me to start learning it i guess !!

I have seen your nodes and subflow that you published for building tables but that is way above where my brain is at at the moment !!


Wow - just looked at the two examples you linked to - very slick - but it looks like a couple of light year steps ahead of where i am now !


This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.