# Using styles in a script transform?

**URL:** <https://forum.inductiveautomation.com/t/using-styles-in-a-script-transform/54942>\
**Category:** Ignition\
**Tags:** perspective, ignition80\
**Created:** [January 12, 2022, 6:44pm UTC](https://forum.inductiveautomation.com/t/using-styles-in-a-script-transform/54942 "2022-01-12T18:44:42Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![bkarabinchak.psi](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bkarabinchak.psi/32/83567_2.png) [@bkarabinchak.psi](https://forum.inductiveautomation.com/u/bkarabinchak.psi)\
**Post date:** [January 12, 2022, 6:44pm UTC](https://forum.inductiveautomation.com/t/using-styles-in-a-script-transform/54942/1 "2022-01-12T18:44:42Z")

</div>

I have a perspective table with a column “Record Count” that varies can be as low as 0 and arbitrarily high.

If the value of the Record Count in a row is 0 to 10, I want to apply a style “BadRecordCount”. If its from 11 to 20, I want to apply a style “WarningRecordCount”, and anything above that gets the style “GoodRecordCount”.

The styles are basic and all look like this just with a different background color -  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/9/2/92e9038f03a34ee0c9a9d6fe0200d275a193521e.png)

I’ve seen people use data transforms to set the background color, but in those examples I’ve seen the color is hardcoded. How can I use my predefined styles instead of hardcoding it into a script? Or perhaps there’s a way to do this in a different manner using styles? Using styles here is important because I have many tables that will require similar styling. I haven’t touched Perspective in a while and I can’t seem to get this to work.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [January 12, 2022, 7:17pm UTC](https://forum.inductiveautomation.com/t/using-styles-in-a-script-transform/54942/2 "2022-01-12T19:17:26Z")

</div>

How are you getting the data onto the table?  
You should be able to add a `styles` key to the row object.

---

<div class="post-metadata">

**Author:** ![bkarabinchak.psi](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bkarabinchak.psi/32/83567_2.png) [@bkarabinchak.psi](https://forum.inductiveautomation.com/u/bkarabinchak.psi)\
**Post date:** [January 12, 2022, 7:53pm UTC](https://forum.inductiveautomation.com/t/using-styles-in-a-script-transform/54942/3 "2022-01-12T19:53:04Z")

</div>

It is coming through as NamedQuery.

I do see the rows object with a style component and setting one of them I do see all the rows take on that style -  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/6/2/62ef4fa54e7b2dc12ed8a290f323093cac3945e4.png)

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/4/7/4763faaba16a9060b63bb96552e32d4c0148a170.png)

How can I make an expression such that “If row[‘recordTotal’] \<10 BadWarningRecordCount then BadRecordCount if row[‘recordTotal’] \< 20 WarningRecordCount Else GoodRecordCount”. Could I do this in an expression or would I need to do it a different way?

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [January 12, 2022, 8:02pm UTC](https://forum.inductiveautomation.com/t/using-styles-in-a-script-transform/54942/4 "2022-01-12T20:02:00Z")

</div>

Bind the classes property to the record count, then use a map transform to set the class as appropriate.

---

<div class="post-metadata">

**Author:** ![Arnaud\_Declerck](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/arnaud_declerck/32/44872_2.png) [@Arnaud\_Declerck](https://forum.inductiveautomation.com/u/Arnaud_Declerck)\
**Post date:** [January 12, 2022, 8:06pm UTC](https://forum.inductiveautomation.com/t/using-styles-in-a-script-transform/54942/5 "2022-01-12T20:06:57Z")

</div>

I think what @paul-griffith is speaking is to put the style into the data props like this  
{  
"value": { // The rows value.  
"city": { // Custom cell configuration.  
"value": "Folsom",  
"editable": true,  
"style": {  
"backgroundColor": "ignition-orange",  
"classes": "some-class"  
},  
"align": "top" // Also accepts center and bottom  
"justify": "left" // Also accepts center and right  
},  
"country": "United States",  
"population": 1000000  
},  
"style": { // Custom row styles.  
"backgroundColor": "#F7901D",  
"classes": "some-class"  
},  
"subview": { // Row subview configuration. Can override configuration from rows config.  
"enabled": true,  
"viewPath": "myView",  
"viewParams": {  
"param1": 3  
}  
}  
}

---

<div class="post-metadata">

**Author:** ![bkarabinchak.psi](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bkarabinchak.psi/32/83567_2.png) [@bkarabinchak.psi](https://forum.inductiveautomation.com/u/bkarabinchak.psi)\
**Post date:** [January 12, 2022, 8:13pm UTC](https://forum.inductiveautomation.com/t/using-styles-in-a-script-transform/54942/6 "2022-01-12T20:13:02Z")

</div>

Sorry it’s been so long since using perspective I’m not sure I understand. I have this column which is the column that is going to be responsible for coloring the row

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/1/7/171ceb4ddac8357c8506411bd3039e08d189fa93.png)

This is the classes property I would bind? Or I would bind the rows style (or classes) property to the rows[‘recordTotal’] somehow?

---

<div class="post-metadata">

**Author:** ![bkarabinchak.psi](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bkarabinchak.psi/32/83567_2.png) [@bkarabinchak.psi](https://forum.inductiveautomation.com/u/bkarabinchak.psi)\
**Post date:** [January 12, 2022, 8:14pm UTC](https://forum.inductiveautomation.com/t/using-styles-in-a-script-transform/54942/7 "2022-01-12T20:14:01Z")

</div>

I’m going to try with the binding first but good to know this is available as an option.

---

<div class="post-metadata">

**Author:** ![Arnaud\_Declerck](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/arnaud_declerck/32/44872_2.png) [@Arnaud\_Declerck](https://forum.inductiveautomation.com/u/Arnaud_Declerck)\
**Post date:** [January 12, 2022, 8:16pm UTC](https://forum.inductiveautomation.com/t/using-styles-in-a-script-transform/54942/8 "2022-01-12T20:16:30Z")

</div>

i have an example running for subview (probably the same method for style) at work with a transform script on a named query. I will post here tomorrow.

---

<div class="post-metadata">

**Author:** ![matthew.ayre](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/matthew.ayre/32/19499_2.png) [@matthew.ayre](https://forum.inductiveautomation.com/u/matthew.ayre)\
**Post date:** [January 12, 2022, 8:40pm UTC](https://forum.inductiveautomation.com/t/using-styles-in-a-script-transform/54942/9 "2022-01-12T20:40:11Z")

</div>

Hi @bkarabinchak.psi, the others are correct, but for further context this may help: [Changing colour of row based off value in cell in perspective table - #17 by cmallonee](https://forum.inductiveautomation.com/t/changing-colour-of-row-based-off-value-in-cell-in-perspective-table/43587/17)

The only difference is that instead of defining `"style":{"backgroundColor":"#000000"}` you would use `"style":{"classes":"BadRecordCount"}` as @Arnaud_Declerck has eluded.

To do this you will need to iterate through your data binding and create the appropriate structure, with the logic in place to assign the appropriate style class.

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [January 12, 2022, 8:50pm UTC](https://forum.inductiveautomation.com/t/using-styles-in-a-script-transform/54942/10 "2022-01-12T20:50:08Z")

</div>

So digging in a bit, it seems that you have to manipulate the data so that it has the needed structure. A map transform will not work in this instance.

Either way you’ll just need to set the style for that data item so that it matches your criteria.

The link provided by @matthew.ayre will guide you pretty well in this.

---

<div class="post-metadata">

**Author:** ![Arnaud\_Declerck](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/arnaud_declerck/32/44872_2.png) [@Arnaud\_Declerck](https://forum.inductiveautomation.com/u/Arnaud_Declerck)\
**Post date:** [January 13, 2022, 6:50am UTC](https://forum.inductiveautomation.com/t/using-styles-in-a-script-transform/54942/11 "2022-01-13T06:50:36Z")

</div>

Hi @bkarabinchak.psi,

Since a good example is better than a lot of text  
[TableStyleTransform.zip](https://forum.inductiveautomation.com/uploads/short-url/yApFysLpV2Qoeu70yZZuaNI40KB.zip) (8.6 KB)

I use a dataset in the custom props of the table component for this example but you can use it with a named query also (Just make sure that the return format is set to Dataset)  
You will need to change also the name of the column where you want to do the check for the style definition (Yellow highlight).

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/a/4/a4678f96a23972caa609b7e9bd3906cce7566920.png)

in the zip file i've include the view and styles used.

Hope this help

Fyi: if you use this structure with column definition using a viewPath make sure the render is set to auto. Otherwise the cell value will not be send to the render view.

> [@Perspective Table cell view render](https://forum.inductiveautomation.com/t/perspective-table-cell-view-render/54868/9):
>
> @ynejati i've found something interesting. when i set the render mode to auto instead of view then the value is set to the render view. i don't know if this is a bug. but this solved my problem

Regards

---

<div class="post-metadata">

**Author:** ![bkarabinchak.psi](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bkarabinchak.psi/32/83567_2.png) [@bkarabinchak.psi](https://forum.inductiveautomation.com/u/bkarabinchak.psi)\
**Post date:** [January 13, 2022, 2:42pm UTC](https://forum.inductiveautomation.com/t/using-styles-in-a-script-transform/54942/12 "2022-01-13T14:42:58Z")

</div>

Thanks for all the help everyone.

Here is what I came up with so far and I just had two follow up questions because I think I am not doing this the “right” or “clean” way

This is what is my current data transform is and it works in that bu

```auto
	import system.date
	pydset = system.dataset.toPyDataSet(value)
	returned_rows = []
	for row in pydset:
		row_dict = {}
		constantColumnsBeforeStyle = ["plantNumber","plantName","LocalDataTableName"]
		constantColumnsMiddle = ["LastUpdated","LastRecordDateTime"]
		constantColumnsAfterStyle = ["recordsPerHourAvg","LastAttemp_Status","LastUpdated_Status","LastRecordDateTime_Status"]
		# Set constants first
		for column in constantColumnsBeforeStyle:
			row_dict[column] = {'value':row[column]}
			
# # Style LastAttempt
# now = system.date.now()
# if system.date.hoursBetween(row['LastAttempt'], now) > 1:
# row_dict['LastAttempt'] = {'value': row['LastAttempt'], 'style':{'classes':'TableStyles/BadRecordCount'}}
# else:
# row_dict['LastAttempt'] = {'value': row['LastAttempt']}
#		
		# Middle constants		
		for column in constantColumnsMiddle:
			row_dict[column] = {'value':row[column]}
			
		# Style Record Columns 
		if int(row['recordsTotal']) < 5:
			row_dict['recordsTotal'] = {'value': row['recordsTotal'], 'style': {'classes':'TableStyles/BadRecordCount'}}
		elif int(row['recordsTotal']) < 10:
			row_dict['recordsTotal'] = {'value': row['recordsTotal'], 'style': {'classes':'TableStyles/WarningRecordCount'}}
		else:
			row_dict['recordsTotal'] = {'value': row['recordsTotal'], 'style': {'classes':'TableStyles/GoodRecordCount'}}

		# Set constants after		
		for column in constantColumnsAfterStyle:
			row_dict[column] = {'value':row[column]}

		returned_rows.append(row_dict)
	return returned_rows

```

Question 1 - am I handling the non styled columns wrong? Is it ok to just do them all in one go or to preserve the order of the columns in the query do I need to do it like how I currently have it?

Question 2 - Normally the recordsTotal is a progress bar -  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/7/d/7d66d7a015bde239a54982481105e85538e1b087.png)

but after my styling it becomes a normal int - how can I preserve the progress bar?  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/a/4/a4e8ec0860513445a05f93f0b874565f2fd35314.png)

Last Question - I have a column LastAttempt that is a datetime in the database and selected directly. I wanted to make it so that if the last attempt was over an hour ago it would be styled red. However my attempt

```auto
# now = system.date.now()
# if system.date.hoursBetween(row['LastAttempt'], now) > 1:
# row_dict['LastAttempt'] = {'value': row['LastAttempt'], 'style':{'classes':'TableStyles/BadRecordCount'}}
# else:
# row_dict['LastAttempt'] = {'value': row['LastAttempt']}

```

just gives me a `java.lang.NullPointerException` hence why its commented out but I also don’t know why it’s giving me that exception specifically.

I know there is a column called LastAttempt in the dataset which is what I thought would throw me the a NullPointException - trying to get a key from the row that doesn’t exist, but it does exist, so I’m lost as to what’s causing this.  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/4/7/479a645bf2bc1ad31569c393d0db93c9072c5da4.png)

---

<div class="post-metadata">

**Author:** ![bkarabinchak.psi](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bkarabinchak.psi/32/83567_2.png) [@bkarabinchak.psi](https://forum.inductiveautomation.com/u/bkarabinchak.psi)\
**Post date:** [January 13, 2022, 2:58pm UTC](https://forum.inductiveautomation.com/t/using-styles-in-a-script-transform/54942/13 "2022-01-13T14:58:33Z")

</div>

Answer to my first question is that no the order of the constant columns in my script transform does not matter, I can do them all in one go at the end, which is good news and makes the script simpler. However I still can’t seem to get the number to come through as a progress bar on the styled column or get the date comparison to work without getting a java.lang.NullPointerException

New script -

```auto
	import system.date
	pydset = system.dataset.toPyDataSet(value)
	returned_rows = []
	for row in pydset:
		row_dict = {}
		unStyledColumns = ["plantNumber","plantName","LocalDataTableName","LastUpdated","LastRecordDateTime","recordsPerHourAvg","LastAttemp_Status","LastUpdated_Status","LastRecordDateTime_Status"]
			
# # Style LastAttempt
# now = system.date.now()
# if system.date.hoursBetween(row['LastAttempt'], now) > 1:
# row_dict['LastAttempt'] = {'value': row['LastAttempt'], 'style':{'classes':'TableStyles/BadRecordCount'}}
# else:
# row_dict['LastAttempt'] = {'value': row['LastAttempt']}
# # Set constants first
			
		# Style Record Columns 
		if int(row['recordsTotal']) < 5:
			row_dict['recordsTotal'] = {'value': row['recordsTotal'], 'style': {'classes':'TableStyles/BadRecordCount'}}
		elif int(row['recordsTotal']) < 10:
			row_dict['recordsTotal'] = {'value': row['recordsTotal'], 'style': {'classes':'TableStyles/WarningRecordCount'}}
		else:
			row_dict['recordsTotal'] = {'value': row['recordsTotal'], 'style': {'classes':'TableStyles/GoodRecordCount'}}

		# Unstyled columns
		for column in unStyledColumns:
			row_dict[column] = {'value':row[column]}

		returned_rows.append(row_dict)
	return returned_rows

```

Just for extra context I’ve confirmed `system.perspective.print(str(type(row['LastAttempt'])))` gives me `<type 'java.sql.Timestamp'>`

---

<div class="post-metadata">

**Author:** ![bkarabinchak.psi](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bkarabinchak.psi/32/83567_2.png) [@bkarabinchak.psi](https://forum.inductiveautomation.com/u/bkarabinchak.psi)\
**Post date:** [January 13, 2022, 4:26pm UTC](https://forum.inductiveautomation.com/t/using-styles-in-a-script-transform/54942/14 "2022-01-13T16:26:02Z")

</div>

@matthew.ayre @lrose @paul-griffith

I realized the script transform provides a timestamp argument for when the dataset comes in. I tried using that instead of doing `now = system.date.now()` but the following

```auto
		if system.date.hoursBetween(row['LastAttempt'],timestamp) > 1:
			row_dict['LastAttempt'] = {'value': row['LastAttempt'], 'style':{'classes':'TableStyles/BadRecordCount'}}
		else:
			row_dict['LastAttempt'] = {'value': row['LastAttempt']}

```

still gives me a java.lang.NullPointerException error.

Either of those two lines separately work as expected.

It seems like it is `if system.date.hoursBetween(row['LastAttempt'],timestamp) > 1` specifically that is giving me a NullPointerException. Any thoughts?

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [January 13, 2022, 4:36pm UTC](https://forum.inductiveautomation.com/t/using-styles-in-a-script-transform/54942/15 "2022-01-13T16:36:00Z")

</div>

My guess is that `system.date.hoursBetween` is having trouble with the `java.sql.Timestamp`.

What happens if you do something like:

```auto
		lastAttempt = system.date.parse(row['LastAttempt'])
		if system.date.hoursBetween(lastAttempt,timestamp) > 1:
			row_dict['LastAttempt'] = {'value': row['LastAttempt'], 'style':{'classes':'TableStyles/BadRecordCount'}}
		else:
			row_dict['LastAttempt'] = {'value': row['LastAttempt']}

```

---

<div class="post-metadata">

**Author:** ![bkarabinchak.psi](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bkarabinchak.psi/32/83567_2.png) [@bkarabinchak.psi](https://forum.inductiveautomation.com/u/bkarabinchak.psi)\
**Post date:** [January 13, 2022, 4:45pm UTC](https://forum.inductiveautomation.com/t/using-styles-in-a-script-transform/54942/16 "2022-01-13T16:45:19Z")

</div>

Ok that got me closer. I realized some of these columns are blank unfortunately because I got a new IllegalArugmentException from system.date.parse(row[‘LastAttempt’]).

This ended up working with that knowledge -

```auto
		if row['LastAttempt'] is None:
			row_dict['LastAttempt'] = {'value': row['LastAttempt']}
		elif system.date.hoursBetween(row['LastAttempt'],timestamp) > 1:
			row_dict['LastAttempt'] = {'value': row['LastAttempt'], 'style':{'classes':'TableStyles/BadRecordCount'}}
		else:
			row_dict['LastAttempt'] = {'value': row['LastAttempt']}

```
