# Ui-table supports ui\_control

**URL:** https://discourse.nodered.org/t/ui-table-supports-ui-control/18870
**Category:** Dashboard
**Created:** [6 December 2019 16:05 UTC](https://discourse.nodered.org/t/ui-table-supports-ui-control/18870 "2019-12-06T16:05:57Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![Christian-Me](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/christian-me/32/10774_2.png) [@Christian-Me](https://discourse.nodered.org/u/Christian-Me)
#### Post date: [6 December 2019 16:05 UTC](https://discourse.nodered.org/t/ui-table-supports-ui-control/18870/1 "2019-12-06T16:05:57Z")

</div>

Hello all,  
ui-table supports now sending `msg.ui_control` messages to have more possibilities to style your dashboard table:

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/b/b73b8d80cedd6937121979590f22514d170658c1.png)  
or with grouping  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/a/a9607db628814e58a1bc0eca04056868b0985311.png)  
Example flow included but many other things should be possible. This Example is "generated" by data collected by my home automation system thermostat giving a compact overview of all values and settings with only one ui-node.  

> **[node-red-node-ui-table](https://flows.nodered.org/node/node-red-node-ui-table)**
>
> Table UI widget node for Node-RED Dashboard

  
Curious to see what you can do with it. Comments always welcome.  
Chris

---

<div class="post-metadata">

### Author: ![jodelkoenig](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/jodelkoenig/32/44645_2.png) [@jodelkoenig](https://discourse.nodered.org/u/jodelkoenig)
#### Post date: [31 December 2019 17:18 UTC](https://discourse.nodered.org/t/ui-table-supports-ui-control/18870/2 "2019-12-31T17:18:18Z")

</div>

Looks really great, Christian.

Would I be able to define the general color scheme of the table via msg.ui\_control? I would like to customize in particular background colors for the first row/header row as well as the alternating colors for odd/even rows. In line with my dashboard theme.

Happy New Year to all 😉

---

<div class="post-metadata">

### Author: ![Christian-Me](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/christian-me/32/10774_2.png) [@Christian-Me](https://discourse.nodered.org/u/Christian-Me)
#### Post date: [31 December 2019 18:40 UTC](https://discourse.nodered.org/t/ui-table-supports-ui-control/18870/3 "2019-12-31T18:40:56Z")

</div>

Hmm, in principle you should be able to do “everything” you can do with tabulator during initialization, either static or dynamic via callback functions. Perhaps take a look in the real comprehensive docs of tabulator first.  
I’m not the css guy but it sounds like a custom css would be the right way to skin the table in general . As I’m happy with the midnight theme I did not focused on that problem but as far as I know there should be several other themes available for tabulator (perhaps not included in the ui-table note but that can be took into consideration).  
I’m working currently on a PR to pass commands to an existing tabulator instance to add / delete or change existing data (and do other things) without replacing the data completely.  
Happy new year too!

---

<div class="post-metadata">

### Author: ![jodelkoenig](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/jodelkoenig/32/44645_2.png) [@jodelkoenig](https://discourse.nodered.org/u/jodelkoenig)
#### Post date: [3 January 2020 10:33 UTC](https://discourse.nodered.org/t/ui-table-supports-ui-control/18870/4 "2020-01-03T10:33:36Z")

</div>

🙂 ... CSS did the trick for me. I now do have a ui-template node, assigned to my ui-tables Group and I can customize the table so that is fits into the overall look and feel.

For reference if anybody wants to do something similar:

```auto
[{"id":"eca62c1a.40bdf8","type":"ui_template","z":"113a5c80.015354","group":"c4aa95f6.0a88","name":"CSS: ui-table","order":1,"width":0,"height":0,"format":"<style>\n\n .tabulator{padding-left:2px;border:1px solid #000;background-color:#202529;font-size:17px}\n \n .tabulator .tabulator-header{border-bottom:0px solid #000;background-color:#202529}\n .tabulator-col-content{background-color:#202529;height:37px}\n\n .tabulator-row{min-height:31px;background-color:#181c1f}\n .tabulator-row:nth-child(2n){background-color:#202529}\n\n .tabulator-row .tabulator-cell{border-right:0px solid #888}\n .tabulator .tabulator-header .tabulator-col{border-right:0px solid #aaa}\n\n</style>","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":1290,"y":2970,"wires":[[]]},{"id":"c4aa95f6.0a88","type":"ui_group","z":"","name":"Default","tab":"b06ddd9b.614eb8","order":1,"disp":false,"width":"24","collapse":false},{"id":"b06ddd9b.614eb8","type":"ui_tab","z":"","name":"Home","icon":"dashboard"}]

```

Note: this one includes only those parameter I wanted to change; a lot more can be found in _./node\_modules/node-red-node-ui-table/lib/css/tabulator??????...?????.css_

Check out for more information here: [Examples for node-red-node-ui-table](https://discourse.nodered.org/t/examples-for-node-red-node-ui-table/14256/58)

---

<div class="post-metadata">

### Author: ![catanto](https://avatars.discourse-cdn.com/v4/letter/c/34f0e0/32.png) [@catanto](https://discourse.nodered.org/u/catanto)
#### Post date: [20 January 2020 09:39 UTC](https://discourse.nodered.org/t/ui-table-supports-ui-control/18870/5 "2020-01-20T09:39:26Z")

</div>

Can you post your flow?

---

<div class="post-metadata">

### Author: ![Christian-Me](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/christian-me/32/10774_2.png) [@Christian-Me](https://discourse.nodered.org/u/Christian-Me)
#### Post date: [20 January 2020 11:16 UTC](https://discourse.nodered.org/t/ui-table-supports-ui-control/18870/6 "2020-01-20T11:16:35Z")

</div>

It is inside the examples folder.

Goto “menu / import / examples / node-red-node-ui-table”

I took a look myself. It is actually no a callback. It is done by setting the formatter param “color” to an array of colors. At the same place you can set “min” and “max” and other things too: (scroll down to progress bar)

> **[Tabulator - Interactive JavaScript Tables](http://tabulator.info/docs/4.5/format)**
>
> Create interactive data tables in seconds with Tabulator. A lightweight, fully featured JavaScript table generation library.

But you can use a callback if you like to implement smoother coloring like red=value\*25.5 (for values from 0-100)

---

<div class="post-metadata">

### Author: ![Bond](https://avatars.discourse-cdn.com/v4/letter/b/9dc877/32.png) [@Bond](https://discourse.nodered.org/u/Bond)
#### Post date: [10 March 2020 17:47 UTC](https://discourse.nodered.org/t/ui-table-supports-ui-control/18870/7 "2020-03-10T17:47:12Z")

</div>

Hello @Christian-Me, I have some basic problems that I can not figure out myself as a newbie.  
I have read the Tabulator page and tried to add some lines in my "tabulator", unfortunately, no luck for me.  
I have created a table after a little modifying the example that you mentioned above. However, the table width is so small. I have to use a slider to see full data (i attached a pic of this).  
1.I'm wondering how to set the overall table width to be bigger.  
2. How to change the theme of my table?  
3. If a have another table in the same dashboard, it will be displayed vertically (1 top, 1 bottom). How can I set 2 tables horizontally (next to each other)?

This is my table: ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/5/d/5df65efb4a14725b48c8adfecb5929bcd73a6580.png)

This is my node file:

````auto
[{"id":"5b313ca3.8337b4","type":"change","z":"7e511ab0.37f324","name":"ui_control","rules":[{"t":"set","p":"ui_control","pt":"msg","to":"{\"tabulator\":{\"width\":500,\"layout\":\"fitColumns\",\"columnResized\":\"function(column){ var newColumn = { field: column._column.field, visible: column._column.visible, width: column._column.width, widthFixed: column._column.widthFixed, widthStyled: column._column.widthStyled }; this.send({topic:this.config.topic,ui_control:{callback:'columnResized',columnWidths:newColumn}}); }\",\"columnMoved\":\"function(column, columns){ var newColumns=[]; columns.forEach(function (column) { newColumns.push({'field': column._column.field}); }); this.send({topic:this.config.topic,ui_control:{callback:'columnMoved',columns:newColumns}}); }\",\"groupHeader\":\"function (value, count, data, group) {return value + \\\"<span style='color:#d00; margin-left:10px;'>(\\\" + count + \\\" Termostat\\\"+((count>1) ? \\\"e\\\" : \\\"\\\") + \\\")</span>\\\";}\",\"columns\":[{\"formatterParams\":{\"target\":\"_blank\"},\"title\":\"ID\",\"field\":\"ID\",\"width\":70,\"frozen\":true},{\"formatterParams\":{\"target\":\"_blank\"},\"title\":\"Position\",\"field\":\"Position\",\"width\":70,\"align\":\"center\"},{\"formatterParams\":{\"target\":\"_blank\"},\"title\":\"Temperature\",\"field\":\"Temperature\",\"width\":100,\"align\":\"center\"},{\"formatterParams\":{\"target\":\"_blank\"},\"title\":\"Humidity\",\"field\":\"Humidity\",\"width\":100,\"align\":\"center\"}],\"movableColumns\":true,\"groupBy\":\"\"},\"customHeight\":12}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":1140,"y":520,"wires":[["36f9f855.eab808"]]},{"id":"36f9f855.eab808","type":"ui_table","z":"7e511ab0.37f324","group":"88f188b6.106548","name":"Data-Table","order":1,"width":"4","height":"21","columns":[],"outputs":1,"cts":true,"x":1303,"y":520,"wires":[["fb2196d1.933088"]]},{"id":"88f188b6.106548","type":"ui_group","z":"","name":"Display","tab":"a26b585a.bc2cf8","disp":true,"width":"6","collapse":false},{"id":"a26b585a.bc2cf8","type":"ui_tab","z":"","name":"Shed","icon":"dashboard","disabled":false,"hidden":false}]```
````

---

<div class="post-metadata">

### Author: ![Christian-Me](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/christian-me/32/10774_2.png) [@Christian-Me](https://discourse.nodered.org/u/Christian-Me)
#### Post date: [10 March 2020 21:11 UTC](https://discourse.nodered.org/t/ui-table-supports-ui-control/18870/8 "2020-03-10T21:11:58Z")

</div>

Hi sorry to come back to you so late, I had to get to a computer with Node-RED insatlled.

1. The width depends on the width of your widget and this is limited by the width of the group the widget is placed:  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/3/c/3ca145956ea7ca6c771b1ae5d525e0a63ec8b47b.png)  
See size option in the second row  
and in the group:  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/2/9/29e143183c73091869f29af2b1f4a9d32a997a9f.png)  
Width in last row.

2. There are two themes available in the dashboard:  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/8/c/8cf889e1e93839675d022c6e0c53fdc0358b0e2e.png)  
ui-tables use switches together with the two main themes to light or dark.

3. widgets including ui-table are placed in groups. Groups are automatically arranged horizontally (as space is available). Widgets in a group are arranged vertically inside the group. All is done dynamically, so real fixed positions are not possible (responsive design). Try to place each table in an own group with the same with and size and you should get what you are looking for.

Hope this helps (a little)  
Chris

---

<div class="post-metadata">

### Author: ![coppo23](https://avatars.discourse-cdn.com/v4/letter/c/a4c791/32.png) [@coppo23](https://discourse.nodered.org/u/coppo23)
#### Post date: [5 July 2020 08:44 UTC](https://discourse.nodered.org/t/ui-table-supports-ui-control/18870/9 "2020-07-05T08:44:45Z")

</div>

Hi  
I am midway through constructing a table for node red heating and am stuck on one thing. I need to get back into node red the list of selected rows in the table.  
I have added the selector which works as i expect- see below. Clicking on any cell in the table apart from the selector row returns info to node red. I'm guessing i need to add something in the

addsomethingHere() bit?

I am at the 'copy and fiddle around' html coding standard!

Can anyone help please?

```auto
        "columns": [
            {
                "formatter": "rowSelection",
                "titleFormatter": "rowSelection",
                "hozAlign": "center",
                "headerSort": false,
                "cellClick": "function(e, cell){ cell.getRow().toggleSelect();addSomethingHere()}",
                "width": "3%",
                "frozen": true
            },

```

Cheers  
Andy

---

<div class="post-metadata">

### Author: ![Christian-Me](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/christian-me/32/10774_2.png) [@Christian-Me](https://discourse.nodered.org/u/Christian-Me)
#### Post date: [6 July 2020 05:29 UTC](https://discourse.nodered.org/t/ui-table-supports-ui-control/18870/10 "2020-07-06T05:29:21Z")

</div>

Hi

Interesting task. First I took a look into the docs:

> **[Tabulator - Interactive JavaScript Tables](http://tabulator.info/examples/4.0#selectable)**
>
> Create interactive data tables in seconds with Tabulator. A lightweight, fully featured JavaScript table generation library.

As I read it ... (I can't test it right now):

1. define the table as selectable
2. define one callback to send an array of selected rows back

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

```

This is the callback in a readable form:

```auto
var rowSelectionChanged = function(data, rows){
    this.send({ui_control:{'callback':'rowSelectionChanged','rowSelection':data}}); 
}

```

hope this helps

---

<div class="post-metadata">

### Author: ![coppo23](https://avatars.discourse-cdn.com/v4/letter/c/a4c791/32.png) [@coppo23](https://discourse.nodered.org/u/coppo23)
#### Post date: [6 July 2020 09:14 UTC](https://discourse.nodered.org/t/ui-table-supports-ui-control/18870/11 "2020-07-06T09:14:45Z")

</div>

Thanks – that worked first time.

What I don’t fully understand is all the dozens of attempts I made either returned null arrays or just nothing.

When I started watching the console (chrome) a lot of my attempts would give the error:

“Uncaught RangeError: Maximum call stack size exceeded”

I didn’t have single quotes in the object names but that doesn’t seem to matter if I do or don’t as none of them have white space.

I tried replacing the rowSelectionChanged callback to rowSelected and that either gives no result or the RangeError.

I had tried using this.table.getSelectedRows() but that gave me the range error.

It would be quite useful to know why I get the range error but your suggestion gets me moving forward again.

Andy

---

<div class="post-metadata">

### Author: ![Christian-Me](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/christian-me/32/10774_2.png) [@Christian-Me](https://discourse.nodered.org/u/Christian-Me)
#### Post date: [6 July 2020 12:49 UTC](https://discourse.nodered.org/t/ui-table-supports-ui-control/18870/12 "2020-07-06T12:49:17Z")

</div>

Perhaps the stack problem is caused by not sending ui\_control.callback property (as described in the readme of ui-table)

> use `this.send({})` to pass result to Node-RED. (to avoid a loopback add `ui_control.callback="someText"` )

Single quotes are easier to use because you do not have to escape them \” when using JSON formation.

---

<div class="post-metadata">

### Author: ![coppo23](https://avatars.discourse-cdn.com/v4/letter/c/a4c791/32.png) [@coppo23](https://discourse.nodered.org/u/coppo23)
#### Post date: [6 July 2020 14:12 UTC](https://discourse.nodered.org/t/ui-table-supports-ui-control/18870/13 "2020-07-06T14:12:25Z")

</div>

> [@Christian-Me](#):
>
> ui\_control.callback="someText"

Thanks.  
I have the code working as needed but for my satisfaction can you explain what is going on that causes loopback and the range error? (And how to avoid it)

For example - this gives me the error when i try and return rows (not that I need to do this, i;m just trying to understand what cause the range error)

```auto
        "rowSelectionChanged": "function(data, rows){this.send({topic:'rowSelection',ui_control:{'callback':'rowSelection','rowList':rows}});}",

```

And this works fine - returning the data part as expected.

```auto
        "rowSelectionChanged": "function(data, rows){this.send({topic:'rowSelection',ui_control:{'callback':'rowSelection','rowList':data}});}",

```

Many thanks  
Andy

---

<div class="post-metadata">

### Author: ![Christian-Me](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/christian-me/32/10774_2.png) [@Christian-Me](https://discourse.nodered.org/u/Christian-Me)
#### Post date: [6 July 2020 14:46 UTC](https://discourse.nodered.org/t/ui-table-supports-ui-control/18870/14 "2020-07-06T14:46:01Z")

</div>

Hi Andy,

Rows is not a JavaScript object per se it is a **component** which can not be transferred to a JSON formatted sting. You can/should access the data by the included methods.

> **[Tabulator - Component Objects](https://tabulator.info/docs/4.0/components)**
>
> Component objects allow you to interact directly with the components that make up your tables, such as rows, columns and cells

This is why the send method fails.

You can pick the relevant data by using the methods in a new object and send this back to the runtime.

Here is an example for the cell component

> [@Examples for node-red-node-ui-table](https://discourse.nodered.org/t/examples-for-node-red-node-ui-table/14256/81):
>
> Yes ... isn't too difficult. You need a callback function to send the edited data back to Node-RED. Best is to define one for the hole table independent of the type of editor defined for the column: msg.ui\_control.tabulator.cellEdited. function(cell){ this.send({ ui\_control:{callback:'cellEdited'}, payload:cell.getValue(), oldValue:cell.getOldValue(), field:cell.getColumn().getField(), id:cell.getRow().getCell('id').getValue() }); …

So your error is not directly related to the loopback issue - your error is caused by trying to convert a component to a json string.

---

<div class="post-metadata">

### Author: ![coppo23](https://avatars.discourse-cdn.com/v4/letter/c/a4c791/32.png) [@coppo23](https://discourse.nodered.org/u/coppo23)
#### Post date: [6 July 2020 19:22 UTC](https://discourse.nodered.org/t/ui-table-supports-ui-control/18870/15 "2020-07-06T19:22:27Z")

</div>

Thank you for your help - much appreciated and really useful.

The problem with my copy and tweak learning method is that it needs lots of attempts as there are a lot of combinations and most explanations omit key basic facts!

---

<div class="post-metadata">

### Author: ![Christian-Me](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/christian-me/32/10774_2.png) [@Christian-Me](https://discourse.nodered.org/u/Christian-Me)
#### Post date: [6 July 2020 20:47 UTC](https://discourse.nodered.org/t/ui-table-supports-ui-control/18870/16 "2020-07-06T20:47:37Z")

</div>

No problem ... try and error. We all learn most form mistakes and discoveries 😉

---

<div class="post-metadata">

### Author: ![davej](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/davej/32/25150_2.png) [@davej](https://discourse.nodered.org/u/davej)
#### Post date: [7 August 2020 00:48 UTC](https://discourse.nodered.org/t/ui-table-supports-ui-control/18870/17 "2020-08-07T00:48:07Z")

</div>

@Christian-Me  
In one of your other posts (Now closed) you specified this example.

```auto
function(cell){     
    this.send({
        ui_control:{callback:'cellEdited'},         
        payload:cell.getValue(),
        oldValue:cell.getOldValue(),
        field:cell.getColumn().getField(),
        id:cell.getRow().getCell('id').getValue()
    }); 
}

```

I cannot get that last line to work

```auto
id:cell.getRow().getCell('id').getValue()

```

if I change it to 'name' - like this:

```auto
id:cell.getRow().getCell('name').getValue()

```

it then works fine and returns the value of that name cell.

I have added id:1 etc at the beginning of the data rows definition.

```auto
{id:1,"name":"MEQ0451495","room":"Bathroom","SET_TEMPERATURE-value":22 ......................

```

Is the id field treated differently than a 'regular' field?

---

<div class="post-metadata">

### Author: ![Christian-Me](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/christian-me/32/10774_2.png) [@Christian-Me](https://discourse.nodered.org/u/Christian-Me)
#### Post date: [7 August 2020 07:23 UTC](https://discourse.nodered.org/t/ui-table-supports-ui-control/18870/18 "2020-08-07T07:23:32Z")

</div>

Hi,  
Yes id field is a little bit special because it is the default index field. You can specify any field as the index by using the index property (use `msg.ui_control.tabulator.index`)  
The index field is necessary if you like to update/delete or select a line or cell.  
The latest version of ui-table should generate the id field/column automatically if not present in the payload.

But you are certainly free to define your own index field or data.

### Row Index

A unique index value should be present for each row of data if you want to be able to programatically alter that data at a later point, this should be either numeric or a string. By default Tabulator will look for this value in the id field for the data. If you wish to use a different field as the index, set this using the index option parameter.

```auto

var table = new Tabulator("#example-table", { index:"age", //set the index field to the "age" field. });

```

---

<div class="post-metadata">

### Author: ![davej](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/davej/32/25150_2.png) [@davej](https://discourse.nodered.org/u/davej)
#### Post date: [7 August 2020 12:44 UTC](https://discourse.nodered.org/t/ui-table-supports-ui-control/18870/19 "2020-08-07T12:44:54Z")

</div>

Hi again @Christian-Me  
So I can remove my definition of id:1 and allow it to be auto generated. That is fine and I will do that but how do I retrieve that id value as I am going to be updating a cell.  
Trying to retrieve it like your code snippet doesn't work - for me at least!.  
So I assume that some other method is required to get that id value but I cannot find it documented how to retrieve it inside of a cellEdited call back

```auto
id:cell.getRow().getCell('id').getValue()

```

---

<div class="post-metadata">

### Author: ![Christian-Me](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/christian-me/32/10774_2.png) [@Christian-Me](https://discourse.nodered.org/u/Christian-Me)
#### Post date: [7 August 2020 16:56 UTC](https://discourse.nodered.org/t/ui-table-supports-ui-control/18870/20 "2020-08-07T16:56:34Z")

</div>

Hi ...

did some tests and yes there is a little bit of a problem with the `.getCell('id')` if the id is hidden or was never visible. Could not find the cause, perhaps a bug of the tabulator version we use. But the `.getIndex()` from the row component should work.

```auto
function(cell){
    this.send({
        ui_control:{callback:'cellEdited'},         
        payload:cell.getValue(),
        oldValue:cell.getOldValue(),
        field:cell.getColumn().getField(),
        id:cell.getRow().getIndex()
    }); 
}

```

and it is more versatile than specifying the index field name.

I updated the example flow too:

```auto
[{"id":"2e6a6379.742abc","type":"ui_table","z":"c4712650.59b5e8","group":"ff9fdb9a.7da098","name":"testTable","order":2,"width":"8","height":5,"columns":[{"field":"rowNumber","title":"Row Number 1","width":"","align":"left","formatter":"rownum","formatterParams":{"target":"_blank"}},{"field":"textValue","title":"Text","width":"","align":"left","formatter":"plaintext","formatterParams":{"target":"_blank"}},{"field":"numberValue","title":"Number","width":"","align":"left","formatter":"plaintext","formatterParams":{"target":"_blank"}}],"outputs":1,"cts":true,"x":808,"y":357,"wires":[["1c377ea0.5801e1","c0a33274.5dbeb"]]},{"id":"16664cef.5b26b3","type":"function","z":"c4712650.59b5e8","name":"table paramter","func":"msg.ui_control = {tabulator:{}};\n\n//workaround that buttos can`t deliver empty strings\nif (msg.payload.hasOwnProperty('payload')) {\n msg.payload=msg.payload.payload;\n}\n\nmsg.ui_control.tabulator[msg.topic]=msg.payload;\ndelete msg.topic;\nmsg.payload=null;\nreturn msg;","outputs":1,"noerr":0,"x":590,"y":646,"wires":[["2e6a6379.742abc","b8d75d24.6cbed"]]},{"id":"b8d75d24.6cbed","type":"debug","z":"c4712650.59b5e8","name":"table input","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":818,"y":646,"wires":[]},{"id":"1c377ea0.5801e1","type":"debug","z":"c4712650.59b5e8","name":"table output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":971,"y":357,"wires":[]},{"id":"b15c31a9.af37c","type":"ui_switch","z":"c4712650.59b5e8","name":"selectable","label":"selectable","tooltip":"","group":"ff9fdb9a.7da098","order":3,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"selectable","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":230,"y":442,"wires":[["16664cef.5b26b3"]]},{"id":"75207e8d.c54d4","type":"ui_switch","z":"c4712650.59b5e8","name":"movableColumns","label":"movableColumns","tooltip":"","group":"ff9fdb9a.7da098","order":5,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"movableColumns","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":260,"y":493,"wires":[["16664cef.5b26b3"]]},{"id":"c585e7a1.dfc648","type":"ui_button","z":"c4712650.59b5e8","name":"","group":"ff9fdb9a.7da098","order":6,"width":"4","height":"1","passthru":false,"label":"Format Numbers > 100","tooltip":"using a rowFormatter callback function","color":"","bgcolor":"","icon":"","payload":"function(row){ if(row.getData().numberValue>100){ row.getElement().style.backgroundColor = \"#A6A6DF\"; } },","payloadType":"str","topic":"rowFormatter","x":280,"y":629,"wires":[["16664cef.5b26b3"]]},{"id":"f178c6fe.710ef8","type":"ui_button","z":"c4712650.59b5e8","name":"","group":"ff9fdb9a.7da098","order":1,"width":0,"height":0,"passthru":false,"label":"Fill demo data","tooltip":"","color":"","bgcolor":"","icon":"","payload":"[{\"textValue\":\"Line #1\",\"numberValue\":123.12},{\"textValue\":\"Line #2\",\"numberValue\":100},{\"textValue\":\"Line #3\",\"numberValue\":50}]","payloadType":"json","topic":"rowFormatter","x":250,"y":357,"wires":[["2e6a6379.742abc"]]},{"id":"2403f929.df4006","type":"ui_button","z":"c4712650.59b5e8","name":"","group":"ff9fdb9a.7da098","order":8,"width":"4","height":"1","passthru":false,"label":"inject Tooltips callback","tooltip":"cell.getColumn().getField() + \" - \" + cell.getValue();","color":"","bgcolor":"","icon":"","payload":"function(cell){return cell.getColumn().getField() + \" - \" + cell.getValue(); },","payloadType":"str","topic":"tooltips","x":270,"y":731,"wires":[["16664cef.5b26b3"]]},{"id":"f6c68c45.58003","type":"ui_button","z":"c4712650.59b5e8","name":"","group":"ff9fdb9a.7da098","order":9,"width":"4","height":"1","passthru":false,"label":"clear Tooltips callback","tooltip":"empty string is not possible! so use a single space","color":"","bgcolor":"","icon":"","payload":"{\"payload\":\"\"}","payloadType":"json","topic":"tooltips","x":270,"y":765,"wires":[["16664cef.5b26b3"]]},{"id":"d2b29dda.60a5a","type":"ui_button","z":"c4712650.59b5e8","name":"","group":"ff9fdb9a.7da098","order":10,"width":"4","height":"1","passthru":false,"label":"reformat Number column","tooltip":"inject additional paramters to numberValue column","color":"","bgcolor":"","icon":"","payload":"[{\"field\":\"numberValue\",\"formatterParams\":{\"min\":0,\"max\":200,\"legend\":\"function (value) { if (value<100) return \\\"<span style='color:#FF0000;'>\\\"+value+\\\"</span>\\\"; else return \\\"<span style='color:#000000;'>\\\"+value+\\\"</span>\\\"; }\",\"legendAlign\":\"center\"},\"formatter\":\"progress\",\"topCalc\":\"function(values, data, calcParams){ var total = 0; var calc = 0; var count = 0; data.forEach(value => { total+=Number(value.numberValue); count++; }); if (count>0) calc=(total/count).toFixed(2); return `${calc} (avg)`; }\",\"headerTooltip\":\"avarage\"}]","payloadType":"json","topic":"columns","x":280,"y":833,"wires":[["16664cef.5b26b3"]]},{"id":"7b6490b3.cd9c7","type":"function","z":"c4712650.59b5e8","name":"callback function(s)","func":"// how to use the editor to write callback functions\n// DO NOT wire this into your flow!\n// copy / paste \"function( ... }\" into the correct calback parameter\n// use the \"debugger\" statement to debug your callback inside your browser\n\nvar topCalc = function(values, data, calcParams){\n var total = 0;\n var calc = 0;\n var count = 0;\n data.forEach(value => {\n total+=Number(value.numberValue);\n count++;\n });\n if (count>0) calc=(total/count).toFixed(2);\n return `${calc} (avg)`;\n}\n\nvar legend = function (value) {\n if (value<100) return \"<span style='color:#FF0000;'>\"+value+\"</span>\";\n else return \"<span style='color:#000000;'>\"+value+\"</span>\"; \n}\n\nvar cellEdited = function(cell){\n this.send({\n ui_control:{callback:'cellEdited'}, \n payload:cell.getValue(),\n oldValue:cell.getOldValue(),\n field:cell.getColumn().getField(),\n id:cell.getRow().getIndex()\n }); \n}","outputs":1,"noerr":0,"x":600,"y":765,"wires":[[]]},{"id":"91506d4b.4956a","type":"comment","z":"c4712650.59b5e8","name":"Intentionally not wired into the flow!","info":"use the editor to write callback functions\n\nDO NOT wire this into your flow!\n\ncopy / paste `function( ... }` into the correct calback parameter\nuse the `debugger` statement to debug your callback inside your browser\n","x":650,"y":731,"wires":[]},{"id":"732afcea.f728f4","type":"ui_button","z":"c4712650.59b5e8","name":"","group":"ff9fdb9a.7da098","order":11,"width":"4","height":"1","passthru":false,"label":"reset Number column","tooltip":"inject additional paramters to numberValue column","color":"","bgcolor":"","icon":"","payload":"[{\"field\":\"numberValue\",\"formatter\":\"plaintext\",\"topCalc\":\"\",\"headerTooltip\":\"\"}]","payloadType":"json","topic":"columns","x":270,"y":867,"wires":[["16664cef.5b26b3"]]},{"id":"89cca7ea.7fc998","type":"ui_button","z":"c4712650.59b5e8","name":"","group":"ff9fdb9a.7da098","order":12,"width":"4","height":"1","passthru":false,"label":"add/show id column","tooltip":"add a new column","color":"","bgcolor":"","icon":"","payload":"[{\"field\":\"id\",\"title\":\"id\",\"visible\":true,\"formatter\":\"plaintext\"}]","payloadType":"json","topic":"columns","x":270,"y":935,"wires":[["16664cef.5b26b3"]]},{"id":"32a3c4ad.1b85fc","type":"ui_button","z":"c4712650.59b5e8","name":"","group":"ff9fdb9a.7da098","order":13,"width":"4","height":"1","passthru":false,"label":"hide id column","tooltip":"hide id column (it is not possible to delete a existing column definition)","color":"","bgcolor":"","icon":"","payload":"[{\"field\":\"id\",\"title\":\"id\",\"visible\":false,\"formatter\":\"plaintext\"}]","payloadType":"json","topic":"columns","x":250,"y":969,"wires":[["16664cef.5b26b3"]]},{"id":"25247f4b.cc7ec","type":"inject","z":"c4712650.59b5e8","name":"","topic":"","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":84,"y":493,"wires":[["75207e8d.c54d4","bd3fd382.a2aa9"]]},{"id":"18ed8d27.bf00a3","type":"ui_button","z":"c4712650.59b5e8","name":"","group":"ff9fdb9a.7da098","order":7,"width":"4","height":"1","passthru":false,"label":"reset Numbers > 100","tooltip":"using a rowFormatter callback function","color":"","bgcolor":"","icon":"","payload":"{\"payload\":\"\"}","payloadType":"json","topic":"rowFormatter","x":270,"y":663,"wires":[["16664cef.5b26b3"]]},{"id":"bd3fd382.a2aa9","type":"ui_switch","z":"c4712650.59b5e8","name":"headerVisible","label":"headerVisible","tooltip":"","group":"ff9fdb9a.7da098","order":4,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"headerVisible","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":250,"y":544,"wires":[["16664cef.5b26b3"]]},{"id":"ce8d3904.be1b08","type":"ui_button","z":"c4712650.59b5e8","name":"","group":"ff9fdb9a.7da098","order":15,"width":"4","height":"1","passthru":false,"label":"inject cellEdited callback","tooltip":"","color":"","bgcolor":"","icon":"","payload":"function(cell){ this.send({ ui_control:{callback:'cellEdited'}, payload:cell.getValue(), oldValue:cell.getOldValue(), field:cell.getColumn().getField(), id:cell.getRow().getIndex() }); }","payloadType":"str","topic":"cellEdited","x":280,"y":1071,"wires":[["16664cef.5b26b3"]]},{"id":"f7b8bb20.5217f8","type":"ui_button","z":"c4712650.59b5e8","name":"","group":"ff9fdb9a.7da098","order":14,"width":"4","height":"1","passthru":false,"label":"enable cell edit (Text)","tooltip":"set \"editor\" to \"input\"","color":"","bgcolor":"","icon":"","payload":"[{\"field\":\"textValue\",\"title\":\"Text\",\"editor\":\"input\",\"formatter\":\"plaintext\"}]","payloadType":"json","topic":"columns","x":270,"y":1037,"wires":[["16664cef.5b26b3"]]},{"id":"c0a33274.5dbeb","type":"ui_text","z":"c4712650.59b5e8","group":"ff9fdb9a.7da098","order":16,"width":0,"height":0,"name":"","label":"table Output","format":"{{msg.payload}} id:{{msg.id}}","layout":"row-spread","x":971,"y":391,"wires":[]},{"id":"ff9fdb9a.7da098","type":"ui_group","z":"","name":"TEST","tab":"7dcc246f.ee661c","order":1,"disp":false,"width":"8","collapse":false},{"id":"7dcc246f.ee661c","type":"ui_tab","z":"","name":"TEST","icon":"dashboard","order":12,"disabled":false,"hidden":false}]

```

[Next page](https://discourse.nodered.org/t/ui-table-supports-ui-control/18870.md?page=2)
