UI Tabular Table Sorting

Ok. What does your code look like so far? Send me what you have and I'll see if I can identify what's going on.

Hi, this is the tabulator template - thanks!


<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/luxon@3.0.4/build/global/luxon.min.js"></script>
<div id="screener"></div>
<script>
    //Copy/paste Tabulator examples directly from the web page here.
    //You will need example data to use them directly.
    //Otherwise copy the examples and alter to your needs.
    //Most of the following is directly from the quickstart page.
    
    var tabledata = [
   	{id:1, name:"Oli Bob", age:"12", col:"red", dob:""}
  //  	{id:2, name:"Mary May", age:"1", col:"blue", dob:"14/05/1982"},
 //   	{id:3, name:"Christine Lobowski", age:"42", col:"green", dob:"22/05/1982"},
 //   	{id:4, name:"Brendon Philips", age:"125", col:"orange", dob:"01/08/1980"},
//    	{id:5, name:"Margret Marmajuke", age:"16", col:"yellow", dob:"31/01/1999"},
    ];
    
    var table = new Tabulator("#screener", {
     	height:900, 
     	textSize : 10,
     	data:tabledata, //assign data to table
     	layout:"fitColumns", //fit columns to width of table (optional)
     	columns:[ //Define Table Columns
    	 	{title:"I", field:"flag", width:"1%"},
    	 	{title:"Coin", field:"currency", hozAlign:"center", width:60},
    	 	{title:"Exchange", field:"exchange", hozAlign:"center", width:70},
    	 	{title:"UP", field:"percent", hozAlign:"center", width:50,
    	 	 formatter: function(cell, formatterParams){var value = cell.getValue(); if(value == null) {return ""}; if (value !== null) {if(value >= 0){cell.getElement().style.color ='#609f70'} else {cell.getElement().style.color ='#ff4a68'} return value +'%';}}    
    	 	},
     	 	{title:"W", field:"window", hozAlign:"center", width:"20"	 	    
    	 	},
    	 	{title:"24Hr", field:"change", hozAlign:"center", width:60, formatterParams:{precision:0},
             formatter: function(cell, formatterParams){var value = cell.getValue(); if(value == null) {return ""}; if (value !== null) {if(value >= 0){cell.getElement().style.color ='#609f70'} else {cell.getElement().style.color ='#ff4a68'} return value +'%';}}	    
    	 	},
    	 	{title:"B", field:"b_coin", hozAlign:"center", width:20, formatter:function(cell, formatterParams, onRendered) {var value = cell.getValue(); if(value == null) {return ""}; return "<span style='color:#2962ff; font-weight:bold;'>" + cell.getValue() + "</span>";}},  
    	 	{title:"F", field:"f_coin", hozAlign:"center", width:20},
    	 	{title:"G", field:"g_coin", hozAlign:"center", width:20},
    	 	{title:"Volume", field:"volume", hozAlign:"right", width:100,formatter:"money", formatterParams:{thousand:",", precision:0}},
    	 	{title:"Price", field:"price", hozAlign:"right", width:70, formatter:"money", formatterParams:{thousand:","}},
    	 	{title:"Time", field:"time", hozAlign:"center", width:100}
     	],
    });
    
    table.on("rowClick", function(e, row){ 
    //	alert("Row " + row.getData().id + " Clicked!!!!");
    
 
         
    });
    
    //This is needed to interact with Node-Red when a message is sent to the ui-template.
    (function(scope){
        scope.$watch('msg', function(msg){
            if(msg){
                table.addData([msg.payload], true); //Your new reaction code
            }
        });
    })(scope);
</script>

Just FYI, I haven't forgotten about this. Just haven't been near my setup this weekend...

Ok. Let's see what we can do to resolve some of these issues.

I'm still figuring it out too. I moved the script to the actual header node to see if that helps.

I'll use one of your column definitions to show you how to insert it.

{
    title:"Price", 
    field:"price", 
    hozAlign:"right", 
    width:70, 
    formatter:"money", 
    formatterParams:{
        thousand:",", 
        emptyValue:0
    }
},

Notice how the key was placed into the formatterParams block? Now whenever you have a cell in that column without a value, it should default to the value of 0 with the money format applied. This may take some experimenting to make sure it applies correctly, but that is where you'll put it. I'm not sure what column(s) you wanted this applied to, so I left it out of my example below.

Try this:

[{"id":"bad2753563239ae2","type":"ui_template","z":"1025dd9ca4a4b52a","group":"17d1928558cb8a7a","name":"Table","order":3,"width":0,"height":0,"format":"<div id=\"screener\"></div>\n<script>\n    var table = new Tabulator(\"#screener\", {\n     \theight:900, \n     \ttextSize : 10,\n     \t//data:tabledata, //assign data to table\n     \t//layout:\"fitColumns\", //fit columns to width of table (optional)\n     \tcolumns:[\n    \t \t{title:\"I\", field:\"flag\", width:\"1%\"},\n    \t \t{title:\"Coin\", field:\"currency\", hozAlign:\"center\", width:60},\n    \t \t{title:\"Exchange\", field:\"exchange\", hozAlign:\"center\", width:70},\n    \t \t{title:\"UP\", field:\"percent\", hozAlign:\"center\", width:50,\n    \t \t formatter: function(cell, formatterParams){var value = cell.getValue(); if(value == null) {return \"\"}; if (value !== null) {if(value >= 0){cell.getElement().style.color ='#609f70'} else {cell.getElement().style.color ='#ff4a68'} return value +'%';}}    \n    \t \t},\n     \t \t{title:\"W\", field:\"window\", hozAlign:\"center\", width:\"20\"\t \t    \n    \t \t},\n    \t \t{title:\"24Hr\", field:\"change\", hozAlign:\"center\", width:60, formatterParams:{precision:0},\n             formatter: function(cell, formatterParams){var value = cell.getValue(); if(value == null) {return \"\"}; if (value !== null) {if(value >= 0){cell.getElement().style.color ='#609f70'} else {cell.getElement().style.color ='#ff4a68'} return value +'%';}}\t    \n    \t \t},\n    \t \t{title:\"B\", field:\"b_coin\", hozAlign:\"center\", width:20, formatter:function(cell, formatterParams, onRendered) {var value = cell.getValue(); if(value == null) {return \"\"}; return \"<span style='color:#2962ff; font-weight:bold;'>\" + cell.getValue() + \"</span>\";}},  \n    \t \t{title:\"F\", field:\"f_coin\", hozAlign:\"center\", width:20},\n    \t \t{title:\"G\", field:\"g_coin\", hozAlign:\"center\", width:20},\n    \t \t{title:\"Volume\", field:\"volume\", hozAlign:\"right\", width:100,formatter:\"money\", formatterParams:{thousand:\",\", precision:0}},\n    \t \t{title:\"Price\", field:\"price\", hozAlign:\"right\", width:70, formatter:\"money\", formatterParams:{thousand:\",\"}},\n    \t \t{title:\"Time\", field:\"time\", hozAlign:\"center\", width:100}\n     \t],\n    });\n    \n    table.on(\"rowClick\", function(e, row){ \n    \tvar fetchOptions = {\n      \t    method:'POST',\n            headers:{'Content-Type':'application/json'},\n            body:JSON.stringify(table.getData())\n        };\n        fetch(\"http://localhost:1880/table-out\", fetchOptions) //Change address here\n            .catch(function(error){alert(error)});\n    });\n    \n    (function(scope){\n        scope.$watch('msg', function(msg){\n            if(msg){\n                table.addData([msg.payload], true); //Your new reaction code\n            }\n        });\n    })(scope);\n</script>","storeOutMessages":true,"fwdInMessages":false,"resendOnRefresh":true,"templateScope":"local","className":"","x":90,"y":80,"wires":[[]]},{"id":"2a9f97487235e84d","type":"ui_template","z":"1025dd9ca4a4b52a","group":"17d1928558cb8a7a","name":"Header","order":1,"width":0,"height":0,"format":"<link href=\"https://unpkg.com/tabulator-tables/dist/css/tabulator_midnight.min.css\" rel=\"stylesheet\">\n<script type=\"text/javascript\" src=\"https://unpkg.com/tabulator-tables/dist/js/tabulator.min.js\"></script>\n<script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/npm/luxon@3.0.4/build/global/luxon.min.js\"></script>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"global","className":"","x":100,"y":40,"wires":[[]]},{"id":"0ef76278da785471","type":"http in","z":"1025dd9ca4a4b52a","name":"","url":"/table-out","method":"post","upload":false,"swaggerDoc":"","x":120,"y":120,"wires":[["d003660184858a35","18728867284187d1"]]},{"id":"d003660184858a35","type":"http response","z":"1025dd9ca4a4b52a","name":"","statusCode":"","headers":{},"x":290,"y":100,"wires":[]},{"id":"18728867284187d1","type":"function","z":"1025dd9ca4a4b52a","name":"Something","func":"//Something needs to be done here with the table output.\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":310,"y":140,"wires":[[]]},{"id":"17d1928558cb8a7a","type":"ui_group","name":"Home","tab":"462af20a79c1cd63","order":2,"disp":true,"width":"6","collapse":false,"className":""},{"id":"462af20a79c1cd63","type":"ui_tab","name":"Home","icon":"dashboard","order":3,"disabled":true,"hidden":false}]

I can't guarantee it will work because I don't have anything outside of what you provided me. You'll notice I added a bit to the rowClicked event. Pretty much all of it applies to the fetch() function in Javascript. This will POST data out to the HTTP node I added. You'll need to alter the connection address in the fetch() function if it is not running on the same system you're using to build your flow. It should be the same root address as you use to access Node-Red editor (i.e. http://192.168.0.1:1880 or http://some.url.or.ip:1880). The output of the HTTP POST node goes into two other nodes. The HTTP response node is required so the calling client gets a response and doesn't go into timeout. The function node attached is where you'll do whatever with the data you sent out. This can be replaced with any node and is only a representative of where to put it.

Let me know if/where you get stuck on things.

First, thank you so much for all of your help. I greatly appreciate it.

Got the row click working! Got stuck on something simple (thought I knew enough by now to handle it). Need to convert the incoming array into simple object with two variables. Been trying change-node with jsonata but no luck.

INCOMING:

Screenshot 2022-10-31 223645

NEED:

Screenshot 2022-10-31 223744

And finally :slight_smile: - I now have to convert a different table (which was interfering with the new tabulator script).

This one is different (and confusing) because it's a two-dimensional configuration. Don't recall how I managed to get it working; it's a messy tabulator template + change-node control + UI table set up:

[
    {
        "id": "ad5dc98ff448c34b",
        "type": "tab",
        "label": "Flow 2",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "22b8b61327c34cbd",
        "type": "function",
        "z": "ad5dc98ff448c34b",
        "name": "",
        "func": "msgAcct = {}; \n\n\nvar binance = Number(msg.payload.all[1].usd_amount);\nvar binance_dc = (Number(msg.payload.all[1].day_profit_usd_percentage)).toFixed(2);\nvar ftxtrade = Number(msg.payload.all[5].usd_amount);\nvar ftxtrade_dc = (Number(msg.payload.all[5].day_profit_usd_percentage)).toFixed(2);\nvar gate = Number(msg.payload.all[7].usd_amount);\nvar gate_dc = (Number(msg.payload.all[7].day_profit_usd_percentage)).toFixed(2);\nvar total = (binance+ftxtrade+gate);\nvar trades_b = msg.payload.b.data.active_smart_trades_count;\nvar trades_ft = msg.payload.ft.data.active_smart_trades_count;\nvar trades_g = msg.payload.g.data.active_smart_trades_count;\nvar bots_b = msg.payload.b.data.active_bots_count;\nvar bots_ft = msg.payload.ft.data.active_bots_count;\nvar bots_g = msg.payload.g.data.active_bots_count;\n\n\n\n\nmsgAcct.payload = [\n    {\n        \"#\": \"BALANCE\",\n        \"Binance\": \"$ \"+binance.toFixed(0),\n        \"FTX\":\"$ \"+ftxtrade.toFixed(0),\n        \"Gate\": \"$ \"+gate.toFixed(0),\n        \"TOTAL\": \"$ \"+total.toFixed(0)\n        \n    },\n    {\n        \"#\": \"24HR\",\n        \"Binance\": binance_dc+\" %\",\n        \"FTX\": ftxtrade_dc+\" %\",\n        \"Gate\":  gate_dc+\" %\",\n        \"TOTAL\": \" \"\n    },    \n    {\n        \"#\": \"Trades\",\n        \"Binance\": trades_b,\n        \"FTX\":  trades_ft,\n        \"Gate\":  trades_g,\n        \"TOTAL\": \" \"\n    },\n    {\n        \"#\": \"Bots\",\n        \"Binance\": bots_b,\n        \"FTX\":  bots_ft,\n        \"Gate\":  bots_g,\n        \"TOTAL\": \" \"\n    },\n    {\n        \"#\": \"ROI\",\n        \"Binance\": (((binance - 1015)/1015)*100).toFixed(2)+\" %\",\n        \"FTX\": (((ftxtrade - 1001)/1001)*100).toFixed(2)+\" %\",\n        \"Gate\":  (((gate - 1091)/1091)*100).toFixed(2)+\" %\",\n        \"TOTAL\": (((total - 3107)/3107)*100).toFixed(2)+\" %\"\n    }\n]\n\n\nreturn msgAcct \n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 530,
        "y": 280,
        "wires": [
            [
                "4ad9cf92df23c5f6",
                "bfba3a5e490de3e9",
                "54a9c0181842889d"
            ]
        ]
    },
    {
        "id": "4ad9cf92df23c5f6",
        "type": "change",
        "z": "ad5dc98ff448c34b",
        "name": "clear",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "[]",
                "tot": "json"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 690,
        "y": 260,
        "wires": [
            [
                "779f58aca95b2ad5"
            ]
        ]
    },
    {
        "id": "c0ca38e45e67db11",
        "type": "change",
        "z": "ad5dc98ff448c34b",
        "name": "ui_control",
        "rules": [
            {
                "t": "set",
                "p": "ui_control",
                "pt": "msg",
                "to": "{\"tabulator\":{\"columns\":[{\"title\":\"#\",\"field\":\"#\",\"align\":\"left\",\"frozen\":true},{\"title\":\"Binance\",\"field\":\"Binance\",\"align\":\"center\"},{\"title\":\"FTX Bots\",\"field\":\"FTX Bots\",\"align\":\"center\"},{\"title\":\"FTX Trade\",\"field\":\"FTX Trade\",\"align\":\"center\"},{\"title\":\"Gate\",\"field\":\"Gate\",\"align\":\"center\"},{\"title\":\"TOTAL\",\"field\":\"TOTAL\",\"align\":\"center\"}],\"item\":\"\",\"layout\":\"fitColumns\",\"movableColumns\":false,\"groupBy\":\"\"}}",
                "tot": "json"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 860,
        "y": 260,
        "wires": [
            [
                "779f58aca95b2ad5"
            ]
        ]
    },
    {
        "id": "779f58aca95b2ad5",
        "type": "ui_table",
        "z": "ad5dc98ff448c34b",
        "group": "a5ba0b01d5e9a353",
        "name": "ACCOUINT",
        "order": 3,
        "width": 6,
        "height": 5,
        "columns": [],
        "outputs": 1,
        "cts": true,
        "x": 1060,
        "y": 260,
        "wires": [
            []
        ]
    },
    {
        "id": "54a9c0181842889d",
        "type": "ui_template",
        "z": "ad5dc98ff448c34b",
        "group": "a5ba0b01d5e9a353",
        "name": "ACCT",
        "order": 2,
        "width": "6",
        "height": "5",
        "format": "\n<div id=\"screener\"></div>\n<script>\n    //Copy/paste Tabulator examples directly from the web page here.\n    //You will need example data to use them directly.\n    //Otherwise copy the examples and alter to your needs.\n    //Most of the following is directly from the quickstart page.\n    \n    var tabledata = [\n//   \t{id:1, name:\"Oli Bob\", age:\"12\", col:\"red\", dob:\"\"}\n  //  \t{id:2, name:\"Mary May\", age:\"1\", col:\"blue\", dob:\"14/05/1982\"},\n //   \t{id:3, name:\"Christine Lobowski\", age:\"42\", col:\"green\", dob:\"22/05/1982\"},\n //   \t{id:4, name:\"Brendon Philips\", age:\"125\", col:\"orange\", dob:\"01/08/1980\"},\n//    \t{id:5, name:\"Margret Marmajuke\", age:\"16\", col:\"yellow\", dob:\"31/01/1999\"},\n    ];\n    \n    var table = new Tabulator(\"#screener\", {\n     \theight:800, \n     \ttextSize : 10,\n     \tdata:tabledata, //assign data to table\n     \tlayout:\"fitColumns\", //fit columns to width of table (optional)\n     \tcolumns:[ //Define Table Columns\n    \t \t{title:\" \", field:\"#\", hozAlign:\"left\" width:20},\n    \t \t{title:\"Binance\", field:\"Binance\", hozAlign:\"center\", width:55},\n    \t \t{title:\"Bots\", field:\"Bots\", hozAlign:\"center\", width:70}\n     \t],\n    });\n    \n    table.on(\"rowClick\", function(e, row){ \n    \talert(\"Row \" + row.getData().id + \" Clicked!!!!\");\n    });\n    \n    //This is needed to interact with Node-Red when a message is sent to the ui-template.\n    (function(scope){\n        scope.$watch('msg', function(msg){\n            if(msg){\n                table.addData([msg.payload], true); //Your new reaction code\n            }\n        });\n    })(scope);\n</script>",
        "storeOutMessages": true,
        "fwdInMessages": true,
        "resendOnRefresh": true,
        "templateScope": "local",
        "className": "",
        "x": 630,
        "y": 360,
        "wires": [
            []
        ]
    },
    {
        "id": "bfba3a5e490de3e9",
        "type": "delay",
        "z": "ad5dc98ff448c34b",
        "name": "",
        "pauseType": "delay",
        "timeout": "1",
        "timeoutUnits": "milliseconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "x": 780,
        "y": 320,
        "wires": [
            [
                "779f58aca95b2ad5"
            ]
        ]
    },
    {
        "id": "a5ba0b01d5e9a353",
        "type": "ui_group",
        "name": "MIDDLE",
        "tab": "7e13e6107768d821",
        "order": 4,
        "disp": false,
        "width": "5",
        "collapse": false,
        "className": ""
    },
    {
        "id": "7e13e6107768d821",
        "type": "ui_tab",
        "name": "CRYPTO",
        "icon": "dashboard",
        "order": 2,
        "disabled": false,
        "hidden": false
    }
]

// Get array element as an object
const data = msg.payload[0]

// Save incoming object without property 'window'. Note there are many ways to do this
// example: delete data.window; msg.payload = data
msg.payload = {currency: data.currrency, exchange: data.exchange}

return msg

Thanks, is this getting specified in the change node? Still confused.

var temp = msg.payload[0];
delete temp.window;
msg.payload = temp;

This is getting handled wherever you're receiving the message. If the message is coming into a function, you'll add one of the code snippets either Buckskin or I have given you. A change node wouldn't be as easy to implement with something where you're trying to convert an array object into a singular object. I would suggest if you're trying to use a change node to instead use a function node with one of the two implementations. If there's already a function node there, just add one of the code sections into it where it fits best.

Based on the flow you have, this should be the equivalent table setup. Keep in mind, I didn't do anything with the rowClicked event because I didn't know what was supposed to happen. But you should be able to look at your other table and get the idea you need on how to handle that.

[{"id":"22b8b61327c34cbd","type":"function","z":"ad5dc98ff448c34b","name":"","func":"msgAcct = {}; \n\n\nvar binance = Number(msg.payload.all[1].usd_amount);\nvar binance_dc = (Number(msg.payload.all[1].day_profit_usd_percentage)).toFixed(2);\nvar ftxtrade = Number(msg.payload.all[5].usd_amount);\nvar ftxtrade_dc = (Number(msg.payload.all[5].day_profit_usd_percentage)).toFixed(2);\nvar gate = Number(msg.payload.all[7].usd_amount);\nvar gate_dc = (Number(msg.payload.all[7].day_profit_usd_percentage)).toFixed(2);\nvar total = (binance+ftxtrade+gate);\nvar trades_b = msg.payload.b.data.active_smart_trades_count;\nvar trades_ft = msg.payload.ft.data.active_smart_trades_count;\nvar trades_g = msg.payload.g.data.active_smart_trades_count;\nvar bots_b = msg.payload.b.data.active_bots_count;\nvar bots_ft = msg.payload.ft.data.active_bots_count;\nvar bots_g = msg.payload.g.data.active_bots_count;\n\n\n\n\nmsgAcct.payload = [\n    {\n        \"Number\": \"BALANCE\",\n        \"Binance\": \"$ \"+binance.toFixed(0),\n        \"FTX\":\"$ \"+ftxtrade.toFixed(0),\n        \"Gate\": \"$ \"+gate.toFixed(0),\n        \"TOTAL\": \"$ \"+total.toFixed(0)\n        \n    },\n    {\n        \"Number\": \"24HR\",\n        \"Binance\": binance_dc+\" %\",\n        \"FTX\": ftxtrade_dc+\" %\",\n        \"Gate\":  gate_dc+\" %\",\n        \"TOTAL\": \" \"\n    },    \n    {\n        \"Number\": \"Trades\",\n        \"Binance\": trades_b,\n        \"FTX\":  trades_ft,\n        \"Gate\":  trades_g,\n        \"TOTAL\": \" \"\n    },\n    {\n        \"Number\": \"Bots\",\n        \"Binance\": bots_b,\n        \"FTX\":  bots_ft,\n        \"Gate\":  bots_g,\n        \"TOTAL\": \" \"\n    },\n    {\n        \"Number\": \"ROI\",\n        \"Binance\": (((binance - 1015)/1015)*100).toFixed(2)+\" %\",\n        \"FTX\": (((ftxtrade - 1001)/1001)*100).toFixed(2)+\" %\",\n        \"Gate\":  (((gate - 1091)/1091)*100).toFixed(2)+\" %\",\n        \"TOTAL\": (((total - 3107)/3107)*100).toFixed(2)+\" %\"\n    }\n]\n\n\nreturn msgAcct \n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":120,"y":100,"wires":[["54a9c0181842889d"]]},{"id":"54a9c0181842889d","type":"ui_template","z":"ad5dc98ff448c34b","group":"a5ba0b01d5e9a353","name":"ACCT","order":2,"width":"6","height":"5","format":"\n<div id=\"screener2\"></div>\n<script>\n    var table = new Tabulator(\"#screener2\", {\n     \theight:800, \n     \ttextSize : 10,\n     \tlayout:\"fitColumns\",\n     \tcolumns:[\n    \t\t{title:\"Number\",field:\"Number\",hozAlign:\"left\",frozen:true},\n    \t\t{title:\"Binance\",field:\"Binance\",hozAlign:\"center\"},\n    \t\t{title:\"FTX Bots\",field:\"FTX Bots\",hozAlign:\"center\"},\n    \t\t{title:\"FTX Trade\",field:\"FTX Trade\",hozAlign:\"center\"},\n    \t\t{title:\"Gate\",field:\"Gate\",hozAlign:\"center\"},\n    \t\t{title:\"TOTAL\",field:\"TOTAL\",hozAlign:\"center\"}\n    \t]\n    });\n    \n    table.on(\"rowClick\", function(e, row){ \n    \talert(\"Row \" + row.getData().id + \" Clicked!!!!\");\n    });\n    \n    (function(scope){\n        scope.$watch('msg', function(msg){\n            if(msg){\n                table.addData([msg.payload], true);\n            }\n        });\n    })(scope);\n</script>","storeOutMessages":true,"fwdInMessages":false,"resendOnRefresh":true,"templateScope":"local","className":"","x":250,"y":100,"wires":[[]]},{"id":"a5ba0b01d5e9a353","type":"ui_group","name":"MIDDLE","tab":"7e13e6107768d821","order":4,"disp":false,"width":"6","collapse":false,"className":""},{"id":"7e13e6107768d821","type":"ui_tab","name":"CRYPTO","icon":"dashboard","order":2,"disabled":false,"hidden":false}]

One other thing I noticed that may or may not have contributed to issues, you had a key labeled "#" in your code that was also used as a field. Most programming languages don't like symbols used as variables or keys. Some can handle it, but other can't. So to keep from having issues, I simply renamed the key and column to "Number". You can change it to whatever is more applicable to your situation.

A change node would also work;

image

Hi, I was able to get your example working in an empty function (prefer not to have an extra just with two lines of code). Can those two values be simply referenced inside the function as data.currency and data.exchange - I just need to save them as flow variables.

The function that is meant to receive this input is as follows (I put in your code but it's throwing error in combination with what's there). Note that it already has currency/exchange variables specified since they can also come from another source.

// ONE INPUT
var currency =  msg.payload.currency;
var exchange  = msg.payload.exchange;

// THIS INPUT
// var data = msg.payload[0]

// Save incoming object without property 'window'. Note there are many ways to do this
// example: delete data.window; msg.payload = data
// msg.payload = {volume: data.currency, exchange: data.exchange}

//SAVING AS FLOW (THEY NEVER ARRIVE AT THE SAME TIME)

flow.set('currency', currency)
flow.set('exchange', exchange)



The change note outputs: "payload[0].currency"

I want to change it to "payload.currency" before it comes in to the function.

I swapped in your code, but the table is not getting generated. Also noticed that manual timestamp inject into this table creates a blank row in the other one (first one we dealt with.

Yes. But because msg.payload is an array, you're going to need to reference the array position to assign individual variables.

var currency =  msg.payload[0].currency;
var exchange  = msg.payload[0].exchange;

Having conflicting variables can be concerning as the possibility for unintended bugs goes up when you can have variable conflicts. Where else are these variables specified and how can they get data from another source?

There's no data for the table to generate initially, so nothing will show up until things start to populate. The function node needs an input in order to create the msgAcct to send out to the table to populate the data. I didn't have the node that fed the function so I couldn't simulate what came in to create an output and test the table.

You'll need to rename the table(s) so that they don't match. The ui-template node works in such a way that one template node can reference stuff in the other template node and vice versa. If you don't keep things unique in the nodes, you're going to run into conflicts. The same goes for the functions defined in each template node. When you have something like

table.on("rowClick", function(e, row){ 
	alert("Row " + row.getData().id + " Clicked!!!!");
});

The function conflicts with the other template node and causes issues. You're going to want to rename your table and your functions.

 var table = new Tabulator("#screener2", {

Becomes...

 var someNewTableName = new Tabulator("#screener2", {

And the function becomes:

someNewTableName.on("rowClick", function(e, row){ 

Make sense?

The function is receiving the currency/exchange values from independent sources (webhook, table row-click, another) - its spread apart in time by hours. This configuration actually works perfectly, I am just having a problem with the new table row-click since its data that structured differently and I want to transform it prior to getting it into the function

Have you set it up as shown, because there is no way that it outputs msg.payload[0] if the input is as given?

[{currency: "GALA", exchange: "FTX", window: ""}]

Yes. You'll just need to rename things in both template nodes so that each template node is unique. That should separate the responses and make the interactions with each work as expected. There will be some housekeeping like this you'll have to do since we don't have your whole flow this is working off of. But it's simple housekeeping and should be done quick and easily.

I just realized I kept using "the function" or something similar in my response. I should be saying "the event" since that is what you have for your rowClicked setup. When you rename your tables, you'll need to use that new name to setup the events that correspond to them (tableName.on or tableName.off). That's what will make things work independently and fix most of your issues you're having with the tables.

There are no interactions on the 2nd table. At this point it's not even loading. You think it's causing by duplicate naming?