Changing order on flex repeater

I have a flex repeater showing various user configurable analog displays, the only drawback is that the order of the instances is in order of which it was entered.
The source of the parameters is a Json column in my database, is there a way to reorder the instances in a flex repeater? Preferably in a intuitive drag and drop manner?

1 Like

They are determined by the array instances property, if you put a script transform on your binding you can sort the list in whatever way you’re looking for.

For instance if you want to sort the list by a parameter named “Order” than for a json list you would do:
return sorted(value, key = lambda x: x[‘Order’])
And a dataset you would do:
return system.dataset.sort(value, value.getColumnIndex(‘Order’))

4 Likes

Hi I’m not sure if this problem was ever resolved, but I’m trying to accomplish something similar.

I’m trying to sort the instances on a Flex Repeater based on a parameter value in DESC order, but the instances are being populated by a query. I can’t add the values from the parameter into the query because it is a live tag value. I’m sure this is extremely simple for software engineers, but I’m not fluent in scripting.

I have been trying to fix this problem for almost a week at this point. If anyone can suggest what I may be doing wrong, I would greatly appreciate it.

Hello,

Use a script transform here to iterate through the data and order it how you need. Can you send an example of your data to be sorted?

Hi @franklepkowski. Thanks for the reply. I really appreciate it.

I have a flex repeater that needs to show station info, then be sorted based on the state of the station.

I linked the instance prop on flex repeater to a query (see below).
SELECT station_number
FROM stations
WHERE station_number > 0

That is populating everything perfectly. The other part is I need to sort these based on the state. I want all faulted stations to be at the bottom.
0 = Off
1 = Auto
2 = Fault

I can't access that data it seems like so I am at a loss on how I would do anything with it.

You will just need to implement @kgamble suggestion and add the return sorted() to your scripting transform.

@mitchell-ACS - I would do that but I can't access the data. My query is only returning the name, not the state. I can't access the state within the query because it's a tag value.

You'll need to add a script transform to your binding and iterate through the query results to get the tag value for each station. It would be like something like this, assuming query results are returned as a dataset. You can then sort this new dataset as above.

Something else you may want is to create a custom property on your view to refresh this binding on state tag change... assuming you want the instance order to update when a station goes into/out of fault state

statusCol = []
for row in range(value.getRowCount()):
	stationNumber = value.getValueAt(row,'station_number')
	tagPath = 'stationStatus_'+stationNumber #your tag path goes here, assume its parameterised with station number
	status = system.tag.readBlocking(tagPath)[0].value
	statusCol.append(status)

newDataset = system.dataset.addColumn(value,0,statusCol,'status',int)
5 Likes

@amy.thompson - Thank you so much! I think what was causing me the issues was how I was returning the data. I thought I tried the various types but apparently not. That you again so much!

Hi All,
in my case the returned value is a dataset format, but the expected property seems to be a json format in order to be populated correctly. The property complains as follow "string found, array expected". Thus, I was trying to convert the resulted dataset to json (with system.util.jsonEncode function), but it is not successful. Do you have any idea how do I deal with ?
Any help would be appreciated. Thanks.

It expects an array of objects, which is not json, but looks very similar.

In any case, jsonEncode and jsonDecode deal with converting json to string and string to json. Nothing to do with datasets.
This explains the error you got, mentioning string.
Note also that this error pretty much tells you what I've said so far.

Here's a screenshot of what it expects:
image

instances is an array, and each element in it (0, 1, 2) is an object.
In python, that's a list of dicts.

So, you'll need to use a script transform, to transform your data into a list of dicts.

First, let's suppose your dataset has columns that match the parameters expected by the repeated view.
This makes things somewhat easier, I'd do something like this:

def transform(self, value, quality, timestamp):
	headers = value.getColumnNames()
	data = system.dataset.toPyDataSet(value)
	return [dict(zip(headers, row)) for row in data]

Here's what's going on:

  • get the column names, as those will be the keys of our dicts
  • transform the dataset into a pyDataset, more convenient to use
  • make (and return) a list of dicts, constructed from the values in headers (our keys) and the values in each row of data

Another way of doing it, which will be needed in case the columns names don't match the parameters names, and that might be a bit easier to follow:

def transform(self, value, quality, timestamp):
	data = system.dataset.toPyDataSet(value)
	return [
		{
			'paramfoo': row['foo'],
			'parambar': row['bar']
		} for row in data
	]

Here, we construct the dicts manually, by specifying the parameter name expected by the view, and give them the value in one of the column, for each row in data.

This should be enough to get your repeater going, but if you need more info about the details, feel free to ask.

2 Likes

Many thanks pascal.fragnoud for your really well explanation. It has been very useful! TKS.

Hi Everyone
This link has been really helpful. After doing everything I have a dataset that works. Only thing remaining is for it to refresh and sort asper the live status update. How can we refresh the script to be up to date with every status change.

Thanks,

If you followed the instructions I gave, you don't have a dataset, but a list of objects.

What status change ? What should trigger a refresh ?
Usually, you'll update data in 2 ways:

  • bindings. They're reevaluated whenever the source changes
  • manual refresh with refreshBinding. This is usually used for manual refreshes, like button clicks, or specific events like message handlers receiving a message.

You'll have to provide more details if you want more help.

Hi @pascal.fragnoud
I couldn't get your concept because we want to check the status of the tag1,tag2..tag(n), based on that display order need to be re-arranged.
Please give me your suggestions Thanks.

You'll need to be more specific about what you want to do.
I suggest you create a new thread and explain your issue there, with as much details as possible.

Sure I will do that.