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?
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ā))
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)
@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:
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 apyDataset
, 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 ofdata
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.
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.