Getting Label of the Dropdown component

I am trying to get the label of the selected dropdown item in perspective and assign it to a label property that I created in the dropdown.

Currently the value is updated automatically when the selection change, but I want the label to be updated to.

So I have the following expression configured on the label property, but it does not get the label item from the list:
{this.props.options[{this.props.value}].label}

however when the expression doesn't have the dynamic value reference it works, so this works:
{this.props.options[0].label}

How can I make it dynamic?

I want to use the selected label text in a named query.

Make the value in the options list an object, too, and include label in it. (You will likely need some transform to generate the item list with the label in both places.)

I am trying to get the label of the selected dropdown item in perspective and assign it to a label property that I created in the dropdown.

OK. You have created a custom property in the dropdown component. You wan it to return the value of the selected option label.

So I have the following expression configured on the label property, ...
{this.props.options[{this.props.value}].label}

You can't nest { } parameters like that. Expression Language does not allow it.

{value}['options'][{value}['index']]['label']

How it works:

{value}['options'] returns the whole list of options.
{value}['index'] returns the pointer.
['label'] returns the label entry for the selected option.

There is a simpler way: make the label and value the same!

Jazz dropdown

Now the dropdown's value property gives you the parameter for your named query.

1 Like

Either do as Phil says, which is to include the label in the value by making it an object,
Or use this (because sometimes having objects as dropdown values is unpractical):

next((opt['label'] for opt in options if opt['value'] == value, "default")

Let's say you want to display that "label" in a label component.
Bind its text property to the dropdown's value and options, then use the code above in a transform.
You'll obviously have to adapt the variables names.

If your options are in dataset format, you can use the lookup expression instead.

I wouldn't use the value as an index, because it's not always valid.

2 Likes


The solution is working, but I had to create an offset for the selected value i.e. selectedValue - 1

You're using values 1, 2, 3 for options 0, 1, 2.
You need to fix something or add a +1 to the expression.

Why can you not make the values the same as the labels?

Yes, because your values start from 1, while indices start from 0.
This is why you shouldn't use values for array indexing.

I'm going to retrieve the the value/label pairs dynamically from the database. Therefore I cannot make them the same. I am aware that the options start at 0 where the values start at 1.
Therefore the below works ok, but I thought that there would be a better option.
This is such simple thing that I was expecting that it would be natively supported by the Ignition SCADA. even in VBA things like that are natively supported.

Could I implement it with a script like the below?

for i in self.props.options:
if i[0] == self.props.value:
self.props.label = i[1]

Please format code in your posts using the </> button.

Try this in your expression structure binding:
{value}['options'][{value}['index'] - 1]['label']

This will work if your option value is always offset by 1 from the array item number.

You can script it but the performance will be worse than an expression binding.

I already provided how to do it in script, check the first few messages.

It is. Use objects.

2 Likes

Thanks for that. I wasn't sure whether that was script or expression. I will try to use that. Seems like the script will be more sensible solution for me as it will be more predictable.

Regarding the dropdown value/label pairs they are currently properties of the options list object as I understand it and based on what I read from manual (screenshot below). Making the value object and including label in it is most likely possible. However, as I mentioned previously, all the dropdowns will be retrieved from the database tables and therefore those list will be dynamic.

The solution from the Transistor also works and I tested it. It can be implemented but with an offset for the value i.e. selected value - 1

I will also test your script and provide all the solutions in the chat when done.

Thanks to everyone for the replies on this subject. It was very helpful.

That's not an issue. Let's say your query returns a table with columns "name" and "id"

You can add a transform to the query binding to make whatever structure your want or need (using json as the return format of the query binding):

return [
	{
		'label': option['name'],
		'value': {'name': option['name'], 'id': option['id']}
	} for option in value
]

And you'll get a dropdown with the names as labels, and objects containing the name AND id as values.

2 Likes

Thank you for providing the valuable information so far. After testing all scenarios and weighing the development times and possible changes needed in the future. I came up with a much simpler and elegant solution that works perfectly.

For those who come across similar problem, here is what I've done.

  1. I created an extra label property on the dropdown object.

  2. I added a change script on the exiting value property
    image

  3. I added a loop in the script that loops through the options array and finds the value matching the selection. Then assign the corresponding label to the new label property.

JOB Done

Bindings do that, only the other way around: they're configured on the object that receives the value, instead of the object that generates it like a change script does.
I (we ?) usually prefer bindings, because they make it very clear what's going on.
Imagine now: you show the label to someone and ask to tell you where the value comes from. It's not a simple task. With a binding, it's as easy as clicking on the icon and looking at the configuration.

So I'll still suggest using a binding on your label, instead of a change script on the dropdown.

And then, the script. This one does exactly the same thing as the one I provided above, so I'm guessing you're not super familiar with python. Do you want me to detail how it works ? It's a good occasion to learn something, and I don't mind explaining, but I'll save myself the trouble if you're not interested.

3 Likes

Sigh. Poorly and unmaintainably. Your reason for not using value objects was shown, with example, to be bogus.

Using value objects is the right answer. Full stop.

I am programming in PHP, C#, VB.Net, VBS and JavaScript and must admit that I am new to Python. However, the principles of the programming languages are the same for every language. Only the syntax is different.
I am not familiar with Ignition expressions that's why I needed help to implement this with binding. However, still don't see this being implemented with binding efficiently, I didn't see that in the answers.

You don't need expressions to use bindings. While it's better to use them when possible, it's not the only way of doing things.

You can use a script transform and use python to process your data. In this case, you'd bind the label to the dropdown's value, then use the script I provided earlier in the transform.

I understand. Please can you provide working implementation example step by step? As I said I am new to the Perspective and need a little guidance. Thanks