The colorization of ui_table is kicking me in the head!

I have a simple ui_table node, populated the way I want, so far so good. Now I want to colorize an entire row text, say when a button is pressed, until the table updates again. For example press button, row text is turned green. When the row in the table is refreshed the text returns to default color.

I guess what I am struggling with is how to use ui_control to drive the ui_table colorization? I don't know if I am over thinking this, or what. Any help greatly appreciated. thanks.

Wow, no one chimed in yet? Color me surprised.

Have you looked at other threads about the ui-table? Take a read thru the tabulator

I have and I did, and it must be me, I can't make heads or tails of it. I just am missing how it works. There does not seem to be any basic examples at all that I can find. I have no clue how an ui_control works with a ui_table, but I have seen mention that it can drive the customization of ui_table... ok, how?

I just want to change the background and text color for an entire row in a table. Some use CSS, some use HTML, some use other methods. But I don't to use an ui_template, the ui_table works for me for about 95% of what I want or need. Using an ui_template to create a table seems over kill, in my case, just as generating a lot of HTML would, to me, seem to be.

So per the link you sent me, states formatters can be used, for example, this javascript...

//Generate print icon
var printIcon = function(cell, formatterParams){ //plain text value
    return "<i class='fa fa-print'></i>";
};

//Build Tabulator
var table = new Tabulator("#example-table", {
    height:"311px",
    layout:"fitColumns",
    rowFormatter:function(row){
        if(row.getData().col == "blue"){
            row.getElement().style.backgroundColor = "#A6A6DF";
        }
    },
    columns:[
    {formatter:"rownum", align:"center", width:40},
    {formatter:printIcon, width:40, align:"center", cellClick:function(e, cell){alert("Printing row data for: " + cell.getRow().getData().name)}},
    {title:"Name", field:"name", width:150, formatter:function(cell, formatterParams){
       var value = cell.getValue();
        if(value.indexOf("o") > 0){
            return "<span style='color:red; font-weight:bold;'>" + value + "</span>";
        }else{
            return value;
        }
    }},
    {title:"Progress", field:"progress", formatter:"progress", formatterParams:{color:["#00dd00", "orange", "rgb(255,0,0)"]}, sorter:"number", width:100},
    {title:"Rating", field:"rating", formatter:"star", formatterParams:{stars:6}, align:"center", width:120},
    {title:"Driver", field:"car", align:"center", formatter:"tickCross", width:50},
    {title:"Col", field:"col" ,formatter:"color", width:50},
    {title:"Line Wraping", field:"lorem" ,formatter:"textarea"},
    {formatter:"buttonCross", width:30, align:"center"}
    ],
});

It does all kinds of things to a table, but how do you apply it? How to you use it? No examples of how it is integrated to a flow? I can't see the how this interacts with a ui_table node, it is just raw javascript to me. No reference to the actual table, no payload, etc. That is where I seem to be struggling how just code relates to the node, if you understand what I am saying?

For a ui_text or ui_button, you just set the value for the given part, of the node. But ui_table does not have any predefined parts.

Hi,
First, take a look at the readme of the ui-table node, there is a lot of information in there. Then take a look at the provided examples. (Import flow/examples). Then search the forum for ui-table ui_control. Then read the tabulator docs.
The way dashboard nodes work is that they do the front end stuff for you and you only provide the data.
So all tabulator configuration is done by sending a msg.ui_control.tabulator object. All data of you code snippet you provided must be transferred into that object to be sent over by ui-table to the frontend where the table will appear in your browser.
I suggest first to start with the ui-table ui_control example.
What you like to do is doable:

In this thread and in the next one you find a lot of examples and insights:

@Christian-Me
Thanks for this, but I have read 10s of not 100s of pages. I just don't understand what I am reading. Hence the title of the thread.

I have a ui_table that is feed a payload message. Basic use of ui_table. This payload changes, is updated. How do I set the row text color for the table? Can you point me to a simple flow that illustrates that completely?

Reading the examples and documentation is just not making sense at this point, I am going around in circles. I have no clue how you send a msg.ui_control.tabulator object, never mind creating the content of said object. All the examples are static, just a predefined object array, with embedded HTML, that is not applicable to my situation.

Specific to the ui_table node, clicking on the format option per row definition in the table, does nothing, I can't set the color?


Versus plain text, this makes no sense to me, why can't I enter a value in the format field? This can't be that complex, right?

I am not trying to be difficult, I just really am not understanding this, at all at this point. I have created extensive and complex flows. But never until now tried to tackle table customization, really struggling here with this.

the format is just setting the format of the data expected for the cell - the data can be shown as text or a progress bar or a tick/cross etc... or a colour fill... this fills the cell with the colour supplied as the data - if the data is #ff0000 it will be red for example - it is NOT formatting the row or background colour etc.

1 Like

Right, I realize the UI setting is per cell, i.e. column wide setting. but since I can't enter any value in the UI, that is confusing. I can't seem to find even one example of how I set that setting if I do change it from plain text to color. I would think some where is a very basic example of how that format color option can be used. I have tried to google every way I can think of, just to figure that much out. No joy so far.

here is a simple example

[{"id":"c140681b.2b13c8","type":"ui_table","z":"846d7832.3348c8","group":"13b35473.20565c","name":"","order":0,"width":0,"height":0,"columns":[{"field":"title","title":"","width":"","align":"left","formatter":"plaintext","formatterParams":{"target":"_blank"}},{"field":"test","title":"","width":"","align":"left","formatter":"color","formatterParams":{"target":"_blank"}},{"field":"rest","title":"","width":"","align":"left","formatter":"plaintext","formatterParams":{"target":"_blank"}}],"outputs":0,"cts":false,"x":550,"y":620,"wires":[]},{"id":"f1da76c5.b75a78","type":"inject","z":"846d7832.3348c8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"#ff0000","payloadType":"str","x":170,"y":600,"wires":[["6ebd4255.17ac3c"]]},{"id":"f1ae029d.a9fbf","type":"inject","z":"846d7832.3348c8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"#00ff00","payloadType":"str","x":170,"y":640,"wires":[["6ebd4255.17ac3c"]]},{"id":"4e359597.2a49ac","type":"inject","z":"846d7832.3348c8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"#0000ff","payloadType":"str","x":170,"y":680,"wires":[["6ebd4255.17ac3c"]]},{"id":"6ebd4255.17ac3c","type":"function","z":"846d7832.3348c8","name":"","func":"msg.payload = [ {title:\"Row1\", test:msg.payload, rest:\"More words\"} ]\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":390,"y":620,"wires":[["c140681b.2b13c8"]]},{"id":"13b35473.20565c","type":"ui_group","z":"","name":"Default","tab":"ced4b0d9.bad33","order":1,"disp":true,"width":"6","collapse":false},{"id":"ced4b0d9.bad33","type":"ui_tab","z":"","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]

looks like


and gives

where the colour changes to match the data button injected.
As the node info text says
image
the data needs to be the html colour name or the #rrggbb hex colour value

1 Like

@dceejay
My hero... I so greatly appreciate this. I now see how to feed the color value to the table, but this flow erases the data in that cell? The first payload that would set the cell data, plain text of course, gets stomped by the following payload that has the color setting. Bare with me here, but I would have thought the color data is applied to the cell, not replacing data in cell. I hope I am asking this right.

Why would changing the attributes of a cell change the data in the cell... like a spreadsheet works, you have data, and then have attributes that display the data in a cell a specific way, such as colorized background.

[{"id":"fc8083cc.ef17","type":"tab","label":"Flow 2","disabled":false,"info":""},{"id":"ab0b249f.a2543","type":"ui_table","z":"fc8083cc.ef17","group":"d5efe0d2.84e7d8","name":"","order":0,"width":0,"height":0,"columns":[{"field":"title","title":"","width":"","align":"left","formatter":"plaintext","formatterParams":{"target":"_blank"}},{"field":"test","title":"","width":"","align":"left","formatter":"plaintext","formatterParams":{"target":"_blank"}},{"field":"rest","title":"","width":"","align":"left","formatter":"plaintext","formatterParams":{"target":"_blank"}}],"outputs":0,"cts":false,"x":850,"y":280,"wires":[]},{"id":"bf4c7ee5.1f3a8","type":"inject","z":"fc8083cc.ef17","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"#ff0000","payloadType":"str","x":470,"y":260,"wires":[["7b9551a5.e12608"]]},{"id":"41acb857.d503e","type":"inject","z":"fc8083cc.ef17","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"#00ff00","payloadType":"str","x":470,"y":300,"wires":[["7b9551a5.e12608"]]},{"id":"f27a9aaa.6eda58","type":"inject","z":"fc8083cc.ef17","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"#0000ff","payloadType":"str","x":470,"y":340,"wires":[["7b9551a5.e12608"]]},{"id":"7b9551a5.e12608","type":"function","z":"fc8083cc.ef17","name":"","func":"msg.payload = [ {title:\"Row1\", test:msg.payload, rest:\"More words\"} ]\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":690,"y":280,"wires":[["ab0b249f.a2543"]]},{"id":"3268cca5.ba4a04","type":"function","z":"fc8083cc.ef17","name":"","func":"msg.payload = [ {title:\"Row1\", test:msg.payload, rest:\"More words\"} ]\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":680,"y":240,"wires":[["ab0b249f.a2543"]]},{"id":"800392a2.151bb","type":"inject","z":"fc8083cc.ef17","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"text","payloadType":"str","x":470,"y":220,"wires":[["3268cca5.ba4a04"]]},{"id":"d5efe0d2.84e7d8","type":"ui_group","z":"","name":"Default","tab":"c7c410ec.469638","order":1,"disp":true,"width":"6","collapse":false},{"id":"c7c410ec.469638","type":"ui_tab","z":"","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]

Clearly, I am not understanding how the colorization is merged with the data, because of course one payload replaces the previous one.

It’s NOTHING to do with attributes. It’s all to do with DATA. That colour option is just a way of using colour to represent the data. Eg like a led indicator in a cell

Ok, so I asked the original question wrong... no need yell.

It’s not yelling. Its emphasis :slight_smile:

I said I am struggling with this... I tried to explain why I was not understanding it... the idea that everything a table gets is data, including the formatting, is new to my experience. When I code a UI or build one even in HTML, it both data and attributes, why I mentioned excel as an example. Obviously somewhere, somehow the data gets parsed so that you can have colorized text in the cell, be it background of the text or foreground or whatever, since the only input to the ui_table is data.

Short of writing an entire function in JavaScript with augmented HTML, using a ui_template from ground up, I am trying to learn how do something I think is really simple, I want to select a row, of existing data, and change its color representation. There has to be a simple way to do that.

The example for tabulator jumps from a very basic table with nothing from but plain text, to an example that has all kinds of shapes and colors.. all as you say data. And it does this with lot of scripting in a function apparently.

Example of using CSS never illustrates exactly how to apply the CSS file to the table, no example flow of how it is done.

The reference to ui_control I don't get as well, because again, I don't see the incremental steps, example flows. So directing me to the various examples are all from 0 to 100% done in two steps, I am struggling with.

So, I asked for help. I get emphasis... just pointing out that I don't get it. I know I don't get it, no emphasis needed.

well actually doing what you want to do is currently madly hard - so not surprising your head is sore from banging it on the wall. Highlighting the selected row is not hooked up by default, as it was mainly started as a display type table and evolved from there. Can certainly look to make this easier. hold that thought.

Hi,

sorry I was too busy yesterday with my day time job to help here. I took several bits out of your conversation:

  1. it would be usefull to merge configurations done in the editor UI with some additional configuration by ui_control messages. This is currently not possible but could be done. (I will look into the code the next days)
  2. (perhaps) some lack of documentation: It is always difficult to find the right balance between "expert" api style docs and step by step tutorials on the other hands. Every user background and approach is different. Sometimes a full featured example is useful to evaluate if something is possible in the first place. In your first posts you mentioned ui_control and posted some javascript lines of code. So it was fair to believe that you plan to take this road where in my experience everything tabulator has to offer is possible.

To help you further and perhaps I missed something

How and who is selecting a row? New data (updated value)? the user by clicking on a row? A message sent to ui-table?

I think (i did not test it) it is possible to "select" a row simply by sending the selectRow(id) to ui_table. You need a id column to be able to identify the row and then to select the row with the id 1 send

msg.payload={
    "command":"selectRow",
    "arguments":[1],
    "returnPromise":false
}

This (should) highlight a row (http://tabulator.info/examples/4.0#selectable)
but I think you have to set the attribute selectable=true first and we are back to my point 1 and you have to wait a few days if you do not want to go the complete defining ui-table by ui_control path, sorry.

Chris

Maybe this is what you're looking for?

The following nodes:
image

[{"id":"d783a5cb.379df8","type":"inject","z":"f30d5e3f.1af94","name":"","topic":"","payload":"[{\"name\":\"Bobby\",\"date\":\"1999-09-09\"},{\"name\":\"Steve\",\"date\":\"1977-07-07\"}]","payloadType":"json","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":550,"y":240,"wires":[["b2cd7710.5bd7e8"]]},{"id":"b2cd7710.5bd7e8","type":"change","z":"f30d5e3f.1af94","name":"","rules":[{"t":"set","p":"ui_control","pt":"msg","to":"{\"tabulator\":{\"rowFormatter\":\"function(row){vardata=row.getData();if(data.name==='Bobby'){row.getElement().style.backgroundColor='#BF3939';}}\",\"columns\":[{\"formatterParams\":{\"target\":\"_blank\"},\"title\":\"Name\",\"field\":\"name\"},{\"formatterParams\":{\"target\":\"_blank\"},\"title\":\"Date\",\"field\":\"date\"}]}}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":710,"y":240,"wires":[["c2af22e4.39acf"]]},{"id":"c2af22e4.39acf","type":"ui_table","z":"f30d5e3f.1af94","group":"42ceb1ec.be218","name":"","order":0,"width":0,"height":0,"columns":[],"outputs":0,"cts":false,"x":870,"y":240,"wires":[]},{"id":"42ceb1ec.be218","type":"ui_group","z":"","name":"Inputs","tab":"e6a82a1a.24db38","order":1,"disp":false,"width":"6","collapse":false},{"id":"e6a82a1a.24db38","type":"ui_tab","z":"","name":"Bobby","icon":"child","order":1,"disabled":false,"hidden":false}]

... create the following table:
image

I'm far from an expert, but when researching for a similar topic recently, I came to conclusion that my only option was ui_control.

The key here is the rowFormatter:

"rowFormatter":"function(row) { var data = row.getData(); if(data.name === 'Bobby') {row.getElement().style.backgroundColor = '#BF3939';} }"

I think from there anything can be achieved, considering that you can dynamically modify the ui_control string. You can also add some formatting to your input data (objects), and then not display those columns in your ui_control.

4 Likes

Yes - that is it... but it's a right pain to have to also declare the columns in the ui_control as well when we have a perfectly good edit panel to do most of it... so yes we need to be able to add to the edit panel options rather than just replace - so you could then just add the formatter... Also if we make the default for items to be delectable then the library itself will also add the "selected" class automatically for us... which can then simply be styled by css - not needing any ui_control (unless you want to do dynamic updates etc) - so yes... we are looking at improving it.

Geez, I really thought I was going nuts. Hell, I have written and debug raw C... Even on a Macintosh. Don't ask. So when I slammed into this, I thought as was losing it.

Ok, I have some other tasks to finish up, before I come back to this again, but thank you all very much for chiming in on this. Based on every thing I have read, looks like I am going to have to tackle understanding ui_control.

The final version of what I need will need will not need to respond to user actions directly in the table, but I will need to change colors, highlighting of rows as a notification or update of data pending. For example, a cell in an existing row has a value of 10, it is green as initial render of the table, if the user clicks on a 'update' button, that cell that has a value of 10 goes red, i.e. the entire row even, until the entire data set of the table is updated. Basically I want the operator to know that the value. or entire row, is going to change because they clicked the update button for the given table.

ok - version 0.3.2 of node-red-node-ui-table is now on npm/flows - so this should now work

[{"id":"5276ae0a.4105","type":"inject","z":"846d7832.3348c8","name":"add data","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":620,"wires":[["6ebd4255.17ac3c"]]},{"id":"6ebd4255.17ac3c","type":"function","z":"846d7832.3348c8","name":"","func":"msg.payload = [ \n    {title:\"Row0\", test:\"red\", rest:\"More words\"},\n    {title:\"Row1\", test:\"blue\", rest:\"More words\"},\n    {title:\"Row2\", test:\"green\", rest:\"More words\"},\n    {title:\"Row3\", test:\"yellow\", rest:\"More words\"},\n    {title:\"Row4\", test:\"cyan\", rest:\"More words\"} \n]\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":300,"y":620,"wires":[["c140681b.2b13c8","54380dea.c7f404"]]},{"id":"c140681b.2b13c8","type":"ui_table","z":"846d7832.3348c8","group":"13b35473.20565c","name":"","order":0,"width":"6","height":"4","columns":[{"field":"title","title":"title","width":"25%","align":"left","formatter":"plaintext","formatterParams":{"target":"_blank"}},{"field":"test","title":"colour","width":"25%","align":"left","formatter":"color","formatterParams":{"target":"_blank"}},{"field":"rest","title":"words","width":"50%","align":"left","formatter":"plaintext","formatterParams":{"target":"_blank"}}],"outputs":1,"cts":true,"x":490,"y":620,"wires":[["e5c1e113.bdf3e","446a5b9b.703374"]]},{"id":"446a5b9b.703374","type":"function","z":"846d7832.3348c8","name":"","func":"\nvar m = { payload: {\n    \"command\":\"deselectRow\",\n    \"arguments\":[ context.get(\"oldrow\") || 0 ],\n    \"returnPromise\":false\n}};\nmsg.payload={\n    \"command\":\"selectRow\",\n    \"arguments\":[msg.row],\n    \"returnPromise\":false\n}\ncontext.set(\"oldrow\",msg.row);\nreturn [[m,msg]];","outputs":1,"noerr":0,"initialize":"","finalize":"","x":500,"y":680,"wires":[["c140681b.2b13c8","905be523.cecbb8"]]},{"id":"e5c1e113.bdf3e","type":"debug","z":"846d7832.3348c8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":650,"y":620,"wires":[]},{"id":"6c5dbc15.6c1e04","type":"ui_template","z":"846d7832.3348c8","group":"13b35473.20565c","name":"","order":1,"width":0,"height":0,"format":"<style>\n.tabulator-row.tabulator-selected {\n\tbackground: #eaa !important;\n}\n</style>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"global","x":300,"y":580,"wires":[[]]},{"id":"13b35473.20565c","type":"ui_group","z":"","name":"Default","tab":"de4df751.046f08","order":3,"disp":false,"width":"6","collapse":false},{"id":"de4df751.046f08","type":"ui_tab","z":"","name":"Home","icon":"track_changes","order":1,"disabled":false,"hidden":false}]