Perspective - color table row based on rowData value

Hello guys, I am new to Perspective. I have a table component binded to a Named Query, I configured columns and one is a view ("Linked IDCoil"). I have also a transform script on the binding to add other columns and show a checkbox.
I want to change the background color of rows that containt IDCoil != self.view.params.IDCoil.
I tried to add style to columns object but doesn't work or view is no more displayed

This is the code:

columnData = [self.view.params.IDCoil] * value.getRowCount()
value = system.dataset.addColumn(value, columnData, 'CurrentIDCoil', str)
	
columnData = []
linkedOrders = []
for row in range(value.getRowCount()):
	if (self.view.params.IDCoil == value.getValueAt(row, "IDCoil")) :
		columnData.append(True)
		linkedOrders.append(value.getValueAt(row, "IDOrder"))
		continue
	
	columnData.append(False)
	
self.view.params.LinkedIDOrder = linkedOrders
value = system.dataset.addColumn(value, 0, columnData, 'Checked', bool)

return system.dataset.sort(value, 0, False)


Thanks @Transistor I edited the question with code

Row formatting requires a little bit of learning. I suggest the following:

  • Drop a Table component onto a new view. Note the following:
    • The table data is in JSON format rather than a dataset (which you seem to be using).
    • If you examine anything other than data[0] you will see that there are three key : value pairs, city, country, population.
    • Now examine data[0] and you'll see that the city entry has been changed to a JSON object with a style and some other properties. This is what you need to create in your instances. Meanwhile the actual value has been included in there as value.
  • There are some examples at the bottom of Perspective - Table - Ignition User Manual 8.1 - Ignition Documentation but we should be able to give you some tips to help you get started.
1 Like

Yes it is clear. So to color all the row the only possibility is to set the style on each cell? Is there a way to tell Ignition to target the entyre row object instead of all row cells?

I'm afraid not. You should be able to script it into each cell fairly efficiently though.

I forgot to mention that you should be able to set the query Return Format
to "json". See the top-right of the query binding editor.

1 Like

Thanks a lot @Transistor now it works perfectly, I paste the complete code:

columnData = [self.view.params.IDCoil] * value.getRowCount()
value = system.dataset.addColumn(value, columnData, 'CurrentIDCoil', str)
	
columnData = []
linkedOrders = []
for row in range(value.getRowCount()):
	if (self.view.params.IDCoil == value.getValueAt(row, "IDCoil")) :
		columnData.append(True)
		linkedOrders.append(value.getValueAt(row, "IDOrder"))
		continue
	
	columnData.append(False)
	
self.view.params.LinkedIDOrder = linkedOrders
value = system.dataset.addColumn(value, 0, columnData, 'Checked', bool)

value = system.dataset.sort(value, 0, False)
	
data = []
for row in  range(value.getRowCount()):
	rowData = {}
	assigned = False
	if (value.getValueAt(row, "IDCoil") != self.view.params.IDCoil and value.getValueAt(row, "IDCoil") is not None) :
		assigned = True
	
	for col in range(len(value.getColumnNames())):
		rowData[value.getColumnName(col)] = {
			'value': value.getValueAt(row, col)
		}
		
		if (assigned is True) :
			rowData[value.getColumnName(col)]['style'] = {
				'background-color': 'orange'
			}
	
	data.append(rowData)
	
return data
1 Like

Good work.

Combining this problem with our other thread discussing CSS, I should be able to persuade you to create a style class for the highlighted rows and use that in your script rather than hard-coding colors! I might go for something a little more subtle than the strong orange. Be cool, man! Be cool!

Keep style and content separate!

1 Like

Yes orangle was only to test script works. Why do you prefer using a CSS class instead of set color in code? Is there a way to set colors based on value in CSS class?

Why do you prefer using a CSS class instead of set color in code?

Because you can theme your whole project there with ease and consistency. It's the way of the web.

For example, if your theme is to highlight problems with orange background then create a style class called backgroundProblem1 and just set the background color on that (or anything else that will always be required when you use this style). Now you can apply that style class to every table, dropdown, text input, etc., when there is a problem. If you find that it's not quite the right color or you need to fit in with branding then you change the style and the whole project updates!

Is there a way to set colors based on value in CSS class?

That's not quite the right question. It should be, "Is there a way to set a component's style class?", and the answer is yes. I think it should be as simple as,

		if (assigned is True) :
			rowData[value.getColumnName(col)]['style'] = {
				'classes': 'backgroundProblem'
			}

1 That name looks a bit clunky but it will keep backgroundOK, backgroundProblem, backgroundOutOfRange, etc. grouped together alphabetically.

2 Likes

Understood @Transistor. In this case this row style is used only on this table I think but could be useful to save that style in a .CSS class to reuse if necessary

Guys I have another problem. All is working correctly but when I check a checkbox and then scroll down & up the table, all my checkboxes selected are unselected. Like Ignition is doing an automatic refresh when scrolling.
I modified the script to set to true checkboxes selected but doesn't work.
If I disable virtualized on the table props it works but the table shows an horizontal scroll bar that doesn't make sense

Reviewed code:

columnData = [self.view.params.IDCoil] * value.getRowCount()
value = system.dataset.addColumn(value, columnData, 'CurrentIDCoil', str)
	
columnData = [0] * value.getRowCount()
value = system.dataset.addColumn(value, columnData, 'Details', int)

columnData = [False] * value.getRowCount()
for row in range(value.getRowCount()):
	if (value.getValueAt(row, "IDOrder") in self.view.params.LinkedIDOrder) :
		columnData[row] = True
	
value = system.dataset.addColumn(value, 0, columnData, 'Checked', bool)

value = system.dataset.sort(value, 0, False)
	
data = []
for row in  range(value.getRowCount()):
	rowData = {}
	assigned = False
	if (value.getValueAt(row, "IDCoil") != self.view.params.IDCoil and value.getValueAt(row, "IDCoil") is not None) :
		assigned = True
	
	for col in range(len(value.getColumnNames())):
		rowData[value.getColumnName(col)] = {
			'value': value.getValueAt(row, col)
		}
		
		if (assigned is True) :
			rowData[value.getColumnName(col)]['style'] = {
				'background-color': 'rgb(255, 228, 181)'
			}
	
	data.append(rowData)
	
return data