@omrid01/node-red-dashboard-2-table-tabulator - Display problem

Hello,
I’m working on various projects using this excellent node :+1:. Everything seems to be working fine, except that sometimes my data doesn’t appear in the table. My tables are organised into groups on my dashboard, and I hide or show these groups depending on user interactions. So I don’t think it’s a problem with the node itself, but I’m trying to find the most efficient and responsive way to display my data in the table. A timer is a basic solution, but I’m looking for something better. Do you have an effective method for solving this problem ? If you have any ideas… I’d love to hear them.
Thanks in advance

Jean-Remy

Glad to hear that you like the node.
I need to understand the details: you say you have multiple tables across several groups, the groups are shown/hidden dynamically, and the table data sometimes disappears.

  1. When does the data disappear, is it random, related to a specific user event, when a group becomes visible?
  2. Once the table goes blank, how do you bring the data back - by clicking the table? or something else?

Hi
You’re right, that happens when a group becomes visible. Is there a way to know when the table is ready to accept data? In my case, when the data isn’t loaded into the table, I simply select the next data to display in my table (using a function node that lets me scroll my data list up and down), then I go back to the previous data. I’m aware of this minor issue and am looking for a more robust solution to fix it. If you have an idea... let me know ?

Regards

Jean-Remy

How are you making it visible? using ui-control? I tried to simulate this, but in my setup the table shows correctly upon getting visibility. In any case, you can try to send the table a redraw command.(msg.tbCmd = 'redraw') after you make the group visible. Let me know if this solves the issue, and I will add this to the documentation.

The table should be always ready to accept data, even when its group is hidden. While playing with this, I noticed that when hidden, it does not accept commands. I'll further investigate this, and issue a fix if needed

[edit]
OK, so nothing to do with my node. In dashboard-2, when hiding with ui-control, it destroys all the group's nodes and recreates them upon show. If this suits you (i.e. you do not need to set data in the table while it's hidden, then OK. Else, you'll need to hide it differently, e.g. hide the ui-group directly from a template node.

I want to release a new version for ui-tabulator, and want to know if the redraw() command fixes the issue you encountered, so I can formally add it to the node.

Hi,

Sorry but I was expecting to make new test based on your answer during the weekend, but I can confirm that the option redraw() didn't solve the problem.

I will let you know the result.

Regards

Jean-Remy

ok. if you don't solve it, try to share a sample flow so that will allow me to simulate it on my end.
Also, maybe try to see if the issue remains if you hide/show the group not with ui-control but from a template (I can show you how).

Hi,

I’ve run a few tests, and I can confirm that in a simplified version of the code I used for my project, the problem no longer occurs (with the ui-control method). I’ll therefore need to investigate why some data is missing in the final version. I apologise for the comment I posted on this matter. Oops...!!!
But I’m interesting to know how you use a template to hide/show.

Thanks

Jean-Remy

I'm enclosing a simple flow that demonstrates the "template-based" method. you can insert it into your flow and check if the problem persists.
the template uses the Id of the ui-group HTML element to set its visibility status. you have 2 hiding modes:

el.style.display = "none"; // hides, while collapsing the hidden area
el.style.display = ""; // shows the group
//or
el.style.visibility = "hidden"; // hides while keeping the blank space of the hidden area
el.style.visibility = "visible"; // shows the group

In both cases, the table stays alive while hidden (you can still update it, query it etc.). this is in contrast to using ui-control which destroys the table when hiding its group, having to recreate upon show.

The "ugly" part is getting the group id, but it's not a big deal. just give the group a unique name, search for it in the flows.json file, grab its id and prefix it with nrdb-ui-group-. the Id doesn't change across import, export etc.
flow file:


template:

<script>
    export default {
        data() {
            return {
                groupId:"nrdb-ui-group-c3e9f265ac49d321"
            }
        },
[
    {
        "id": "0f03c0fb85c0777f",
        "type": "ui-tabulator",
        "z": "408d3ca34533d82b",
        "name": "",
        "group": "c3e9f265ac49d321",
        "initObj": "{\n   \"height\": 200,\n   \"layout\": \"fitColumns\",\n   \"columns\": [\n      {\"field\":\"id\",\"visible\":false},\n      {\"title\":\"Name\",\"field\":\"name\",\"width\":200,\"hozAlign\":\"left\"},\n      {\"title\":\"Age\",\"field\":\"age\",\"width\": 100,\"hozAlign\":\"center\"}\n   ],\n   \"data\": [\n      {\"id\":1,\"name\":\"John Brown\", \"age\":30},\n      {\"id\":2,\"name\":\"Betty Clark\", \"age\":25}\n   ]\n}",
        "funcs": "",
        "allowMsgFuncs": false,
        "maxWidth": "",
        "events": "",
        "order": 1,
        "multiUser": false,
        "validateRowIds": false,
        "themeCSS": "",
        "themeFile": "",
        "tblDivId": "",
        "printToLog": false,
        "width": 0,
        "height": 0,
        "x": 110,
        "y": 380,
        "wires": [
            []
        ]
    },
    {
        "id": "bb7de9e9cd68cae0",
        "type": "ui-template",
        "z": "408d3ca34533d82b",
        "group": "baaab07585f45e6d",
        "page": "",
        "ui": "",
        "name": "",
        "order": 1,
        "width": 0,
        "height": 0,
        "head": "",
        "format": "<template>\n    <div>\n        <v-btn class=\"small mx-4\" @click=\"hide(true)\">Hide</v-btn>\n        <v-btn class=\"small mx-4\" @click=\"hide(false)\">Show</v-btn>\n    </div>\n</template>\n\n<script>\n    export default {\n        data() {\n            return {\n                groupId:\"nrdb-ui-group-c3e9f265ac49d321\"\n            }\n        },\n        methods: {\n            // expose a method to our <template> and Vue Application\n            hide: function (hide) {\n                const el = document.getElementById(this.groupId);\n                if (hide)\n                    //el.style.display = \"none\"; --> collapsing the hidden area\n                    el.style.visibility = \"hidden\";\n                else\n                    //el.style.display = \"\";\n                    el.style.visibility = \"visible\";            }\n        },\n        mounted() {\n            const vThis = this; // saving the value of 'this' so we can use it inside the socket handler \n            // Socket listener\n            this.$socket.on('msg-input:' + this.id, function(msg) {\n                vThis.hide(msg.payload);\n            });\n        }\n    }\n</script>\n",
        "storeOutMessages": true,
        "passthru": false,
        "resendOnRefresh": true,
        "templateScope": "local",
        "className": "",
        "x": 240,
        "y": 300,
        "wires": [
            []
        ]
    },
    {
        "id": "d892e4e80adea664",
        "type": "inject",
        "z": "408d3ca34533d82b",
        "name": "Hide",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "true",
        "payloadType": "bool",
        "x": 90,
        "y": 280,
        "wires": [
            [
                "bb7de9e9cd68cae0"
            ]
        ]
    },
    {
        "id": "7b20718cb4bd0cbc",
        "type": "inject",
        "z": "408d3ca34533d82b",
        "name": "Show",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "false",
        "payloadType": "bool",
        "x": 90,
        "y": 320,
        "wires": [
            [
                "bb7de9e9cd68cae0"
            ]
        ]
    },
    {
        "id": "c3e9f265ac49d321",
        "type": "ui-group",
        "name": "Omri-Test-Group",
        "page": "e1489f1914461e08",
        "width": "8",
        "height": "3",
        "order": 1,
        "showTitle": true,
        "className": "",
        "visible": "true",
        "disabled": "false",
        "groupType": "default"
    },
    {
        "id": "baaab07585f45e6d",
        "type": "ui-group",
        "name": "Group-2",
        "page": "e1489f1914461e08",
        "width": 6,
        "height": 1,
        "order": 2,
        "showTitle": true,
        "className": "",
        "visible": "true",
        "disabled": "false",
        "groupType": "default"
    },
    {
        "id": "e1489f1914461e08",
        "type": "ui-page",
        "name": "Omri",
        "ui": "b7fd8a2cce8052cc",
        "path": "/omri",
        "icon": "home",
        "layout": "grid",
        "theme": "b7b1935fbb33bbc8",
        "breakpoints": [
            {
                "name": "Default",
                "px": "0",
                "cols": "3"
            },
            {
                "name": "Tablet",
                "px": "576",
                "cols": "6"
            },
            {
                "name": "Small Desktop",
                "px": "768",
                "cols": "9"
            },
            {
                "name": "Desktop",
                "px": "1024",
                "cols": "12"
            }
        ],
        "order": 1,
        "className": "",
        "visible": "true",
        "disabled": "false"
    },
    {
        "id": "b7fd8a2cce8052cc",
        "type": "ui-base",
        "name": "ui",
        "path": "/dashboard",
        "appIcon": "",
        "includeClientData": true,
        "acceptsClientConfig": [
            "ui-notification",
            "ui-dropdown",
            "ui-control",
            "ui-text",
            "ui-text-input"
        ],
        "showPathInSidebar": false,
        "headerContent": "page",
        "navigationStyle": "default",
        "titleBarStyle": "default",
        "showReconnectNotification": true,
        "notificationDisplayTime": 5,
        "showDisconnectNotification": true,
        "allowInstall": true
    },
    {
        "id": "b7b1935fbb33bbc8",
        "type": "ui-theme",
        "name": "Default theme",
        "colors": {
            "surface": "#ffffff",
            "primary": "#0094ce",
            "bgPage": "#eeeeee",
            "groupBg": "#ffffff",
            "groupOutline": "#cccccc"
        },
        "sizes": {
            "pagePadding": "12px",
            "groupGap": "12px",
            "groupBorderRadius": "4px",
            "widgetGap": "12px"
        }
    },
    {
        "id": "5f52a6a336a9ac0a",
        "type": "global-config",
        "env": [],
        "modules": {
            "@omrid01/node-red-dashboard-2-table-tabulator": "0.8.2",
            "@flowfuse/node-red-dashboard": "1.30.2"
        }
    }
]

let me know how it goes.

Hi,

I’ve tested the “flow” you suggested in the simplified code for my project, and it works really well. The table is directly populated with the correct values. It’s a huge step forward.
Your solution is a better approach than the "ui-control" method.
Many thanks for your explanations. :+1:

As soon as I can, I will update my code for my project.

Regards

Jean-Remy

if you use this template in your dashboard just to control visibility of UI elements, and you want it to work in the background without occupying screen space, give it the CSS class d-none in its configuration.

1 Like

Hi,

Well spotted... :wink:

Regards

Jean-Remy