Change color for each option based on some category for Perspective Dropdown Component

Hi,

How to change the color for each option dynamically when the page is loaded based on the categories. Options will be binded from database using named query.

Thanks in advance.

1 Like

I second this. I would like to do this as well, but have not been able to find a way.

It's important to clarify which version you are on. The Dropdown currently (8.1.38) only allows for setting the style of ALL items to be the same.

If you know CSS and are using 8.1.22 or newer, you could conceivably alter individual options to display based on their label by maiking use of the stylesheet.css resource.

.iaDropdownCommon_options[data-label="KnownText"] {
    color: #FF0000
}

You would need to add a rule like this for every known text. Terrible if there is an unknown set of options. Not so bad if the set is known and finite.

1 Like

My particular set of dropdown options is always changing. The number of options and the labels will vary. I want to set their color based on some other stored information I have for each option. Trying to think of a way to do this using stylesheets...

I suggest that you use a table instead and "roll your own". You can make it perform like a dropdown, depending on your view type.

  • If the view is coordinate then toggle the visibility of the table and position it relative to the "dropdown" (which could be made of a text field and button with a down arrow icon).
  • If the view is flex then put the table below the "dropdown" and have it shove everything else on the page down when open.
  • Another option is to have the "dropdown" open a popup with the table on it. Use a message handler to send the selection back to the main view.

I finally figured out how to do it. I used the method shared here:

In their solution, they were able to set a specific style for each drop down option, adding a checkmark image to certain options. I just modified it to add on to the "styles" variable for each option, and set a background-color rather than adding content.

image

I'm using a list of options that I get from my database (it changes all the time). I loop through these options and check a time variable for them to determine if we are running late or on time. Based on the conditions, I set a background color for the option. Then append a styles script for each option to my "styles" variable. I did not have to bind the Markdown component to my dropdown. I'm assuming that the .iaDropdownCommon_options applies the styles to any dropdown found in the same view? - I'd like clarification on that if anyone knows.. But I'm not sure... just happy that this is working for me!

Also, I set the Markdown component's "display" to false, to hide it from the user.

def transform(self, value, quality, timestamp):
	styles = ''
	trailersPy = system.dataset.toPyDataSet(self.view.custom.TrailersOnsite)
	for trailer in trailersPy:
			trailerNum = trailer[1]
			lastEdited = trailer[5]
			#Determine if trailer has been checked (green), missed (orange), or late for a check (yellow), or just awaiting a check (white).
			#Trailer Back Color
			trailerBackColor = 'transparent'
			if system.date.minutesBetween(lastEdited, system.date.now()) > 150:
				# Over 2.5 hours since last check. Check was missed.
				# ORANGE
				trailerBackColor = '#F7901D'
			elif system.date.minutesBetween(lastEdited, system.date.now()) > 120 + 15:
				# Over 2 hours and 15 minutes since last check. Check is running late.
				# YELLOW
				trailerBackColor = '#FFF800'
			elif system.date.minutesBetween(lastEdited, system.date.now()) >= 120 - 15:
				# Last check was 1 hour and 45 minutes ago. Needs new check soon. (30 minute window)
				trailerBackColor = 'transparent'
			elif system.date.minutesBetween(lastEdited, system.date.now()) < 120 - 15:
				# Check happened within past 1 hour and 45 minutes. On Time.
				trailerBackColor = '#AAFFA1'
			
#			styles = ".iaDropdownCommon_options [data-label='"+ trailerNum +"']:before { content: url('/system/images/Builtin/icons/16/check2.png');	}"
			styles = styles + ".iaDropdownCommon_options [data-label='"+ trailerNum +"'] { background-color: " + trailerBackColor + ";	}"
	
	code =  """<style>
		"""+styles+"""
	\"></style>""".replace("\n", "").replace("\t", "")

# Copied and tested from Felipe_CRM's answer:
#	styles=".iaDropdownCommon_options [data-label='YourLabel']:before { content: url('/system/images/Builtin/icons/16/check2.png');	}"
#	styles2=".iaDropdownCommon_options [data-label='Another Label']{ background-color:#AAFFA1}"
#	code =  """<style>
#		"""+styles+styles2+"""
#	\"></style>""".replace("\n", "").replace("\t", "")
	
	return code
4 Likes

it works on any dropdown on the screen, if this view is loaded in.

If want to specify only a certain dropdown, you best use a meta property domId
and add #yourdomid infront
#MyUniqueDropDownId .iaDropdownCommon_options ...

1 Like

I tried adding a domID to the dropdown's Meta props and in front of the styles script, but doing so broke it. The dropdown doesn't display any colors then. I recognize the #id syntax for CSS stylesheets and I think it is correct, so I'm not sure why it doesn't work in this case.

Ahh no i remember, it wont work like that
the dropdown is a "popup" that is not nested isntde the component. so yeah that wont work

you could add a classes in though i think
dropdownOptionStyle.class

Tried this:

styles = styles + "dropdownOptionStyle.trailer [data-label='"+ trailerNum +"'] { background-color: " + trailerBackColor + ";	}"


image

Also tried this:

styles = styles + ".trailer [data-label='"+ trailerNum +"'] { background-color: " + trailerBackColor + ";	}"

Neither of those worked. Did I understand the usage correctly?

close :stuck_out_tongue:
Ignition adds "psc-" infront of every custom class

Add you have to remove the space for this case. a space indicated its a nested element. For this case both class and label are on the same element so not nested. This is something you can only know using the inspector and see where the class gets applied.

.psc-trailer[data-label=...

1 Like

I have several dropdown components with the same data presented in different groups. Some dropdown components might have the same data in them. On one particular dropdown I want to add icons to specific users in that dropdown.

I have applied a unique style to this one dropdown component called Add_Test_Project_Engineer_Custom.

The following transform does add icons to specific users but it does it to all dropdown components on the view.

def transform(self, value, quality, timestamp):
	
	tests = value
		
	# Get all tests that don't have a valid workstation
	testNames = [test['USR'] for test in tests if not test['ValidUser']]
	
	# Generate a css selector for each test
	testCssSelector = lambda testName: ".iaDropdownCommon_options [data-label='{}']:after".format(testName.replace("'", "\\'"))
	
	# Concatenate together those css selectors
	concatenatedTestCssSelectors = ', '.join(testCssSelector(testName) for testName in testNames)
	
	# Apply the following styles to all matching tests
	return '''<style>
		{cssSelectors} {{
			content: url('/system/images/Builtin/icons/16/warning.png');
			float: right;
		}}
	</style>
		'''.format(cssSelectors = concatenatedTestCssSelectors)

If I change the following line

return ".iaDropdownCommon_options [data-label='{}']::after".format(testName.replace("'", "\\'"))

to this new line

return ".psc-Add_Test_Project_Engineer_Custom .iaDropdownCommon_options [data-label='{}']::after".format(testName.replace("'", "\\'"))

Now none of the dropdown components show an icon.

I assume I am not targeting the dropdown component property.

Any ideas on what I am doing wrong?

Nevermind. I was doing 2 things wrong.

  1. I was applying the custom style to the style property instead of the drodownOptionStyle property.

  2. I didn't need to include .iaDropdownCommon_options anymore.

Updated code:

testCssSelector = lambda testName: ".psc-Add_Test_Project_Engineer_Custom[data-label='{}']:after".format(testName.replace("'", "\\'"))
1 Like

also be careful with spaces between css selectors, they matter ^^ the spacing between your samples are inconsistent

1 Like