How do I get a single row of data (status indicators) in to a page

@TotallyInformation I am coming to a halt on how to get a table into my SPA UIBUILDER Dashboard. I can put the HTML Table into the code for the page and it displays 'roughly' how I want it (just needs a couple of CSS tweaks.).

As we can pass into a web page and get it to display how we want using uib-update, I assumed at first that if I assembled the correct HTML code, which I have - it copies and pastes into the page as direct input and formats how a Table would look in the code. But no, that doesn't seem to work.

I then tried using your 'no code' example using the 'uib-element' node, but it appears to require both Row and Column Data, all I want is a simple row. Using the Dev. Tools I can see where my injected code is supposed to go, but nothing displayc, just my Hard Code actualy written into the page.

Do you have any suggestion as to which direction I might be able to go to get this working?

You already know what my CSS knowledge is like! :sweat_smile:

[{"id":"dbe4874dae89f10c","type":"function","z":"87caedb32446fde2","name":"function 9","func":"let colours = [];\n//Test data\ncolours = [\"#33ff55\",\"#33ff55\",\"#33ff55\",\"#FFFF33\",\"#33ff55\",\"#33ff55\",\"#33ff55\",\"#33ff55\",\"#33ff55\",\"#33ff55\",\"#33ff55\",\"#33ff55\",\"#33ff55\",\"#33ff55\",\"#33ff55\",\"#FF3333\",\"#FF3333\",\"#FF3333\",\"#33ff55\"]\n\n//This is supposed to simulate the HTML code to make a table in UIBUILDER using `uib-update`\nmsg.payload = \"<span>\"\nmsg.payload += \"<table id=\\\"table1\\\">\"\nmsg.payload += \"<tbody>\"\nmsg.payload += \"<tr>\"\nmsg.payload += \"<span id:\\\"row1\\\" class=\\\"led-green\\\" uib-update=\\\"modulesWiFi\\\"> </span>\"\nmsg.payload += \"</tr>\"\nmsg.payload += \"<tr>\"\nmsg.payload += \"<td><span id:\\\"colour0\\\" class=\\\"led-green\\\" style=\\\"background-color: \" + colours[0] + \";\\\">&nbsp;&nbsp;</span></td>\"\nmsg.payload += \"<td><span id:\\\"colour1\\\" class=\\\"led-green\\\" style=\\\"background-color: \" + colours[1] + \";\\\">&nbsp;&nbsp;</span></td>\"\nmsg.payload += \"<td><span id:\\\"colour2\\\" class=\\\"led-green\\\" style=\\\"background-color: \" + colours[2] + \";\\\">&nbsp;&nbsp;</span></td>\"\nmsg.payload += \"<td><span id:\\\"colour3\\\" class=\\\"led-green\\\" style=\\\"background-color: \" + colours[3] + \";\\\">&nbsp;&nbsp;</span></td>\"\nmsg.payload += \"<td><span id:\\\"colour4\\\" class=\\\"led-green\\\" style=\\\"background-color: \" + colours[4] + \";\\\">&nbsp;&nbsp;</span></td>\"\nmsg.payload += \"<td> </td>\"\nmsg.payload += \"<td><span id:\\\"colour5\\\" class=\\\"led-green\\\" style=\\\"background-color: \" + colours[5] + \";\\\">&nbsp;&nbsp;</span></td>\"\nmsg.payload += \"<td><span id:\\\"colour6\\\" class=\\\"led-green\\\" style=\\\"background-color: \" + colours[6] + \";\\\">&nbsp;&nbsp;</span></td>\"\nmsg.payload += \"<td><span id:\\\"colour7\\\" class=\\\"led-green\\\" style=\\\"background-color: \" + colours[7] + \";\\\">&nbsp;&nbsp;</span></td>\"\nmsg.payload += \"<td><span id:\\\"colour8\\\" class=\\\"led-green\\\" style=\\\"background-color: \" + colours[8] + \";\\\">&nbsp;&nbsp;</span></td>\"\nmsg.payload += \"<td> </td>\"\nmsg.payload += \"<td><span id:\\\"colour9\\\" class=\\\"led-green\\\" style=\\\"background-color: \" + colours[9] + \";\\\">&nbsp;&nbsp;</span></td>\"\nmsg.payload += \"<td><span id:\\\"colour10\\\" class=\\\"led-green\\\" style=\\\"background-color: \" + colours[10] + \";\\\">&nbsp;&nbsp;</span></td>\"\nmsg.payload += \"<td><span id:\\\"colour11\\\" class=\\\"led-green\\\" style=\\\"background-color: \" + colours[11] + \";\\\">&nbsp;&nbsp;</span></td>\"\nmsg.payload += \"<td> </td>\"\nmsg.payload += \"<td><span id:\\\"colour12\\\" class=\\\"led-green\\\" style=\\\"background-color: \" + colours[12] + \";\\\">&nbsp;&nbsp;</span></td>\"\nmsg.payload += \"<td><span id:\\\"colour13\\\" class=\\\"led-green\\\" style=\\\"background-color: \" + colours[13] + \";\\\">&nbsp;&nbsp;</span></td>\"\nmsg.payload += \"<td><span id:\\\"colour14\\\" class=\\\"led-green\\\" style=\\\"background-color: \" + colours[14] + \";\\\">&nbsp;&nbsp;</span></td>\"\nmsg.payload += \"<td> </td>\"\nmsg.payload += \"<td><span id:\\\"colour15\\\" class=\\\"led-green\\\" style=\\\"background-color: \" + colours[15] + \";\\\">&nbsp;&nbsp;</span></td>\"\nmsg.payload += \"<td><span id:\\\"colour16\\\" class=\\\"led-green\\\" style=\\\"background-color: \" + colours[16] + \";\\\">&nbsp;&nbsp;</span></td>\"\nmsg.payload += \"<td><span id:\\\"colour17\\\" class=\\\"led-green\\\" style=\\\"background-color: \" + colours[17] + \";\\\">&nbsp;&nbsp;</span></td>\"\nmsg.payload += \"<td><span id:\\\"colour18\\\" class=\\\"led-green\\\" style=\\\"background-color: \" + colours[18] + \";\\\">&nbsp;&nbsp;</span></td>\"\nmsg.payload += \"</tr>\"\nmsg.payload += \"</tbody>\"\nmsg.payload += \"</table>\"\n\nmsg.topic = \"modulesWiFi\"\nreturn msg;\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":380,"y":1180,"wires":[["2bc41918c1e1aaa8","1672636f0e2d0b52"]]},{"id":"8e31336dcbaa6a22","type":"inject","z":"87caedb32446fde2","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":220,"y":1180,"wires":[["dbe4874dae89f10c"]]},{"id":"2bc41918c1e1aaa8","type":"debug","z":"87caedb32446fde2","name":"debug 23","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":560,"y":1180,"wires":[]}]

This is approx. what I am looking for.

Using CSS and a couple of nbsp; in the page to show a couple of characters.

TIA

What you've shared there cannot work as given I'm afraid. The thing to remember is that there is DATA from NR to the browser, then there is the DOM in the browser. These 2 things are very separate. The DOM is the HTML magic, the data is just text. So to pass HTML from Node-RED to the browser we need something to do the conversion for us so we don't have to bother. To drive that from Node-RED, you still want to use the uib-element node. But set to a Type of "html".


The above is taken from the uib-element example I provide, some way down the resulting page. I typically use the core node-red template node if I'm manually pushing HTML to the front-end since it is easier to edit.

You can, of course, also use the uib-element node set to table type to generate a full table and you have the remote command to get the HTML back to node-red if you like.

Now the question - do you have a fixed number of "LEDs" in that display? If so, all you need to do is use a uib-update node to change the class on the appropriate column.

If, on the other hand, you might keep adding to the LED's, there are a number of choices. However, adding columns to a table is much harder than adding rows. Because you need to add a tr/td to every row. That's why there isn't a uib-element type to add a column (though doubtless there should be - another one to add to the backlog!)

Instead, if you want 1 row and many LED's, it would be much better to use a div set to use display: "grid"; or display: "flex"; These are much easier (once you've overcome the initial hurdle of understanding how they work).

Hopefully I've made things a little clearer - hard for me to assess at the moment as I have a stinking cold so might not be thinking totally straight.

2 Likes

There you go, you mentioned DOM again! I was going to deny that I knew anything about it and get away with it. But, it has been around since the dawn of the Browser, so I have no excuse other than 'I have never needed to use it knowingly or directly'.

The UIBUILDER uib-element example worked, I "just" need to adapt it for my use.

My Homework has been set, my learning head needs to be dug out and I need to try and absorb what the eyes are seeing!!

Thank you for the pointer, as always, it is appreciated. I have learnt something more today!

1 Like

So, I found out that I had already done the groundwork and changing the uib-element to HTML displayed what I wanted! It took me longer to find out what the DOM was than to just modify my flow with the 'HTML selection of the uib-element'! I will read a bit more regarding DOM just to try and make sure it sinks in.

Thank you again Julian, so easy when you know how!!

I don't think you need to over-think it too much. Just remember that any visual digital output of any complexity is likely to have a structured OBJECT that the system uses to more easily process your requested data into something visible. Things like Microsoft Word, for example, also have a DOM. If you ever get into programming for any of the office products, you will be dealing with it.

HTML is no different - HTML is just structured text after all. Your browser has to turn that structured text into something that it can work with programmatically. That's the DOM.

So when working programmatically with a web page, we inevitably have to deal with the DOM, there is no other way. What UIBUILDER attempts to do, in part, is to make that interaction easier.

For example, when you use the uib-element node to send some HTML as text to the browser, the uibuilder client library then has to apply that text to the DOM. In reality, that is a very easy thing because there is already an API for it: innerHTML. All uibuilder is doing is saving you from having to remember how to do it using front-end code and the HTML API's. You could, of course, equally do this yourself using your own front-end JavaScript code.

1 Like

When I read the DOM definition, it all seemed to click into place. A couple more DOM articles and that persuaded me to just try what I had as it seemed to fulfil the requirements. If it worked, I understood it (possibly), if it didn't work, I would need to dig deeper. It worked, so I am putting it down to skill rather than being lucky! :rofl:

Of course, your hand in developing the uib-element had a lot to do with how easy it was!

Now there you go again! innerHTML. I have seen this for as long as I can remember, never understood it as I didn't need to, I could get by. That is of course until I read that the DOM is used for both HTML and Javascript. I think I understand what is going on with these `innerHTML' calls for the first time in 30 years!!

Now playing with CSS again. Most of the 'other stuff' (Button Inputs, Outputs, readings, Text Input etc.) for the HMI are done. Really pleased with how this is going, my stumbles give me a 'learning opportunity'. Just need to transfer what I have learnt to the other pages I need.

Thank you again for your help.

2 Likes

Por qué no los dos?

It is the answer I prefer... :wink:

Need to get my bonuses whenever and wherever I can just to stay sane!