Ui-template - HTML Table - How to adjust the height to desired height?

(db-1) Dashboard 3.6.5
NR - 4.0.0-beta.4

I have a ui-template with a 1 row html table defined in it, but the space taken is more than that and i get a scroll bar, how to avoid this ?

[{"id":"f47e7012dc1e56bb","type":"ui_template","z":"8aeac5104f2cecfe","group":"422c63c25531cb58","name":"Ha","order":11,"width":"30","height":"1","format":"<style>\n\n.rotate {\n  \n  font-size:12px;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: middle;\n  width: 1.0em;\n}\n.rotate div {\n     -moz-transform: rotate(-90.0deg);  /* FF3.5+ */\n       -o-transform: rotate(-90.0deg);  /* Opera 10.5 */\n  -webkit-transform: rotate(-90.0deg);  /* Saf3.1+, Chrome */\n             filter:  progid:DXImageTransform.Microsoft.BasicImage(rotation=0.083);  /* IE6,IE7 */\n         -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=0.083)\"; /* IE8 */\n         margin-left: -10em;\n         margin-right: -10em;\n}\n.m_on {\nfont-size:32px;\ncolor: green;\nfont-family: \"courier\";\ntext-align: center;\n}\n.m_off {\nfont-size:32px;\ncolor: brown;\nfont-family: \"courier\";\ntext-align: center;\n}\n</style>\n\n<div ng-bind-html=\"msg.payload\"></div>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","className":"","x":3600,"y":1250,"wires":[[]]},{"id":"de10a7895e9c78be","type":"inject","z":"8aeac5104f2cecfe","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"<table  border = '0'  cellpadding = \"0\" > <tr><th width=\"120px\" height = \"1px\" align =\"left\">SAMPLE-1 :</th> <td class = 'rotate'><div>11:50</div></td> <td class='m_on'>โ–„</td><td class='m_on'>โ–„</td><td class='m_on'>โ–„</td><td class='m_on'>โ–„</td><td class='m_on'>โ–„</td> <td class='m_on'>โ–„</td><td class='m_on'>โ–„</td><td class='m_on'>โ–„</td><td class='m_on'>โ–„</td><td class='m_on'>โ–„</td> <td class = 'rotate'><div>11:40</div></td> <td class='m_on'>โ–„</td><td class='m_on'>โ–„</td><td class='m_on'>โ–„</td><td class='m_on'>โ–„</td><td class='m_on'>โ–„</td> <td class='m_on'>โ–„</td><td class='m_on'>โ–„</td><td class='m_on'>โ–„</td><td class='m_off'>โ–„</td><td class='m_off'>โ–„</td>                        <td class = 'rotate'><div>11:30</div></td>                     <td class='m_on'>โ–„</td><td class='m_on'>โ–„</td><td class='m_on'>โ–„</td><td class='m_on'>โ–„</td><td class='m_on'>โ–„</td> <td class='m_on'>โ–„</td><td class='m_on'>โ–„</td><td class='m_on'>โ–„</td><td class='m_on'>โ–„</td><td class='m_on'>โ–„</td> ","payloadType":"str","x":3450,"y":1250,"wires":[["f47e7012dc1e56bb"]]},{"id":"422c63c25531cb58","type":"ui_group","name":"TABLE","tab":"5e0dd10e66fdea95","order":1,"disp":false,"width":"30","collapse":false,"className":""},{"id":"5e0dd10e66fdea95","type":"ui_tab","name":"TRAIL","icon":"dashboard","order":8,"disabled":false,"hidden":false}]

image

changing size 30x2 also still gives scroll bar, it only goes after i change it to 30x5, but by this, I loose lot of real estate on the dashboard.

my site dimensions are like below
image

Quick question: Why put that in a table?

Also, do you REALLY need to allow IE8 as your styles suggest?

You also have rather ancient attributes in your table anyway and so may be mixing attributes and styles to control the layout which is rarely a good thing unless you REALLY need browser support going back to the dark ages! :slight_smile:

I dont know any other way?
I am trying to get something similar to ui-state trail. to show the status of machine on a bar.

i dont even know what that means, i am just browsing internet and trying my luck to get it as per my liking.

would love if you point to me in right direction. i have 20 lines which i want to show their status, so using table to use each row as one machine status line.

1 Like

OK, I didn't pick up that you needed multiple lines of output.

As the author of UIBUILDER, I don't really use Dashboard except for really simple things. So I might not be the best person to help with this.

Unless you can find a chart library that can output something like this, I don't think what you are trying to do is especially simple, especially if you don't have any web skills. But it would be significantly more complex without Node-RED - EXCEPT for 1 exception and that would be to use Grafana with a suitable data source. Grafana already has heatmaps, wouldn't look quite the same probably but you might get close. Even that though isn't especially easy to achieve.

Coming back to the problem at hand though. You should remove border='0' cellpadding="0" from the table entry and width="120px" height="1px" align="left" from the tr (which defines a row).

Next immediate issue is that you haven't closed off the tr or the table tags. So the browser will be struggling to understand what is happening.

Next up is working out how to make your data dynamic rather than, as it currently is, static.

Are the number of devices (rows) static? Or do you get a different number or rows from time-to-time - and if so, how often.

You basically have a couple of choices here. Either rebuild the HTML table each time you do an update (which looks to be once a minute?) or get the browser to rebuild the table. Hard to say which is best because it somewhat depends on how many rows you will have and how relatively powerful/congested your server and clients are respectively.

So, some additional things for you to think about and come back with answers. Then we can look for actual answers.

I have been there, but unfortunately, the help forum is almost non-responsive and difficult to get through if there are any roadblocks.

I noticed that and have already rectified, but it didn't have any effect. (was working fine without it too)

It is dynamic, (the data flows in with a mysql query set to run every minute) if that is what you mean. have posted a static data for demo purpose.

yes, they are. it will increase if we add another brand new packing line.

Yes, data update happens every minute at the stroke of 00.

this is what i am comfortable with, as i dont know how to tackle this otherwise.

AFTERTHOUGHT:

the problem of extra height of the template in the dashboard, is not a great issue, once I have 20 lines, as the 'extra padding' i am getting is constant for 1 line or 20 lines. i think i can live with it.

However, i would still need guidance to simplify my flow if there is a chance.

I am following you since very long, but honestly didn't try to use it as dashboard 1 was serving my requirement, but as i keep learning and see the possibilities, i would definitely look into UIBUILDER or dashboard-2. if DB2 had node-red-contrib-ui-state-trail by @hotNipi i would have easily switched over by now.

Check this git comment:

There is a link to example on doing something similar to state trail using echarts, don't know how customizable that is, but seems doable using ui-template even in DB1.

Thanks for the replies.

If I were to use Dashboard 2.0 or UIBUILDER with VueJS, I would simply send the data to the front-end and get VueJS to build the table. But that means learning Vue.

Without Vue or similar, I would use UIBUILDER's low-code capability. Converting the SQL output into something that the browser outputs as the table. Here is an example of something I quickly knocked up for work.

This is just a segment of the code to give you a feel for how the low-code JSON output is built, not a complete example.

        /** Each group/treatment has a list of apps
         * @param {string} groupName Name of the current group
         * @param {string} treatName Name of the current treatment
         * @param {*} msg Data to process
         * @returns {Array} a _ui components array
         */
        listAppsInGroup: function listAppsInGroup(groupName, treatName, msg) {
            const grouped = msg.grouped
            const treatment = grouped[groupName][treatName] ? grouped[groupName][treatName] : []
            const out = []
            treatment.forEach(app => {
                const maturity = app.maturity ? app.maturity : '-'
                const vis = app.visibility ? app.visibility : '-'
                const org = app.org ? app.org : '-'
                out.push({
                    type: 'li',
                    attributes: {
                        'class': 'flex box surface4',
                        style: `color: ${tColours[treatName]}`,
                    },
                    components: [
                        // {
                        //     type: 'div',
                        //     attributes: {
                        //         class: 'status-side-panel'
                        //     },
                        // },
                        {
                            type: 'div',
                            attributes: {},
                            components: [
                                {
                                    type: 'details',
                                    components: [
                                        {
                                            type: 'summary',
                                            attributes: {
                                                style: 'list-style-type: none;'
                                            },
                                            slot: app.name,
                                        },
                                        {
                                            type: 'div',
                                            attributes: {
                                                style: 'font-size: smaller; color: var(--text1);'
                                            },
                                            slot: app.desc,
                                        },
                                        {
                                            type: 'div',
                                            attributes: {
                                                style: 'font-size: smaller; color: var(--text2);'
                                            },
                                            slot: `<abbr title="Maturity: ${maturity}">${maturity.slice(0, 1).toUpperCase()}</abbr> <abbr title="Visibility: ${vis}">${vis.slice(0, 1).toUpperCase()}</abbr> <abbr title="Legacy Organisation: ${org}">${org.toUpperCase()}</abbr>`,
                                        },
                                    ],
                                },
                            ],
                        },

                    ],
                })
            })
            return out
        },

Because I knocked it up quickly, it has lots of manual styles in there but really, it should have only used class names.

Note that you could also use the same approach to build the HTML and send it to either of the Dashboard's because UIBUILDER is able to do the conversion from low-code to HTML in Node-RED using the uib-html node.

The advantage of using UIBUILDER low-code is that it is very close to HTML so learning to do it in low-code is a good stepping stone to building something that outputs HTML in the future. Of course, whether that is important to you is something only you can decide.

Using UIBUILDER would also make it easy enough for you to write some front-end JS to build the table from data sent from Node-RED. This is the "traditional" way to use UIBUILDER. The front-end library makes it trivial to listen for messages from NR and gives a few helpers such as $(cssSelector) to get a reference to an element on the page. Using this method means that you will be building directly on your existing knowledge of HTML and JS.


By the way, thought of another approach if you are happy building HTML. You could also use the core template node with Mustache. You feed the SQL output to the template and it builds the HTML which you can send to a ui_template node.

You can also use the same method with UIBUILDER if you like. The uib-element node has an html element type so just send the output of the template node through the uib-element node and straight on to the uibuilder node. Job done. UIBUILDER has a built-in example for this:


The example doesn't do a lot but the number changes every time you trigger the flow:
image


As always with Node-RED, lots of options to choose from. :grinning:


PS: Remembered another example. My home dashboard has a number of pages but this is an extract - it shows the status of some of the services I have running:


Here is the most important part of the flow that builds the whole SPA, not just the section shown:

Here I use a mix-and-match approach where the core page is built using a template (the lower part of the flow) and other parts built dynamically (the upper part).

With newer versions of UIBUILDER, I would actually build and save the HTML for the core page layout so that it was static. Naturally, uibuilder has the uib-html and uib-save nodes to make that easy.

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