How to select all checkboxes in UI_table

Hello everyone,

I'm recent in using node red and I have the following question.
In my project, I'm listing the contents of a directory in a UI_table and I have check boxes that allow selecting one or more lines. However I need to have a button for select/deselect all.
I leave my flow below if someone can help.
Thanks to everyone and congratulations for your contribution to the community

[
    {
        "id": "f0ac6e667fc173d9",
        "type": "tab",
        "label": "Download",
        "disabled": false,
        "info": ""
    },
    {
        "id": "40ce0bd9496ea3c6",
        "type": "function",
        "z": "f0ac6e667fc173d9",
        "name": "",
        "func": "//var user = global.get(\"user\")\n//var ip = global.get(\"host\")\n//var cmd = \"whoami\";\n//var file = {};\n//var status = {};\n \nmsg.payload = `scp pi@10.42.0.2:/home/pi/animalTAGS/data/logs/datalog--2021-6-30--11-54--0.csv /data/`;\n \nreturn msg\n\n\n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 260,
        "y": 80,
        "wires": [
            [
                "9e76d69ac90056ab"
            ]
        ]
    },
    {
        "id": "9e76d69ac90056ab",
        "type": "exec",
        "z": "f0ac6e667fc173d9",
        "command": "",
        "addpay": "payload",
        "append": "",
        "useSpawn": "false",
        "timer": "5",
        "winHide": false,
        "oldrc": false,
        "name": "",
        "x": 390,
        "y": 80,
        "wires": [
            [
                "5d6b37170365daa9"
            ],
            [],
            []
        ]
    },
    {
        "id": "3b810f98cb3ecee8",
        "type": "ui_button",
        "z": "f0ac6e667fc173d9",
        "name": "",
        "group": "2768d5bb10e62e93",
        "order": 3,
        "width": 0,
        "height": 0,
        "passthru": false,
        "label": "Update Files List",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "",
        "payloadType": "str",
        "topic": "topic",
        "topicType": "msg",
        "x": 110,
        "y": 280,
        "wires": [
            [
                "b6828ff0e97ee852",
                "658e66209e05b0f5"
            ]
        ]
    },
    {
        "id": "0ece2307eb0c58ad",
        "type": "inject",
        "z": "f0ac6e667fc173d9",
        "name": "",
        "props": [
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "x": 110,
        "y": 180,
        "wires": [
            [
                "b6828ff0e97ee852"
            ]
        ]
    },
    {
        "id": "d5de889f057ef535",
        "type": "debug",
        "z": "f0ac6e667fc173d9",
        "name": "func",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 690,
        "y": 60,
        "wires": []
    },
    {
        "id": "5d6b37170365daa9",
        "type": "function",
        "z": "f0ac6e667fc173d9",
        "name": "",
        "func": "//var user = global.get(\"user\")\n//var ip = global.get(\"host\")\n//var cmd = \"whoami\";\n//var file = {};\n//var status = {};\n \nmsg.payload = `scp /data/datalog--2021-6-30--11-54--0.csv miguelsoares@10.42.0.1:/home/miguelsoares/Desktop`;\n\n \nreturn msg\n\n\n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 540,
        "y": 60,
        "wires": [
            [
                "d5de889f057ef535"
            ]
        ]
    },
    {
        "id": "b6828ff0e97ee852",
        "type": "function",
        "z": "f0ac6e667fc173d9",
        "name": "",
        "func": "var user = global.get(\"user\");\nvar ip = global.get(\"host\");\nvar cmd1 = \"ls\";\nvar cmd2 = \"-lvh\";\nvar dir = \"/home/pi/animalTAGS/data/videos/\";\nvar header1 =\"| awk '{print $5 \";\nvar header2 = '\"->\"';\nvar header3 = \" $9}'\";\nvar file = {};\nvar status = {};\n \n//ssh pi@10.42.0.2 ls /home/pi/animalTAGS/data/videos/ -lvh | awk '{print $5 \" -> \" $9}'\nmsg.payload =  `ssh ${user}@${ip} ${cmd1} ${dir} ${cmd2} ${header1}${header2}${header3}`;\n \nreturn msg;\n\n\n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 300,
        "y": 200,
        "wires": [
            [
                "0812e650858b0358"
            ]
        ]
    },
    {
        "id": "0812e650858b0358",
        "type": "exec",
        "z": "f0ac6e667fc173d9",
        "command": "",
        "addpay": "payload",
        "append": "",
        "useSpawn": "false",
        "timer": "10",
        "winHide": false,
        "oldrc": false,
        "name": "",
        "x": 450,
        "y": 200,
        "wires": [
            [
                "63b569e1e53b2802",
                "aa32606ab2d36c43"
            ],
            [],
            []
        ]
    },
    {
        "id": "63b569e1e53b2802",
        "type": "debug",
        "z": "f0ac6e667fc173d9",
        "name": "debug_LS",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 570,
        "y": 300,
        "wires": []
    },
    {
        "id": "aa32606ab2d36c43",
        "type": "json",
        "z": "f0ac6e667fc173d9",
        "name": "",
        "property": "payload",
        "action": "str",
        "pretty": true,
        "x": 630,
        "y": 180,
        "wires": [
            [
                "c02d050c2abb6c2e",
                "0f5afe1072fec061"
            ]
        ]
    },
    {
        "id": "3070a972d0a0cec1",
        "type": "debug",
        "z": "f0ac6e667fc173d9",
        "name": "js",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 930,
        "y": 300,
        "wires": []
    },
    {
        "id": "c02d050c2abb6c2e",
        "type": "split",
        "z": "f0ac6e667fc173d9",
        "name": "",
        "splt": "\\n",
        "spltType": "str",
        "arraySplt": "1",
        "arraySpltType": "len",
        "stream": false,
        "addname": "key",
        "x": 770,
        "y": 180,
        "wires": [
            [
                "3070a972d0a0cec1",
                "50352d57a13aa964"
            ]
        ]
    },
    {
        "id": "50352d57a13aa964",
        "type": "function",
        "z": "f0ac6e667fc173d9",
        "name": "",
        "func": "var data=msg.payload;\nvar temp=data.split(\"->\");\nmsg.file_size=temp[0];\nmsg.file_name=temp[1];\n\nreturn msg;\n\n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 920,
        "y": 180,
        "wires": [
            [
                "8a73d7aed4f0c188",
                "b1e1f66e4419d48d"
            ]
        ]
    },
    {
        "id": "0f5afe1072fec061",
        "type": "debug",
        "z": "f0ac6e667fc173d9",
        "name": "debug_json",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 750,
        "y": 300,
        "wires": []
    },
    {
        "id": "44599119a368ca93",
        "type": "ui_table",
        "z": "f0ac6e667fc173d9",
        "group": "870a91418c5861d1",
        "name": "",
        "order": 1,
        "width": 10,
        "height": 7,
        "columns": [],
        "outputs": 1,
        "cts": true,
        "x": 1210,
        "y": 360,
        "wires": [
            [
                "2154edb51d899a58",
                "785c9fd83e7be407",
                "afac46f550f2172f"
            ]
        ]
    },
    {
        "id": "8a73d7aed4f0c188",
        "type": "function",
        "z": "f0ac6e667fc173d9",
        "name": "updateOrAddData (add)",
        "func": "var check=msg.file_size;\nif(check===\"\"){\n    return null;   \n}\nelse {\n    var id=flow.get(\"lastId\") || 0;\n    ++id;\n    msg.payload={\n        command:\"updateOrAddData\",\n        arguments: [\n            [\n                {\n                \"id\":id,\n                \"filesize\":msg.file_size,\n                \"filename\":msg.file_name,\n                \"check_box\":false\n                }\n            ]\n        ],\n        returnPromise: true\n    }\n    flow.set(\"lastId\",id);\n    return msg;\n}\n\n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1130,
        "y": 180,
        "wires": [
            [
                "2afe27d64fd9d669",
                "56e34c6dd19c7e1f"
            ]
        ],
        "info": "# updateOrAddData([row])\n\nadds a the row with a new id (same as addRow)"
    },
    {
        "id": "6c4c6d5e44c1aead",
        "type": "inject",
        "z": "f0ac6e667fc173d9",
        "name": "format table",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payloadType": "date",
        "x": 110,
        "y": 440,
        "wires": [
            [
                "658e66209e05b0f5"
            ]
        ]
    },
    {
        "id": "658e66209e05b0f5",
        "type": "change",
        "z": "f0ac6e667fc173d9",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "ui_control",
                "pt": "msg",
                "to": "{\"customHeight\":12,\"tabulator\":{\"columns\":[{\"title\":\" <div style='text-align:center'>#</div>\",\"field\":\"id\",\"width\":5,\"formatter\":\"rownum\",\"align\":\"center\"},{\"title\":\" <div style='text-align:center'>File Size</div>\",\"field\":\"filesize\",\"align\":\"center\",\"formatter\":\"text\",\"width\":100,\"layout\":\"fitData\"},{\"title\":\" <div style='text-align:center'>File Name</div>\",\"field\":\"filename\",\"formatter\":\"text\",\"width\":330,\"sorter\":\"alphanum\",\"sorterParams\":{\"alignEmptyValues\":\"bottom\"},\"layout\":\"fitData\",\"align\":\"center\"},{\"title\":\"\",\"field\":\"check_box\",\"width\":5,\"formatter\":\"tickCross\",\"formatterParams\":{\"target\":\"_blank\",\"allowEmpty\":true,\"allowTruthy\":true,\"tickElement\":\"<i class='fa fa-check-square-o fa-1x'></i>\",\"crossElement\":\"<i class='fa fa-square-o fa-1x'></i>\"},\"align\":\"center\"}],\"initialSort\":[{\"column\":\"filename\",\"dir\":\"asc\"}],\"setSort\":[{\"column\":\"filename\",\"dir\":\"asc\"}],\"layout\":\"fitColumns\",\"movableColumns\":false,\"resizableColumns\":false,\"headerVisible\":true,\"headerSort\":false,\"autoColumns\":false,\"selectable\":true}}",
                "tot": "json"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 330,
        "y": 360,
        "wires": [
            [
                "44599119a368ca93"
            ]
        ]
    },
    {
        "id": "2154edb51d899a58",
        "type": "switch",
        "z": "f0ac6e667fc173d9",
        "name": "",
        "property": "payload.check_box",
        "propertyType": "msg",
        "rules": [
            {
                "t": "true"
            },
            {
                "t": "false"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 410,
        "y": 520,
        "wires": [
            [
                "39a1f890d6922b15"
            ],
            [
                "605ec706105cb760"
            ]
        ]
    },
    {
        "id": "39a1f890d6922b15",
        "type": "change",
        "z": "f0ac6e667fc173d9",
        "name": "change_icon_false",
        "rules": [
            {
                "t": "set",
                "p": "payload.check_box",
                "pt": "msg",
                "to": "false",
                "tot": "bool"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 590,
        "y": 500,
        "wires": [
            [
                "20d5d68ff73ed577"
            ]
        ]
    },
    {
        "id": "605ec706105cb760",
        "type": "change",
        "z": "f0ac6e667fc173d9",
        "name": "change_icon_true",
        "rules": [
            {
                "t": "set",
                "p": "payload.check_box",
                "pt": "msg",
                "to": "true",
                "tot": "bool"
            },
            {
                "t": "set",
                "p": "change_icon",
                "pt": "msg",
                "to": "true",
                "tot": "bool"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 590,
        "y": 540,
        "wires": [
            [
                "063f4ca61b41d4c3"
            ]
        ]
    },
    {
        "id": "063f4ca61b41d4c3",
        "type": "switch",
        "z": "f0ac6e667fc173d9",
        "name": "",
        "property": "change_icon",
        "propertyType": "msg",
        "rules": [
            {
                "t": "null"
            },
            {
                "t": "true"
            },
            {
                "t": "false"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 3,
        "x": 790,
        "y": 540,
        "wires": [
            [],
            [
                "20d5d68ff73ed577"
            ],
            []
        ]
    },
    {
        "id": "20d5d68ff73ed577",
        "type": "function",
        "z": "f0ac6e667fc173d9",
        "name": "update_data",
        "func": "var id = msg.payload.id\n\nmsg.payload={\n    command:\"updateOrAddData\",\n    arguments: [\n        [\n            {\n                \"id\":id,\n                \"filesize\":msg.file_size,\n                \"filename\":msg.file_name,\n                \"check_box\":msg.payload.check_box\n            }\n        ]\n    ],\n    returnPromise: true\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1110,
        "y": 520,
        "wires": [
            [
                "658e66209e05b0f5"
            ]
        ],
        "info": "# updateOrAddData([row])\n\nupdates a the row with an id in the middle from 1 to lastId, hope it exists!\nIf not a row will be added"
    },
    {
        "id": "b1e1f66e4419d48d",
        "type": "debug",
        "z": "f0ac6e667fc173d9",
        "name": "js",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1090,
        "y": 240,
        "wires": []
    },
    {
        "id": "2afe27d64fd9d669",
        "type": "debug",
        "z": "f0ac6e667fc173d9",
        "name": "check_blanks",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1400,
        "y": 80,
        "wires": []
    },
    {
        "id": "bbd1a8e0279a419e",
        "type": "switch",
        "z": "f0ac6e667fc173d9",
        "name": "",
        "property": "return.arguments[0][0].check_box",
        "propertyType": "msg",
        "rules": [
            {
                "t": "true"
            },
            {
                "t": "false"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 1510,
        "y": 360,
        "wires": [
            [
                "2fc9567e0d90dc95"
            ],
            [
                "1e4734db8a9e6825"
            ]
        ]
    },
    {
        "id": "5739cb8cfed70545",
        "type": "debug",
        "z": "f0ac6e667fc173d9",
        "name": "concat",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1950,
        "y": 340,
        "wires": []
    },
    {
        "id": "785c9fd83e7be407",
        "type": "switch",
        "z": "f0ac6e667fc173d9",
        "name": "",
        "property": "return.command",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "updateOrAddData",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 1370,
        "y": 360,
        "wires": [
            [
                "bbd1a8e0279a419e"
            ]
        ]
    },
    {
        "id": "afac46f550f2172f",
        "type": "change",
        "z": "f0ac6e667fc173d9",
        "name": "",
        "rules": [
            {
                "t": "move",
                "p": "payload.filesize",
                "pt": "msg",
                "to": "filesize",
                "tot": "flow"
            },
            {
                "t": "move",
                "p": "payload.filename",
                "pt": "msg",
                "to": "filename",
                "tot": "flow"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1400,
        "y": 420,
        "wires": [
            []
        ]
    },
    {
        "id": "2fc9567e0d90dc95",
        "type": "function",
        "z": "f0ac6e667fc173d9",
        "name": "",
        "func": "msg.payload=flow.get(\"filename\");\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1640,
        "y": 300,
        "wires": [
            [
                "295423132774751e",
                "2c5d048c1153bc6b"
            ]
        ]
    },
    {
        "id": "295423132774751e",
        "type": "debug",
        "z": "f0ac6e667fc173d9",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 1690,
        "y": 360,
        "wires": []
    },
    {
        "id": "1e4734db8a9e6825",
        "type": "function",
        "z": "f0ac6e667fc173d9",
        "name": "",
        "func": "var arr=flow.get(\"selected_array\");\nvar value = flow.get(\"filename\");\n\nfunction removeItemOnce(arr, value) {\n  var index = arr.indexOf(value);\n  if (index > -1) {\n    arr.splice(index, 1);\n  }\n  return arr;\n}\n\nmsg.payload=removeItemOnce(arr, value);\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1650,
        "y": 420,
        "wires": [
            [
                "4399bb92ab057975"
            ]
        ]
    },
    {
        "id": "a81faf8bd0a44154",
        "type": "change",
        "z": "f0ac6e667fc173d9",
        "name": "",
        "rules": [
            {
                "t": "move",
                "p": "payload",
                "pt": "msg",
                "to": "selected_array",
                "tot": "flow"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1990,
        "y": 240,
        "wires": [
            []
        ]
    },
    {
        "id": "4399bb92ab057975",
        "type": "debug",
        "z": "f0ac6e667fc173d9",
        "name": "selected_dw",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1690,
        "y": 480,
        "wires": []
    },
    {
        "id": "2c5d048c1153bc6b",
        "type": "function",
        "z": "f0ac6e667fc173d9",
        "name": "concat",
        "func": "var arr = flow.get(\"selected_array\");\nvar value = msg.payload;\n\n\nmsg.payload=arr.concat(value);\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1810,
        "y": 300,
        "wires": [
            [
                "a81faf8bd0a44154",
                "5739cb8cfed70545"
            ]
        ]
    },
    {
        "id": "56e34c6dd19c7e1f",
        "type": "change",
        "z": "f0ac6e667fc173d9",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "selected_array",
                "pt": "flow",
                "to": "[]",
                "tot": "json"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1340,
        "y": 240,
        "wires": [
            [
                "44599119a368ca93"
            ]
        ]
    },
    {
        "id": "ddcc4658deb88732",
        "type": "ui_button",
        "z": "f0ac6e667fc173d9",
        "name": "",
        "group": "2768d5bb10e62e93",
        "order": 4,
        "width": 0,
        "height": 0,
        "passthru": false,
        "label": "Set Files For Download",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "",
        "payloadType": "str",
        "topic": "topic",
        "topicType": "msg",
        "x": 1630,
        "y": 560,
        "wires": [
            [
                "c8b3477f13671566"
            ]
        ]
    },
    {
        "id": "c8b3477f13671566",
        "type": "change",
        "z": "f0ac6e667fc173d9",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "selected_array",
                "tot": "flow"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1840,
        "y": 560,
        "wires": [
            [
                "8ae438fbf7b0f1db"
            ]
        ]
    },
    {
        "id": "8ae438fbf7b0f1db",
        "type": "split",
        "z": "f0ac6e667fc173d9",
        "name": "Split array",
        "splt": "\\n",
        "spltType": "str",
        "arraySplt": "1",
        "arraySpltType": "len",
        "stream": false,
        "addname": "",
        "x": 2000,
        "y": 560,
        "wires": [
            [
                "ca59221821fc89c7"
            ]
        ]
    },
    {
        "id": "ca59221821fc89c7",
        "type": "debug",
        "z": "f0ac6e667fc173d9",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 2150,
        "y": 560,
        "wires": []
    },
    {
        "id": "1c6cf2e317868d1a",
        "type": "function",
        "z": "f0ac6e667fc173d9",
        "name": "",
        "func": "function toggle(source) {\n    var checkboxes = document.querySelectorAll('input[type=\"checkbox\"]');\n    for (var i = 0; i < checkboxes.length; i++) {\n        if (checkboxes[i] != source)\n            checkboxes[i].checked = source.checked;\n    }\n}",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1050,
        "y": 680,
        "wires": [
            [
                "b18e2c5c8b2c7459"
            ]
        ]
    },
    {
        "id": "b55751b892fa15b4",
        "type": "ui_button",
        "z": "f0ac6e667fc173d9",
        "name": "",
        "group": "2768d5bb10e62e93",
        "order": 4,
        "width": 0,
        "height": 0,
        "passthru": false,
        "label": "Select All Files",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "",
        "payloadType": "str",
        "topic": "topic",
        "topicType": "msg",
        "x": 880,
        "y": 680,
        "wires": [
            [
                "1c6cf2e317868d1a"
            ]
        ]
    },
    {
        "id": "b18e2c5c8b2c7459",
        "type": "debug",
        "z": "f0ac6e667fc173d9",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1190,
        "y": 680,
        "wires": []
    },
    {
        "id": "960b6ba012d7ced2",
        "type": "ui_spacer",
        "z": "f0ac6e667fc173d9",
        "name": "spacer",
        "group": "2768d5bb10e62e93",
        "order": 1,
        "width": 6,
        "height": 1
    },
    {
        "id": "0a70b37758bc78b8",
        "type": "ui_spacer",
        "z": "f0ac6e667fc173d9",
        "name": "spacer",
        "group": "2768d5bb10e62e93",
        "order": 2,
        "width": 6,
        "height": 1
    },
    {
        "id": "2768d5bb10e62e93",
        "type": "ui_group",
        "name": "Group 1",
        "tab": "94ff3c5caa315fa9",
        "order": 1,
        "disp": false,
        "width": 6,
        "collapse": false,
        "className": ""
    },
    {
        "id": "870a91418c5861d1",
        "type": "ui_group",
        "name": "List of files in directory",
        "tab": "94ff3c5caa315fa9",
        "order": 2,
        "disp": true,
        "width": "10",
        "collapse": false,
        "className": ""
    },
    {
        "id": "94ff3c5caa315fa9",
        "type": "ui_tab",
        "name": "Download",
        "icon": "fa-cloud-download fa-2x",
        "order": 4,
        "disabled": false,
        "hidden": false
    }
]
1 Like

Hi @MiguelSoares , welcome to the forum.

Please edit your original post to reformat the code, otherwise no one will be able to import your flow for testing.

Here below the guideline.

Hi @Andrei,

First of all thank you for your reply.
sorry for the original post but it was my first post on the forum :smile:
I've already changed it and I think it's ok.
Thanks again

1 Like

Because no one has access to your list of files and you are using globals no one else has access to, , please put a debug node on the output of the set flow.selected_array and copy/paste the results in a reply so I could have some data to test with.

Thank you @zenofmud,
already had a debug node at the output of this set flow.selected_array and its result is as follows in the image below. Expand one of the results so you can see all the fields that make up the msg.

image

Please copy the data from the debug ad paste it to a reply so I don't have to type it in.

Pay particular attention to the part about the buttons that appear under your mouse pointer when you over hover a debug message property in the sidebar.

BX00Cy7yHi

Do you really need the column check_box in your table ? Tabulator has a built-in formatter (rowSelection) that allows you to add a tick box in each line:

Row Selection

The rowSelection formatter allows you to add a column of tickboxes down one side of your table to handle row selection, when used as a titleFormatter it provides a tickbox that can toggle the selection of all rows in the table

If you use this formatter it is possible to create a function node using the command SelectRow. Then you can attach this function node to a button.

Select Row

To programmatically select a row you can use the selectRow function.

To select a specific row you can pass the any of the standard row component look up options into the first argument of the function. If you leave the argument blank you will select all rows (if you have set the selectable option to a numeric value, it will be ignored when selecting all rows).

Thanks @Andrei for the suggestion,
I need to have the check boxes because in this specific case I need the option to be able to select the files for download.
I explored your solution that you suggested through the tabulator, despite not being familiar with java script.
In an empty flow I just created a function node with a Tabulator example and a button, but I got the error ""ReferenceError: Tabulator is not defined (line 1, col 13)".
The code I used to test your suggestion was:

var table = new Tabulator("#example-table", {
    height:"311px",
    selectable:true, //make rows selectable
    columns:[
	    {title:"Name", field:"name", width:200},
	    {title:"Progress", field:"progress", width:100, hozAlign:"right", sorter:"number"},
	    {title:"Gender", field:"gender", width:100},
	    {title:"Rating", field:"rating", hozAlign:"center", width:80},
	    {title:"Favourite Color", field:"col"},
	    {title:"Date Of Birth", field:"dob", hozAlign:"center", sorter:"date"},
	    {title:"Driver", field:"car", hozAlign:"center", width:100},
    ],
    rowSelectionChanged:function(data, rows){
        //update selected row counter on selection change
    	document.getElementById("select-stats").innerHTML = data.length;
    },
});

//select row on "select" button click
document.getElementById("select-row").addEventListener("click", function(){
    table.selectRow(1);
});

//deselect row on "deselect" button click
document.getElementById("deselect-row").addEventListener("click", function(){
    table.deselectRow(1);
});

//select row on "select all" button click
document.getElementById("select-all").addEventListener("click", function(){
    table.selectRow();
});

//deselect row on "deselect all" button click
document.getElementById("deselect-all").addEventListener("click", function(){
    table.deselectRow();
});

Thanks @zenofmud for your help and time,
Meanwhile I'm trying @Andrei suggestion because I didn't know the built-in function for rowSelection and meanwhile I've been trying to use this method because it seems simpler and more straightforward, although it's not very easy because I don't know much about java script.

@MiguelSoares , only today I had a look in your flow to realize that it relies on table clicking to perform many actions. Said that I am not sure my suggestion would fit the logic of your flow. Anyway I provide a short flow to demonstrate how the selectRow works. After importing the flow click the Initialize table button and then the Select All button. You will see that all rows get selected. Using this functionality would require your to use a callback to get the selected rows to build the array of files to download. I am not sure which Tabulator event would be the most appropriate for that.

[{"id":"f0ac6e667fc173d9","type":"tab","label":"Download","disabled":false,"info":"","env":[]},{"id":"44599119a368ca93","type":"ui_table","z":"f0ac6e667fc173d9","group":"870a91418c5861d1","name":"File download","order":1,"width":10,"height":7,"columns":[],"outputs":1,"cts":true,"x":780,"y":160,"wires":[["d592b6fcd9261596"]]},{"id":"658e66209e05b0f5","type":"change","z":"f0ac6e667fc173d9","name":"","rules":[{"t":"set","p":"ui_control","pt":"msg","to":"{\"customHeight\":12,\"tabulator\":{\"columns\":[{\"title\":\" <div style='text-align:center'>#</div>\",\"field\":\"id\",\"width\":15,\"formatter\":\"rowSelection\",\"align\":\"center\"},{\"title\":\" <div style='text-align:center'>File Size</div>\",\"field\":\"filesize\",\"align\":\"center\",\"formatter\":\"text\",\"width\":100,\"layout\":\"fitData\"},{\"title\":\" <div style='text-align:center'>File Name</div>\",\"field\":\"filename\",\"formatter\":\"text\",\"width\":330,\"sorter\":\"alphanum\",\"sorterParams\":{\"alignEmptyValues\":\"bottom\"},\"layout\":\"fitData\",\"align\":\"center\"},{\"title\":\"Check\",\"field\":\"check_box\",\"width\":5,\"formatter\":\"tickCross\",\"formatterParams\":{\"target\":\"_blank\",\"allowEmpty\":true,\"allowTruthy\":true,\"tickElement\":\"<i class='fa fa-check-square-o fa-1x'></i>\",\"crossElement\":\"<i class='fa fa-square-o fa-1x'></i>\"},\"align\":\"center\"}],\"initialSort\":[{\"column\":\"filename\",\"dir\":\"asc\"}],\"setSort\":[{\"column\":\"filename\",\"dir\":\"asc\"}],\"layout\":\"fitColumns\",\"movableColumns\":false,\"resizableColumns\":false,\"headerVisible\":true,\"headerSort\":false,\"autoColumns\":false,\"selectable\":true}}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":590,"y":160,"wires":[["44599119a368ca93"]]},{"id":"b1c72c679e24cf25","type":"function","z":"f0ac6e667fc173d9","name":"selectRow","func":"\nmsg.payload={\n    command:\"selectRow\",\n    returnPromise: true\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":350,"y":220,"wires":[["658e66209e05b0f5"]],"info":"# deleteRow(row / [rows])\n\n`row=singleId`\n\nor\n\n`row=[array of IDs]` // seems there is a bug/issue in tabulator\n\ndelete a single the row with an id in the middle from 1 to lastId, hope it exists.\n\nWill fail on the second hit if you inject this two times because the id wad deleteted on the first"},{"id":"d592b6fcd9261596","type":"debug","z":"f0ac6e667fc173d9","name":"Table Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":970,"y":160,"wires":[]},{"id":"e126649fe405fa5a","type":"ui_button","z":"f0ac6e667fc173d9","name":"","group":"2768d5bb10e62e93","order":0,"width":"4","height":"1","passthru":false,"label":"Select All","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"","payloadType":"str","topic":"topic","topicType":"msg","x":180,"y":220,"wires":[["b1c72c679e24cf25"]]},{"id":"1cbd77873713897d","type":"ui_button","z":"f0ac6e667fc173d9","name":"","group":"2768d5bb10e62e93","order":2,"width":"4","height":"1","passthru":false,"label":"Initialize Table","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"[{\"id\":10,\"filesize\":100,\"filename\":\"file10\",\"check_box\":true},{\"id\":20,\"filesize\":200,\"filename\":\"file20\",\"check_box\":false}]","payloadType":"json","topic":"topic","topicType":"msg","x":160,"y":160,"wires":[["658e66209e05b0f5"]]},{"id":"960b6ba012d7ced2","type":"ui_spacer","z":"f0ac6e667fc173d9","name":"spacer","group":"2768d5bb10e62e93","order":1,"width":6,"height":1},{"id":"0a70b37758bc78b8","type":"ui_spacer","z":"f0ac6e667fc173d9","name":"spacer","group":"2768d5bb10e62e93","order":2,"width":6,"height":1},{"id":"870a91418c5861d1","type":"ui_group","name":"List of files in directory","tab":"94ff3c5caa315fa9","order":2,"disp":true,"width":"10","collapse":false,"className":""},{"id":"2768d5bb10e62e93","type":"ui_group","name":"Group 1","tab":"94ff3c5caa315fa9","order":1,"disp":false,"width":6,"collapse":false,"className":""},{"id":"94ff3c5caa315fa9","type":"ui_tab","name":"Download","icon":"fa-cloud-download fa-2x","order":4,"disabled":false,"hidden":false}]

Thanks again @Andrei ,

With your help I've already change my flow to have tick boxes associated with each line, I also got the button to select all and added another one to deselect all. Visually they are working well.

The question now is to be able to put in an array or something the name of the selected files. I saw something related to the getData() command but I don't know if it will be a good option for this :frowning:

thanks again,

any suggestion in this regard is welcome :slight_smile:

Nice !

Exactly. There is the need to add a callback to build the array, most likley using the getdata command as you mentioned. I will have a look when I am back home at night (at work now).

PS: I did a search in the forum to recall how to create a callback function for the ui_table and found a ready to use example..

Copy/paste that callback to the testing flow. Seems to work well.

[{"id":"f0ac6e667fc173d9","type":"tab","label":"Download","disabled":false,"info":"","env":[]},{"id":"44599119a368ca93","type":"ui_table","z":"f0ac6e667fc173d9","group":"870a91418c5861d1","name":"File download","order":1,"width":10,"height":7,"columns":[],"outputs":1,"cts":true,"x":780,"y":160,"wires":[["d592b6fcd9261596"]]},{"id":"658e66209e05b0f5","type":"change","z":"f0ac6e667fc173d9","name":"","rules":[{"t":"set","p":"ui_control","pt":"msg","to":"{\"customHeight\":12,\"tabulator\":{\"columns\":[{\"title\":\" <div style='text-align:center'>#</div>\",\"field\":\"id\",\"width\":15,\"formatter\":\"rowSelection\",\"align\":\"center\"},{\"title\":\" <div style='text-align:center'>File Size</div>\",\"field\":\"filesize\",\"align\":\"center\",\"formatter\":\"text\",\"width\":100,\"layout\":\"fitData\"},{\"title\":\" <div style='text-align:center'>File Name</div>\",\"field\":\"filename\",\"formatter\":\"text\",\"width\":330,\"sorter\":\"alphanum\",\"sorterParams\":{\"alignEmptyValues\":\"bottom\"},\"layout\":\"fitData\",\"align\":\"center\"},{\"title\":\"Check\",\"field\":\"check_box\",\"width\":5,\"formatter\":\"tickCross\",\"formatterParams\":{\"target\":\"_blank\",\"allowEmpty\":true,\"allowTruthy\":true,\"tickElement\":\"<i class='fa fa-check-square-o fa-1x'></i>\",\"crossElement\":\"<i class='fa fa-square-o fa-1x'></i>\"},\"align\":\"center\"}],\"initialSort\":[{\"column\":\"filename\",\"dir\":\"asc\"}],\"setSort\":[{\"column\":\"filename\",\"dir\":\"asc\"}],\"layout\":\"fitColumns\",\"movableColumns\":false,\"resizableColumns\":false,\"headerVisible\":true,\"headerSort\":false,\"autoColumns\":false,\"selectable\":true}}","tot":"json"},{"t":"set","p":"ui_control.tabulator.rowSelectionChanged","pt":"msg","to":"function(data, rows){this.send({ui_control:{'callback':'rowSelectionChanged','rowSelection':data}});}","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":580,"y":160,"wires":[["44599119a368ca93"]]},{"id":"b1c72c679e24cf25","type":"function","z":"f0ac6e667fc173d9","name":"selectRow","func":"\nmsg.payload={\n    command:\"selectRow\",\n    returnPromise: true\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":350,"y":220,"wires":[["658e66209e05b0f5"]],"info":"# deleteRow(row / [rows])\n\n`row=singleId`\n\nor\n\n`row=[array of IDs]` // seems there is a bug/issue in tabulator\n\ndelete a single the row with an id in the middle from 1 to lastId, hope it exists.\n\nWill fail on the second hit if you inject this two times because the id wad deleteted on the first"},{"id":"d592b6fcd9261596","type":"debug","z":"f0ac6e667fc173d9","name":"Table Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":970,"y":160,"wires":[]},{"id":"e126649fe405fa5a","type":"ui_button","z":"f0ac6e667fc173d9","name":"","group":"2768d5bb10e62e93","order":0,"width":"4","height":"1","passthru":false,"label":"Select All","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"","payloadType":"str","topic":"topic","topicType":"msg","x":180,"y":220,"wires":[["b1c72c679e24cf25"]]},{"id":"1cbd77873713897d","type":"ui_button","z":"f0ac6e667fc173d9","name":"","group":"2768d5bb10e62e93","order":2,"width":"4","height":"1","passthru":false,"label":"Initialize Table","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"[{\"id\":10,\"filesize\":100,\"filename\":\"file10\",\"check_box\":true},{\"id\":20,\"filesize\":200,\"filename\":\"file20\",\"check_box\":false}]","payloadType":"json","topic":"topic","topicType":"msg","x":160,"y":160,"wires":[["658e66209e05b0f5"]]},{"id":"960b6ba012d7ced2","type":"ui_spacer","z":"f0ac6e667fc173d9","name":"spacer","group":"2768d5bb10e62e93","order":1,"width":6,"height":1},{"id":"0a70b37758bc78b8","type":"ui_spacer","z":"f0ac6e667fc173d9","name":"spacer","group":"2768d5bb10e62e93","order":2,"width":6,"height":1},{"id":"870a91418c5861d1","type":"ui_group","name":"List of files in directory","tab":"94ff3c5caa315fa9","order":2,"disp":true,"width":"10","collapse":false,"className":""},{"id":"2768d5bb10e62e93","type":"ui_group","name":"Group 1","tab":"94ff3c5caa315fa9","order":1,"disp":false,"width":6,"collapse":false,"className":""},{"id":"94ff3c5caa315fa9","type":"ui_tab","name":"Download","icon":"fa-cloud-download fa-2x","order":4,"disabled":false,"hidden":false}]

@Andrei first of all you're a machine :laughing:

Then,
I tested this example that you sent in a flow alone and it works, I can see the array being dynamic when adding or removing files depending on whether they are selected or not.
The problem is that I added it to my main flow, exactly the same (without adding or removing nodes to the flow) and it doesn't work. The debug node at the output of the table only shows "undifened" payloads and I don't see the array being created, whether I select one file at a time or all via select all.

Do you have any idea what it might be? :frowning:

Thanks again

Sorry to jump in as @Andrei does an excellent job. Have you enabled selectable In your main flow?

msg.ui_control.tabulator={
    "selectable":true, 
    "columns":[ define your columns here ],
    "rowSelectionChanged":"function(data, rows){this.send({ui_control:{'callback':'rowSelectionChanged','rowSelection':data}});}"
}

No problem @Christian-Me, any help is welcome.

As I told @Andrei above, I tested the flow that he posted above and it works, when I try it on mine it doesn't work.
The only difference is that in Andrei's flow, in the "Initialize Table" button he defines a payload to be able to have some filenames to show in the table, in mine I don't have that and I don't know if the problem can't come from there.

I leave you my flow to check if you have a chance, and if you notice the change node that sets the properties of ui_control I have the option "selectable" in "true".

To put you in context, in the first nodes I build the commands for ssh connection and to list the files in the directory, then I split to have only filename and filesize to show in the table, then the function node "updateOrAddData" which removes the blanks and puts them in the table .

Maybe you will find that some things are not very well done but I am new to node red and java script :laughing:

[
    {
        "id": "5d8ae3d6a240f30b",
        "type": "tab",
        "label": "DW_v2_test",
        "disabled": false,
        "info": ""
    },
    {
        "id": "2b28f7c08c539c66",
        "type": "ui_button",
        "z": "5d8ae3d6a240f30b",
        "name": "",
        "group": "2768d5bb10e62e93",
        "order": 2,
        "width": 0,
        "height": 0,
        "passthru": false,
        "label": "Update Files List",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "",
        "payloadType": "str",
        "topic": "topic",
        "topicType": "msg",
        "x": 150,
        "y": 320,
        "wires": [
            [
                "b9982c0efbcbb0ef",
                "ea57acbfc651477e"
            ]
        ]
    },
    {
        "id": "b564775da71227cc",
        "type": "inject",
        "z": "5d8ae3d6a240f30b",
        "name": "",
        "props": [
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "x": 110,
        "y": 180,
        "wires": [
            [
                "b9982c0efbcbb0ef"
            ]
        ]
    },
    {
        "id": "b9982c0efbcbb0ef",
        "type": "function",
        "z": "5d8ae3d6a240f30b",
        "name": "",
        "func": "var user = global.get(\"user\");\nvar ip = global.get(\"host\");\nvar cmd1 = \"ls\";\nvar cmd2 = \"-lvh\";\nvar dir = \"/home/pi/animalTAGS/data/videos/\";\nvar header1 =\"| awk '{print $5 \";\nvar header2 = '\"->\"';\nvar header3 = \" $9}'\";\nvar file = {};\nvar status = {};\n \n//ssh pi@10.42.0.2 ls /home/pi/animalTAGS/data/videos/ -lvh | awk '{print $5 \" -> \" $9}'\nmsg.payload =  `ssh ${user}@${ip} ${cmd1} ${dir} ${cmd2} ${header1}${header2}${header3}`;\n \nreturn msg;\n\n\n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 300,
        "y": 200,
        "wires": [
            [
                "83d86483611034dc"
            ]
        ]
    },
    {
        "id": "83d86483611034dc",
        "type": "exec",
        "z": "5d8ae3d6a240f30b",
        "command": "",
        "addpay": "payload",
        "append": "",
        "useSpawn": "false",
        "timer": "10",
        "winHide": false,
        "oldrc": false,
        "name": "",
        "x": 450,
        "y": 200,
        "wires": [
            [
                "e9837fd8314a16a2"
            ],
            [],
            []
        ]
    },
    {
        "id": "e9837fd8314a16a2",
        "type": "json",
        "z": "5d8ae3d6a240f30b",
        "name": "",
        "property": "payload",
        "action": "str",
        "pretty": true,
        "x": 630,
        "y": 180,
        "wires": [
            [
                "d73c37efbfea72b4",
                "8a27eb67146619fe"
            ]
        ]
    },
    {
        "id": "52405a56f517c82b",
        "type": "debug",
        "z": "5d8ae3d6a240f30b",
        "name": "js",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 950,
        "y": 300,
        "wires": []
    },
    {
        "id": "d73c37efbfea72b4",
        "type": "split",
        "z": "5d8ae3d6a240f30b",
        "name": "",
        "splt": "\\n",
        "spltType": "str",
        "arraySplt": "1",
        "arraySpltType": "len",
        "stream": false,
        "addname": "key",
        "x": 770,
        "y": 180,
        "wires": [
            [
                "52405a56f517c82b",
                "1c089ef3c705a27c"
            ]
        ]
    },
    {
        "id": "1c089ef3c705a27c",
        "type": "function",
        "z": "5d8ae3d6a240f30b",
        "name": "",
        "func": "var data=msg.payload;\nvar temp=data.split(\"->\");\nmsg.file_size=temp[0];\nmsg.file_name=temp[1];\n\nreturn msg;\n\n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 920,
        "y": 180,
        "wires": [
            [
                "0e08cebceae36f81"
            ]
        ]
    },
    {
        "id": "8a27eb67146619fe",
        "type": "debug",
        "z": "5d8ae3d6a240f30b",
        "name": "debug_json",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 770,
        "y": 300,
        "wires": []
    },
    {
        "id": "b15a306b063146d4",
        "type": "ui_table",
        "z": "5d8ae3d6a240f30b",
        "group": "870a91418c5861d1",
        "name": "",
        "order": 1,
        "width": 10,
        "height": 7,
        "columns": [],
        "outputs": 1,
        "cts": true,
        "x": 1210,
        "y": 360,
        "wires": [
            [
                "690e93e8712dbaad"
            ]
        ]
    },
    {
        "id": "0e08cebceae36f81",
        "type": "function",
        "z": "5d8ae3d6a240f30b",
        "name": "updateOrAddData (add)",
        "func": "var check=msg.file_size;\nif(check===\"\"){\n    return null;   \n}\nelse {\n    var id=flow.get(\"lastId\") || 0;\n    ++id;\n    msg.payload={\n        command:\"updateOrAddData\",\n        arguments: [\n            [\n                {\n                \"id\":id,\n                \"filesize\":msg.file_size,\n                \"filename\":msg.file_name\n                }\n            ]\n        ],\n        returnPromise: true\n    }\n    flow.set(\"lastId\",id);\n    return msg;    \n}\n\n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1130,
        "y": 180,
        "wires": [
            [
                "b15a306b063146d4"
            ]
        ],
        "info": "# updateOrAddData([row])\n\nadds a the row with a new id (same as addRow)"
    },
    {
        "id": "3a5b70bffdce2cc0",
        "type": "inject",
        "z": "5d8ae3d6a240f30b",
        "name": "format table",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payloadType": "date",
        "x": 110,
        "y": 440,
        "wires": [
            []
        ]
    },
    {
        "id": "ea57acbfc651477e",
        "type": "change",
        "z": "5d8ae3d6a240f30b",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "ui_control",
                "pt": "msg",
                "to": "{\"customHeight\":12,\"tabulator\":{\"columns\":[{\"title\":\" <div style='text-align:center'>#</div>\",\"field\":\"id\",\"width\":5,\"formatter\":\"rowSelection\",\"align\":\"center\"},{\"title\":\" <div style='text-align:center'>File Size</div>\",\"field\":\"filesize\",\"align\":\"center\",\"formatter\":\"text\",\"width\":100,\"layout\":\"fitData\"},{\"title\":\" <div style='text-align:center'>File Name</div>\",\"field\":\"filename\",\"formatter\":\"text\",\"width\":330,\"sorter\":\"alphanum\",\"sorterParams\":{\"alignEmptyValues\":\"bottom\"},\"layout\":\"fitData\",\"align\":\"center\"}],\"initialSort\":[{\"column\":\"filename\",\"dir\":\"asc\"}],\"setSort\":[{\"column\":\"filename\",\"dir\":\"asc\"}],\"layout\":\"fitColumns\",\"movableColumns\":false,\"resizableColumns\":false,\"headerVisible\":true,\"headerSort\":false,\"autoColumns\":false,\"selectable\":true}}",
                "tot": "json"
            },
            {
                "t": "set",
                "p": "ui_control.tabulator.rowSelectionChanged",
                "pt": "msg",
                "to": "function(data, rows){this.send({ui_control:{'callback':'rowSelectionChanged','rowSelection':data}});}",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 560,
        "y": 380,
        "wires": [
            [
                "b15a306b063146d4"
            ]
        ]
    },
    {
        "id": "690e93e8712dbaad",
        "type": "debug",
        "z": "5d8ae3d6a240f30b",
        "name": "js",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1250,
        "y": 440,
        "wires": []
    },
    {
        "id": "cf7de094252476c0",
        "type": "change",
        "z": "5d8ae3d6a240f30b",
        "d": true,
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "ui_control",
                "pt": "msg",
                "to": "{\"customHeight\":12,\"tabulator\":{\"columns\":[{\"title\":\" <div style='text-align:center'>#</div>\",\"field\":\"id\",\"width\":15,\"formatter\":\"rowSelection\",\"align\":\"center\"},{\"title\":\" <div style='text-align:center'>File Size</div>\",\"field\":\"filesize\",\"align\":\"center\",\"formatter\":\"text\",\"width\":100,\"layout\":\"fitData\"},{\"title\":\" <div style='text-align:center'>File Name</div>\",\"field\":\"filename\",\"formatter\":\"text\",\"width\":330,\"sorter\":\"alphanum\",\"sorterParams\":{\"alignEmptyValues\":\"bottom\"},\"layout\":\"fitData\",\"align\":\"center\"},{\"title\":\"Check\",\"field\":\"check_box\",\"width\":5,\"formatter\":\"tickCross\",\"formatterParams\":{\"target\":\"_blank\",\"allowEmpty\":true,\"allowTruthy\":true,\"tickElement\":\"<i class='fa fa-check-square-o fa-1x'></i>\",\"crossElement\":\"<i class='fa fa-square-o fa-1x'></i>\"},\"align\":\"center\"}],\"initialSort\":[{\"column\":\"filename\",\"dir\":\"asc\"}],\"setSort\":[{\"column\":\"filename\",\"dir\":\"asc\"}],\"layout\":\"fitColumns\",\"movableColumns\":false,\"resizableColumns\":false,\"headerVisible\":true,\"headerSort\":false,\"autoColumns\":false,\"selectable\":true}}",
                "tot": "json"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 230,
        "y": 820,
        "wires": [
            []
        ]
    },
    {
        "id": "a5e5ef2fd9f9043e",
        "type": "function",
        "z": "5d8ae3d6a240f30b",
        "name": "selectRow",
        "func": "\nmsg.payload={\n    command:\"selectRow\",\n    returnPromise: true\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 250,
        "y": 520,
        "wires": [
            [
                "ea57acbfc651477e"
            ]
        ],
        "info": "# deleteRow(row / [rows])\n\n`row=singleId`\n\nor\n\n`row=[array of IDs]` // seems there is a bug/issue in tabulator\n\ndelete a single the row with an id in the middle from 1 to lastId, hope it exists.\n\nWill fail on the second hit if you inject this two times because the id wad deleteted on the first"
    },
    {
        "id": "bfd05de29112882f",
        "type": "ui_button",
        "z": "5d8ae3d6a240f30b",
        "name": "",
        "group": "2768d5bb10e62e93",
        "order": 0,
        "width": "4",
        "height": "1",
        "passthru": false,
        "label": "Select All",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "",
        "payloadType": "str",
        "topic": "topic",
        "topicType": "msg",
        "x": 80,
        "y": 520,
        "wires": [
            [
                "a5e5ef2fd9f9043e"
            ]
        ]
    },
    {
        "id": "3375a2c2f9ce4689",
        "type": "ui_button",
        "z": "5d8ae3d6a240f30b",
        "name": "",
        "group": "2768d5bb10e62e93",
        "order": 0,
        "width": "4",
        "height": "1",
        "passthru": false,
        "label": "DeSelect All",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "",
        "payloadType": "str",
        "topic": "topic",
        "topicType": "msg",
        "x": 90,
        "y": 580,
        "wires": [
            [
                "470d9262730ea258"
            ]
        ]
    },
    {
        "id": "470d9262730ea258",
        "type": "function",
        "z": "5d8ae3d6a240f30b",
        "name": "deselectRow",
        "func": "\nmsg.payload={\n    command:\"deselectRow\",\n    returnPromise: true\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 250,
        "y": 580,
        "wires": [
            [
                "b15a306b063146d4"
            ]
        ],
        "info": "# deleteRow(row / [rows])\n\n`row=singleId`\n\nor\n\n`row=[array of IDs]` // seems there is a bug/issue in tabulator\n\ndelete a single the row with an id in the middle from 1 to lastId, hope it exists.\n\nWill fail on the second hit if you inject this two times because the id wad deleteted on the first"
    },
    {
        "id": "12d983df1d74df0c",
        "type": "change",
        "z": "5d8ae3d6a240f30b",
        "d": true,
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "ui_control",
                "pt": "msg",
                "to": "{\"customHeight\":12,\"tabulator\":{\"columns\":[{\"title\":\" <div style='text-align:center'>#</div>\",\"field\":\"id\",\"width\":15,\"formatter\":\"rowSelection\",\"align\":\"center\"},{\"title\":\" <div style='text-align:center'>File Size</div>\",\"field\":\"filesize\",\"align\":\"center\",\"formatter\":\"text\",\"width\":100,\"layout\":\"fitData\"},{\"title\":\" <div style='text-align:center'>File Name</div>\",\"field\":\"filename\",\"formatter\":\"text\",\"width\":330,\"sorter\":\"alphanum\",\"sorterParams\":{\"alignEmptyValues\":\"bottom\"},\"layout\":\"fitData\",\"align\":\"center\"}],\"initialSort\":[{\"column\":\"filename\",\"dir\":\"asc\"}],\"setSort\":[{\"column\":\"filename\",\"dir\":\"asc\"}],\"layout\":\"fitColumns\",\"movableColumns\":false,\"resizableColumns\":false,\"headerVisible\":true,\"headerSort\":false,\"autoColumns\":false,\"selectable\":true}}",
                "tot": "json"
            },
            {
                "t": "set",
                "p": "ui_control.tabulator.rowSelectionChanged",
                "pt": "msg",
                "to": "function(data, rows){this.send({ui_control:{'callback':'rowSelectionChanged','rowSelection':data}});}",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 280,
        "y": 880,
        "wires": [
            []
        ]
    },
    {
        "id": "7aae3184bbd5501c",
        "type": "ui_spacer",
        "z": "5d8ae3d6a240f30b",
        "name": "spacer",
        "group": "2768d5bb10e62e93",
        "order": 1,
        "width": 6,
        "height": 1
    },
    {
        "id": "32edff36c097bdf1",
        "type": "ui_spacer",
        "z": "5d8ae3d6a240f30b",
        "name": "spacer",
        "group": "2768d5bb10e62e93",
        "order": 3,
        "width": 6,
        "height": 1
    },
    {
        "id": "07608dfbcb112e7b",
        "type": "ui_spacer",
        "z": "5d8ae3d6a240f30b",
        "name": "spacer",
        "group": "2768d5bb10e62e93",
        "order": 6,
        "width": 6,
        "height": 1
    },
    {
        "id": "2768d5bb10e62e93",
        "type": "ui_group",
        "name": "Group 1",
        "tab": "94ff3c5caa315fa9",
        "order": 1,
        "disp": false,
        "width": 6,
        "collapse": false,
        "className": ""
    },
    {
        "id": "870a91418c5861d1",
        "type": "ui_group",
        "name": "List of files in directory",
        "tab": "94ff3c5caa315fa9",
        "order": 2,
        "disp": true,
        "width": "10",
        "collapse": false,
        "className": ""
    },
    {
        "id": "94ff3c5caa315fa9",
        "type": "ui_tab",
        "name": "Download",
        "icon": "fa-cloud-download fa-2x",
        "order": 4,
        "disabled": false,
        "hidden": false
    }
]

Thank you very much for your help

Actually your flow is well written and clever on resolving some problems like generating the list of files and updating ui_table dynamically. I would anyway propose a simpler approach to populating the list of files. I find easier to create an array of objects and send the full table to the ui_table node. I will see how it could be done. I jut need to bring up a raspberry pi for the testing.

Thanks for the motivation @Andrei :laughing:

Actually looking step by step at my flow, I deleted json's node because I was converting the payload (return list of files in directory) to json but I don't need to. Then I just need to do the splits to get only the fields I want referring to each file (size and name).

The strange thing is that testing yours works very well and the array dynamics never failed. When I test on mine, I have no result. As I mentioned above in the response to @Christian, the only thing that's different is that on your "Initialize table" button you pass a payload but I think it's just to have data to show. Maybe the problem can also be in my function node "updadeOrAddData, I don't know :frowning:

Thank you so much for your attention

Good catch.

I would suggest adding a second flow variable to store the full table. It would looks like:

Then is it trivial to update the ui_table node. You just need to read the list from context. Using this approach your main concern is to keep the list updated in the context. Whenever you change the list you should send it to the ui_table node.

Below flow shows it in action.

[{"id":"f0ac6e667fc173d9","type":"tab","label":"Download","disabled":false,"info":"","env":[]},{"id":"44599119a368ca93","type":"ui_table","z":"f0ac6e667fc173d9","group":"870a91418c5861d1","name":"File download","order":1,"width":10,"height":7,"columns":[],"outputs":1,"cts":true,"x":740,"y":320,"wires":[["d592b6fcd9261596"]]},{"id":"658e66209e05b0f5","type":"change","z":"f0ac6e667fc173d9","name":"","rules":[{"t":"set","p":"ui_control","pt":"msg","to":"{\"customHeight\":12,\"tabulator\":{\"columns\":[{\"title\":\" <div style='text-align:center'>#</div>\",\"field\":\"id\",\"width\":15,\"formatter\":\"rowSelection\",\"align\":\"center\"},{\"title\":\" <div style='text-align:center'>File Size</div>\",\"field\":\"filesize\",\"align\":\"center\",\"formatter\":\"text\",\"width\":100,\"layout\":\"fitData\"},{\"title\":\" <div style='text-align:center'>File Name</div>\",\"field\":\"filename\",\"formatter\":\"text\",\"width\":330,\"sorter\":\"alphanum\",\"sorterParams\":{\"alignEmptyValues\":\"bottom\"},\"layout\":\"fitData\",\"align\":\"center\"},{\"title\":\"Check\",\"field\":\"check_box\",\"width\":5,\"formatter\":\"tickCross\",\"formatterParams\":{\"target\":\"_blank\",\"allowEmpty\":true,\"allowTruthy\":true,\"tickElement\":\"<i class='fa fa-check-square-o fa-1x'></i>\",\"crossElement\":\"<i class='fa fa-square-o fa-1x'></i>\"},\"align\":\"center\"}],\"initialSort\":[{\"column\":\"filename\",\"dir\":\"asc\"}],\"setSort\":[{\"column\":\"filename\",\"dir\":\"asc\"}],\"layout\":\"fitColumns\",\"movableColumns\":false,\"resizableColumns\":false,\"headerVisible\":true,\"headerSort\":false,\"autoColumns\":false,\"selectable\":true}}","tot":"json"},{"t":"set","p":"ui_control.tabulator.rowSelectionChanged","pt":"msg","to":"function(data, rows){this.send({ui_control:{'callback':'rowSelectionChanged','rowSelection':data}});}","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":540,"y":320,"wires":[["44599119a368ca93"]]},{"id":"b1c72c679e24cf25","type":"function","z":"f0ac6e667fc173d9","name":"selectRow","func":"\nmsg.payload={\n    command:\"selectRow\",\n    returnPromise: true\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":310,"y":380,"wires":[["658e66209e05b0f5"]],"info":"# deleteRow(row / [rows])\n\n`row=singleId`\n\nor\n\n`row=[array of IDs]` // seems there is a bug/issue in tabulator\n\ndelete a single the row with an id in the middle from 1 to lastId, hope it exists.\n\nWill fail on the second hit if you inject this two times because the id wad deleteted on the first"},{"id":"d592b6fcd9261596","type":"debug","z":"f0ac6e667fc173d9","name":"Table Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":930,"y":320,"wires":[]},{"id":"e126649fe405fa5a","type":"ui_button","z":"f0ac6e667fc173d9","name":"","group":"2768d5bb10e62e93","order":0,"width":"4","height":"1","passthru":false,"label":"Select All","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"","payloadType":"str","topic":"topic","topicType":"msg","x":140,"y":380,"wires":[["b1c72c679e24cf25"]]},{"id":"1cbd77873713897d","type":"ui_button","z":"f0ac6e667fc173d9","name":"","group":"2768d5bb10e62e93","order":2,"width":"4","height":"1","passthru":false,"label":"Initialize Table","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"","payloadType":"str","topic":"topic","topicType":"msg","x":120,"y":320,"wires":[["ce4c5218fe191a89"]]},{"id":"1bcfd549a54054a3","type":"inject","z":"f0ac6e667fc173d9","name":"Initialize","props":[{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"test","x":110,"y":100,"wires":[["158a744767d3cef1"]]},{"id":"d52f7df509f4be7c","type":"split","z":"f0ac6e667fc173d9","name":"","splt":"\\n","spltType":"str","arraySplt":"1","arraySpltType":"len","stream":true,"addname":"key","x":650,"y":100,"wires":[["3063682c39c766b6"]]},{"id":"3063682c39c766b6","type":"function","z":"f0ac6e667fc173d9","name":"","func":"var data=msg.payload;\nvar temp=data.split(\"->\");\nmsg.file_size=temp[0];\nmsg.file_name=temp[1];\n\nreturn msg;\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":840,"y":100,"wires":[["880fd5864a1a3142"]]},{"id":"880fd5864a1a3142","type":"function","z":"f0ac6e667fc173d9","name":"updateOrAddData (add)","func":"let fileList = flow.get(\"fileList\") || [];\nlet pay = {};\n\nvar check=msg.file_size;\nif(check===\"\"){\n    return null;   \n}\nelse {\n    var id=flow.get(\"lastId\") || 0;\n    ++id;\n    pay = {\n            \"id\":id,\n            \"filesize\":msg.file_size,\n            \"filename\":msg.file_name\n          }\n    fileList.push(pay);\n    flow.set(\"lastId\",id);\n    \n       \n}\n\nflow.set(\"fileList\" , fileList);\nreturn msg; ","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1050,"y":100,"wires":[[]],"info":"# updateOrAddData([row])\n\nadds a the row with a new id (same as addRow)"},{"id":"50fc5c2cd4c1d21f","type":"template","z":"f0ac6e667fc173d9","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"->\n238K->flows_pi.json\n5.9K->flows_pi_cred.json\n4.0K->lib\n12K->node_modules\n568->package.json\n98K->package-lock.json\n140K->pic.jpg\n158K->pic-1.jpg\n169K->pic-2.jpg\n155K->pic-3.jpg\n14K->settings.js\n","output":"str","x":500,"y":100,"wires":[["d52f7df509f4be7c"]]},{"id":"158a744767d3cef1","type":"change","z":"f0ac6e667fc173d9","name":"Restart flow context","rules":[{"t":"set","p":"fileList","pt":"flow","to":"[]","tot":"json"},{"t":"set","p":"lastId","pt":"flow","to":"0","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":290,"y":100,"wires":[["50fc5c2cd4c1d21f"]]},{"id":"ce4c5218fe191a89","type":"change","z":"f0ac6e667fc173d9","name":"Load list from context","rules":[{"t":"set","p":"payload","pt":"msg","to":"fileList","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":320,"y":320,"wires":[["658e66209e05b0f5"]]},{"id":"960b6ba012d7ced2","type":"ui_spacer","z":"f0ac6e667fc173d9","name":"spacer","group":"2768d5bb10e62e93","order":1,"width":6,"height":1},{"id":"0a70b37758bc78b8","type":"ui_spacer","z":"f0ac6e667fc173d9","name":"spacer","group":"2768d5bb10e62e93","order":2,"width":6,"height":1},{"id":"870a91418c5861d1","type":"ui_group","name":"List of files in directory","tab":"94ff3c5caa315fa9","order":2,"disp":true,"width":"10","collapse":false,"className":""},{"id":"2768d5bb10e62e93","type":"ui_group","name":"Group 1","tab":"94ff3c5caa315fa9","order":1,"disp":false,"width":6,"collapse":false,"className":""},{"id":"94ff3c5caa315fa9","type":"ui_tab","name":"Download","icon":"fa-cloud-download fa-2x","order":4,"disabled":false,"hidden":false}]

I used a template node to simulate the list of files you get from ssh.

and now I added a change node to the flow to store a new flow context to keep the modified list. Whenever you change a selection this flow context will be immediately updated.

[{"id":"f0ac6e667fc173d9","type":"tab","label":"Download","disabled":false,"info":"","env":[]},{"id":"44599119a368ca93","type":"ui_table","z":"f0ac6e667fc173d9","group":"870a91418c5861d1","name":"File download","order":1,"width":10,"height":7,"columns":[],"outputs":1,"cts":true,"x":740,"y":320,"wires":[["d592b6fcd9261596","7bb15ba4a1d31594"]]},{"id":"658e66209e05b0f5","type":"change","z":"f0ac6e667fc173d9","name":"","rules":[{"t":"set","p":"ui_control","pt":"msg","to":"{\"customHeight\":12,\"tabulator\":{\"columns\":[{\"title\":\" <div style='text-align:center'>#</div>\",\"field\":\"id\",\"width\":15,\"formatter\":\"rowSelection\",\"align\":\"center\"},{\"title\":\" <div style='text-align:center'>File Size</div>\",\"field\":\"filesize\",\"align\":\"center\",\"formatter\":\"text\",\"width\":100,\"layout\":\"fitData\"},{\"title\":\" <div style='text-align:center'>File Name</div>\",\"field\":\"filename\",\"formatter\":\"text\",\"width\":330,\"sorter\":\"alphanum\",\"sorterParams\":{\"alignEmptyValues\":\"bottom\"},\"layout\":\"fitData\",\"align\":\"center\"},{\"title\":\"Check\",\"field\":\"check_box\",\"width\":5,\"formatter\":\"tickCross\",\"formatterParams\":{\"target\":\"_blank\",\"allowEmpty\":true,\"allowTruthy\":true,\"tickElement\":\"<i class='fa fa-check-square-o fa-1x'></i>\",\"crossElement\":\"<i class='fa fa-square-o fa-1x'></i>\"},\"align\":\"center\"}],\"initialSort\":[{\"column\":\"filename\",\"dir\":\"asc\"}],\"setSort\":[{\"column\":\"filename\",\"dir\":\"asc\"}],\"layout\":\"fitColumns\",\"movableColumns\":false,\"resizableColumns\":false,\"headerVisible\":true,\"headerSort\":false,\"autoColumns\":false,\"selectable\":true}}","tot":"json"},{"t":"set","p":"ui_control.tabulator.rowSelectionChanged","pt":"msg","to":"function(data, rows){this.send({ui_control:{'callback':'rowSelectionChanged','rowSelection':data}});}","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":540,"y":320,"wires":[["44599119a368ca93"]]},{"id":"b1c72c679e24cf25","type":"function","z":"f0ac6e667fc173d9","name":"selectRow","func":"\nmsg.payload={\n    command:\"selectRow\",\n    returnPromise: true\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":310,"y":380,"wires":[["658e66209e05b0f5"]],"info":"# deleteRow(row / [rows])\n\n`row=singleId`\n\nor\n\n`row=[array of IDs]` // seems there is a bug/issue in tabulator\n\ndelete a single the row with an id in the middle from 1 to lastId, hope it exists.\n\nWill fail on the second hit if you inject this two times because the id wad deleteted on the first"},{"id":"d592b6fcd9261596","type":"debug","z":"f0ac6e667fc173d9","name":"Table Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":970,"y":320,"wires":[]},{"id":"e126649fe405fa5a","type":"ui_button","z":"f0ac6e667fc173d9","name":"","group":"2768d5bb10e62e93","order":0,"width":"4","height":"1","passthru":false,"label":"Select All","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"","payloadType":"str","topic":"topic","topicType":"msg","x":140,"y":380,"wires":[["b1c72c679e24cf25"]]},{"id":"1cbd77873713897d","type":"ui_button","z":"f0ac6e667fc173d9","name":"","group":"2768d5bb10e62e93","order":2,"width":"4","height":"1","passthru":false,"label":"Initialize Table","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"","payloadType":"str","topic":"topic","topicType":"msg","x":120,"y":320,"wires":[["ce4c5218fe191a89"]]},{"id":"1bcfd549a54054a3","type":"inject","z":"f0ac6e667fc173d9","name":"Initialize","props":[{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"test","x":110,"y":220,"wires":[["158a744767d3cef1"]]},{"id":"d52f7df509f4be7c","type":"split","z":"f0ac6e667fc173d9","name":"","splt":"\\n","spltType":"str","arraySplt":"1","arraySpltType":"len","stream":true,"addname":"key","x":650,"y":220,"wires":[["3063682c39c766b6"]]},{"id":"3063682c39c766b6","type":"function","z":"f0ac6e667fc173d9","name":"","func":"var data=msg.payload;\nvar temp=data.split(\"->\");\nmsg.file_size=temp[0];\nmsg.file_name=temp[1];\n\nreturn msg;\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":840,"y":220,"wires":[["880fd5864a1a3142"]]},{"id":"880fd5864a1a3142","type":"function","z":"f0ac6e667fc173d9","name":"updateOrAddData (add)","func":"let fileList = flow.get(\"fileList\") || [];\nlet pay = {};\n\nvar check=msg.file_size;\nif(check===\"\"){\n    return null;   \n}\nelse {\n    var id=flow.get(\"lastId\") || 0;\n    ++id;\n    pay = {\n            \"id\":id,\n            \"filesize\":msg.file_size,\n            \"filename\":msg.file_name\n          }\n    fileList.push(pay);\n    flow.set(\"lastId\",id);\n    \n       \n}\n\nflow.set(\"fileList\" , fileList);\nreturn msg; ","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1050,"y":220,"wires":[[]],"info":"# updateOrAddData([row])\n\nadds a the row with a new id (same as addRow)"},{"id":"50fc5c2cd4c1d21f","type":"template","z":"f0ac6e667fc173d9","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"->\n238K->flows_pi.json\n5.9K->flows_pi_cred.json\n4.0K->lib\n12K->node_modules\n568->package.json\n98K->package-lock.json\n140K->pic.jpg\n158K->pic-1.jpg\n169K->pic-2.jpg\n155K->pic-3.jpg\n14K->settings.js\n","output":"str","x":500,"y":220,"wires":[["d52f7df509f4be7c"]]},{"id":"158a744767d3cef1","type":"change","z":"f0ac6e667fc173d9","name":"Restart flow context","rules":[{"t":"set","p":"fileList","pt":"flow","to":"[]","tot":"json"},{"t":"set","p":"lastId","pt":"flow","to":"0","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":290,"y":220,"wires":[["50fc5c2cd4c1d21f"]]},{"id":"ce4c5218fe191a89","type":"change","z":"f0ac6e667fc173d9","name":"Load list from context","rules":[{"t":"set","p":"payload","pt":"msg","to":"fileList","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":320,"y":320,"wires":[["658e66209e05b0f5"]]},{"id":"7bb15ba4a1d31594","type":"change","z":"f0ac6e667fc173d9","name":"","rules":[{"t":"set","p":"newFileList","pt":"flow","to":"ui_control.rowSelection","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":950,"y":400,"wires":[[]]},{"id":"960b6ba012d7ced2","type":"ui_spacer","z":"f0ac6e667fc173d9","name":"spacer","group":"2768d5bb10e62e93","order":1,"width":6,"height":1},{"id":"0a70b37758bc78b8","type":"ui_spacer","z":"f0ac6e667fc173d9","name":"spacer","group":"2768d5bb10e62e93","order":2,"width":6,"height":1},{"id":"870a91418c5861d1","type":"ui_group","name":"List of files in directory","tab":"94ff3c5caa315fa9","order":2,"disp":true,"width":"10","collapse":false,"className":""},{"id":"2768d5bb10e62e93","type":"ui_group","name":"Group 1","tab":"94ff3c5caa315fa9","order":1,"disp":false,"width":6,"collapse":false,"className":""},{"id":"94ff3c5caa315fa9","type":"ui_tab","name":"Download","icon":"fa-cloud-download fa-2x","order":4,"disabled":false,"hidden":false}]

I am leaving now but I think these suggestions will get you going.

Final addition: a button to update the table.

[{"id":"f0ac6e667fc173d9","type":"tab","label":"Download","disabled":false,"info":"","env":[]},{"id":"44599119a368ca93","type":"ui_table","z":"f0ac6e667fc173d9","group":"870a91418c5861d1","name":"File download","order":1,"width":10,"height":7,"columns":[],"outputs":1,"cts":true,"x":740,"y":320,"wires":[["d592b6fcd9261596","7bb15ba4a1d31594"]]},{"id":"658e66209e05b0f5","type":"change","z":"f0ac6e667fc173d9","name":"","rules":[{"t":"set","p":"ui_control","pt":"msg","to":"{\"customHeight\":12,\"tabulator\":{\"columns\":[{\"title\":\" <div style='text-align:center'>#</div>\",\"field\":\"id\",\"width\":15,\"formatter\":\"rowSelection\",\"align\":\"center\"},{\"title\":\" <div style='text-align:center'>File Size</div>\",\"field\":\"filesize\",\"align\":\"center\",\"formatter\":\"text\",\"width\":100,\"layout\":\"fitData\"},{\"title\":\" <div style='text-align:center'>File Name</div>\",\"field\":\"filename\",\"formatter\":\"text\",\"width\":330,\"sorter\":\"alphanum\",\"sorterParams\":{\"alignEmptyValues\":\"bottom\"},\"layout\":\"fitData\",\"align\":\"center\"},{\"title\":\"Check\",\"field\":\"check_box\",\"width\":5,\"formatter\":\"tickCross\",\"formatterParams\":{\"target\":\"_blank\",\"allowEmpty\":true,\"allowTruthy\":true,\"tickElement\":\"<i class='fa fa-check-square-o fa-1x'></i>\",\"crossElement\":\"<i class='fa fa-square-o fa-1x'></i>\"},\"align\":\"center\"}],\"initialSort\":[{\"column\":\"filename\",\"dir\":\"asc\"}],\"setSort\":[{\"column\":\"filename\",\"dir\":\"asc\"}],\"layout\":\"fitColumns\",\"movableColumns\":false,\"resizableColumns\":false,\"headerVisible\":true,\"headerSort\":false,\"autoColumns\":false,\"selectable\":true}}","tot":"json"},{"t":"set","p":"ui_control.tabulator.rowSelectionChanged","pt":"msg","to":"function(data, rows){this.send({ui_control:{'callback':'rowSelectionChanged','rowSelection':data}});}","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":540,"y":320,"wires":[["44599119a368ca93"]]},{"id":"b1c72c679e24cf25","type":"function","z":"f0ac6e667fc173d9","name":"selectRow","func":"\nmsg.payload={\n    command:\"selectRow\",\n    returnPromise: true\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":310,"y":380,"wires":[["658e66209e05b0f5"]],"info":"# deleteRow(row / [rows])\n\n`row=singleId`\n\nor\n\n`row=[array of IDs]` // seems there is a bug/issue in tabulator\n\ndelete a single the row with an id in the middle from 1 to lastId, hope it exists.\n\nWill fail on the second hit if you inject this two times because the id wad deleteted on the first"},{"id":"d592b6fcd9261596","type":"debug","z":"f0ac6e667fc173d9","name":"Table Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":970,"y":320,"wires":[]},{"id":"e126649fe405fa5a","type":"ui_button","z":"f0ac6e667fc173d9","name":"","group":"2768d5bb10e62e93","order":0,"width":"4","height":"1","passthru":false,"label":"Select All","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"","payloadType":"str","topic":"topic","topicType":"msg","x":140,"y":380,"wires":[["b1c72c679e24cf25"]]},{"id":"1cbd77873713897d","type":"ui_button","z":"f0ac6e667fc173d9","name":"","group":"2768d5bb10e62e93","order":2,"width":"4","height":"1","passthru":false,"label":"Initialize Table","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"","payloadType":"str","topic":"topic","topicType":"msg","x":120,"y":320,"wires":[["ce4c5218fe191a89"]]},{"id":"1bcfd549a54054a3","type":"inject","z":"f0ac6e667fc173d9","name":"Initialize","props":[{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"test","x":110,"y":220,"wires":[["158a744767d3cef1"]]},{"id":"d52f7df509f4be7c","type":"split","z":"f0ac6e667fc173d9","name":"","splt":"\\n","spltType":"str","arraySplt":"1","arraySpltType":"len","stream":true,"addname":"key","x":650,"y":220,"wires":[["3063682c39c766b6"]]},{"id":"3063682c39c766b6","type":"function","z":"f0ac6e667fc173d9","name":"","func":"var data=msg.payload;\nvar temp=data.split(\"->\");\nmsg.file_size=temp[0];\nmsg.file_name=temp[1];\n\nreturn msg;\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":840,"y":220,"wires":[["880fd5864a1a3142"]]},{"id":"880fd5864a1a3142","type":"function","z":"f0ac6e667fc173d9","name":"updateOrAddData (add)","func":"let fileList = flow.get(\"fileList\") || [];\nlet pay = {};\n\nvar check=msg.file_size;\nif(check===\"\"){\n    return null;   \n}\nelse {\n    var id=flow.get(\"lastId\") || 0;\n    ++id;\n    pay = {\n            \"id\":id,\n            \"filesize\":msg.file_size,\n            \"filename\":msg.file_name\n          }\n    fileList.push(pay);\n    flow.set(\"lastId\",id);\n    \n       \n}\n\nflow.set(\"fileList\" , fileList);\nreturn msg; ","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1050,"y":220,"wires":[[]],"info":"# updateOrAddData([row])\n\nadds a the row with a new id (same as addRow)"},{"id":"50fc5c2cd4c1d21f","type":"template","z":"f0ac6e667fc173d9","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"->\n238K->flows_pi.json\n5.9K->flows_pi_cred.json\n4.0K->lib\n12K->node_modules\n568->package.json\n98K->package-lock.json\n140K->pic.jpg\n158K->pic-1.jpg\n169K->pic-2.jpg\n155K->pic-3.jpg\n14K->settings.js\n","output":"str","x":500,"y":220,"wires":[["d52f7df509f4be7c"]]},{"id":"158a744767d3cef1","type":"change","z":"f0ac6e667fc173d9","name":"Restart flow context","rules":[{"t":"set","p":"fileList","pt":"flow","to":"[]","tot":"json"},{"t":"set","p":"lastId","pt":"flow","to":"0","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":290,"y":220,"wires":[["50fc5c2cd4c1d21f"]]},{"id":"ce4c5218fe191a89","type":"change","z":"f0ac6e667fc173d9","name":"Load list from context","rules":[{"t":"set","p":"payload","pt":"msg","to":"fileList","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":320,"y":320,"wires":[["658e66209e05b0f5"]]},{"id":"7bb15ba4a1d31594","type":"change","z":"f0ac6e667fc173d9","name":"","rules":[{"t":"set","p":"newFileList","pt":"flow","to":"ui_control.rowSelection","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":950,"y":400,"wires":[[]]},{"id":"d33380c182d936f2","type":"ui_button","z":"f0ac6e667fc173d9","name":"","group":"2768d5bb10e62e93","order":0,"width":"4","height":"1","passthru":false,"label":"Update Table","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"","payloadType":"str","topic":"topic","topicType":"msg","x":130,"y":440,"wires":[["53f67a6c1d8d427b"]]},{"id":"53f67a6c1d8d427b","type":"change","z":"f0ac6e667fc173d9","name":"Load new File list from context","rules":[{"t":"set","p":"payload","pt":"msg","to":"newFileList","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":370,"y":440,"wires":[["658e66209e05b0f5"]]},{"id":"960b6ba012d7ced2","type":"ui_spacer","z":"f0ac6e667fc173d9","name":"spacer","group":"2768d5bb10e62e93","order":1,"width":6,"height":1},{"id":"0a70b37758bc78b8","type":"ui_spacer","z":"f0ac6e667fc173d9","name":"spacer","group":"2768d5bb10e62e93","order":2,"width":6,"height":1},{"id":"870a91418c5861d1","type":"ui_group","name":"List of files in directory","tab":"94ff3c5caa315fa9","order":2,"disp":true,"width":"10","collapse":false,"className":""},{"id":"2768d5bb10e62e93","type":"ui_group","name":"Group 1","tab":"94ff3c5caa315fa9","order":1,"disp":false,"width":6,"collapse":false,"className":""},{"id":"94ff3c5caa315fa9","type":"ui_tab","name":"Download","icon":"fa-cloud-download fa-2x","order":4,"disabled":false,"hidden":false}]
1 Like

Thanks @Andrei, at great cost yesterday I managed to get your version working in my flow.
With these latest improvements it got even better, great work and help.
Your idea for the "update table" button, as I realized when testing, is to show only the files that were selected in the table, right?

I tested another question that gives me a lot of help in this specific case, which is, I'll have a flow like this one but listing files from another directory, otherwise everything remains the same. The point is that, logically, the files will be listed in the same table as it wouldn't make sense to have two tables. I've already managed this part, but I have 2 buttons to initialize the table with data from one or another directory. What happens is that when I'm looking at the files in one directory and I want to list the files in the other, I only get the second click on the initialize button (I understand that the first click resets the array and the second responds to the listing and puts in the table, but don't know if it's true). The ideal would be to click on the button to show the directory in question right away in the table.
Any suggestions on how to do this?

Thanks again for your help and sharing knowledge.