Help Needed Populating Dropdown with String Array

Good Afternoon,

I am seeking some help with getting a string array to populate as options in a dropdown. I have everything going to the string array nicely. I did put a transformation in place and bound it to the options with a property tag to read the string array, but it keeps coming up as blank. I am using a dropdown in perspective.

I am after this (as an example), apologies for the handwriting:

# Ensure value is a list from the bound tag
batch_numbers = value if isinstance(value, list) else []

# Initialize an empty list for dropdown options
dropdown_options = []

# Add values from the array to the dropdown options, ensuring no duplicates
for batch_number in batch_numbers:
    if batch_number and batch_number not in [opt["value"] for opt in dropdown_options]:
        dropdown_options.append({"value": str(batch_number), "label": str(batch_number)})

# Return the options list
return dropdown_options

Any help would be great.

Thanks,

You are running into a type issue. If you put return isinstance(value, list) as your first line, you'll see that it returns false. Because of that, your script is falling back to the empty list as the value of batch_numbers.

The reported type of the value when bound to a custom array property is a JsonifiableArrayList.

You would need to change the first two lines of your transform script to:

	import java.util.ArrayList
	# Ensure value is a list from the bound tag
	batch_numbers = value if isinstance(value, java.util.ArrayList) else []

Your attempt at skipping duplicates will not work as you expect, as you are comparing an integer to strings, and that will always not match. You need to cast the batch_number to a string when making the check. Your duplicate check should be:

if batch_number and str(batch_number) not in [opt["value"] for opt in dropdown_options]:

With the above notes, here is your corrected script:

def transform(self, value, quality, timestamp):
	""" """
	import java.util.ArrayList
	# Ensure value is a list from the bound tag
	batch_numbers = value if isinstance(value, java.util.ArrayList) else []

	# Initialize an empty list for dropdown options
	dropdown_options = []

	# Add values from the array to the dropdown options, ensuring no duplicates
	for batch_number in batch_numbers:
		if batch_number and str(batch_number) not in [opt["value"] for opt in dropdown_options]:
			dropdown_options.append({"value": str(batch_number), "label": str(batch_number)})

	# Return the options list
	return dropdown_options

No need for any explicit type comparison; the only meaningful thing to defend against is "null", which you can do with a simple coalesce via or.

The 'duplicate' detection is also trivial by converting to a set.

Put together with a list comprehension, you can write this as tersely as:

def transform(self, value, quality, timestamp):
	batch_numbers = value or []

	return [
		{
			"value": batch_number,
			"label": batch_number
		}
		for batch_number in sorted(set(batch_numbers))
	]

Or in the imperative style:

def transform(self, value, quality, timestamp):
	batch_numbers = value or []
	
	dropdown_options = []

	distinct_batch_numbers = set(batch_numbers)
	sorted_batch_numbers = sorted(distinct_batch_numbers)
	
	for batch_number in sorted_batch_numbers:
		dropdown_options.append({
			"value": batch_number,
			"label": batch_number
		})

	return dropdown_options
6 Likes