Dropdown Selected Label (Value Label)

Wondering what would be the best way to retrieve the label associated with a specific dropdown value. I remember in Vision there is are separate "selection" and "selection text" properties. Would be a nice feature to have for this dropdown as well, not sure why it was removed.

Perhaps Phil's comment will be helpful,

Not quite the same. dwb was trying to extract the labels and values from a dataset for use with the dropdown. I'm aware that perspective doesn't use two columns, but it does still use two properties. It's kind of silly to provide two selection properties (value and label) and only return one (value) and not the other (label).

Maybe this one will guide you?

If you think it's silly, post your idea here, https://ideas.inductiveautomation.com/

That's what I was just working on as well. Would also be nice to be able to set/get the selection with just the index. That way I can add a button to move on to the next item in the list fairly easily.

For those looking to do the same thing, I added 3 custom props to the dropdown.

  1. selected_value - bound directly to the value prop of the dropdown
    a. Use a value change script to loop through the array of options and update the index and label.
  2. selected_index - updated from change script
  3. selected_label - updated from change script

change script:

def valueChanged(self, previousValue, currentValue, origin, missedEvents):

	val = currentValue.value
	if val is not None:
		count = len(self.props.options)
		for item in range(0, count):
			if self.props.options[item].value == val:
				self.custom.selected_index = item
				self.custom.selected_label = self.props.options[item].label
	else:
		self.custom.selected_index = None
		self.custom.selected_label = None

My reason for wanting to do this was to add buttons that would go to the next or previous item in the list. Fairly easy with scripts with the selected_index property.

next:

def runAction(self, event):
	
	current = self.getSibling('Dropdown').custom.selected_index
	maxIndex = len(self.getSibling('Dropdown').props.options)-1
	if current < maxIndex:
		next = current + 1
	else:
		next = 0
	
	self.getSibling('Dropdown').props.value = self.getSibling('Dropdown').props.options[next].value

previous:

def runAction(self, event):

	current = self.getSibling('Dropdown').custom.selected_index
	maxIndex = len(self.getSibling('Dropdown').props.options)-1
	if current > 0:
		next = current - 1
	else:
		next = maxIndex
	
	self.getSibling('Dropdown').props.value = self.getSibling('Dropdown').props.options[next].value

The enabled prop for each button is bound to the dropdown. If the value is null, the button is disabled.

1 Like

Another reason I like MS Access combo boxes! Bind to a query, set the number of columns, and which column holds the value you want to use. Simple and easy!

Thanks for this solution, I hope I can use it to filter a table...

Is the props.value or props.options bound to your dataset? In preview mode, I get an error that states
self.props.options has no length. And, I am assuming the change script is on the drop down value...

I dropped a label and bound it's text to the dropdown.props.value which, when a label is selected from the available list (currently the options are bound to a query because binding to the value did not work), the label component displays the correct "index" value as I would expect an Access combo box to do.

The len error does not appear to affect anything in the browser tho...except that the selected_index and selected_label props do not update.

Neither are bound to a dataset.

The change script is on the dropdown.custom.selected_value prop
dropdown.custom.selected_value is bound directly to dropdown.props.value

I don't get any error in preview mode.

dropdown_wIndex.zip (2.6 KB)

1 Like

I see how your code works. Just realized I don't think I need to loop through the dataset to do what I need.

Thank you, sir!

Here is a solution I used:
For my options I just appended the option number to the front of my value and parse it out in the event
selectedIndex = int(self.props.value[0:1])
labelText = self.props.options[selectedIndex].label
valueText = self.props.value[1:12]
image
image

Interesting, I just noticed the selected index is in the pic above (greyed next to the option number)
Too bad we can't access it. :frowning:

Nice solution! So many ways to skin the cat, just as always when it comes to programming.

Does this work with more than 10 options? I suppose you could use 00, 01, 02, etc. Probably safest to use double digit instead of single in the even the list needs to grow. It's easy to get over 10, not as easy to get over 100.

1 Like

Here's another option:

  1. Create a Custom Property called "selectedLabel" on the Dropdown
  2. In a Change Script on the Props/value property, put this code:
def valueChanged(self, previousValue, currentValue, origin, missedEvents):
	if self.props.value is None:
		self.custom.selectedLabel = None
	else:
		self.custom.selectedLabel = next(d['label'] for d in self.props.options if d['value'] == self.props.value)

Not a bad idea, but that assumes that a value of None means that no option is selected, while it's very possible that None is instead the value of a selected option.

Agreed. I liked the one line of code to handle the logic, but the None business was just error handling for my case because I have the showClearIcon property set to true, and none of my options result in a valid None value.