Flex Repeater - Make Dynamic

I am working with perspective and using the flex repeater. I am using a simple query to return some values from a database. These values are then intended to be passed to the various instances of the flex repeater. I watched the demo in Ignition U on setting this up. I can follow that instruction but it pretty much breaks the page if I do so. I think when I bind to my query, I am killing the new instanceStyle, instancePosition items that were added in Ignition 8.0.3. I think this because I can manually create each instance and the flex repeater works fine. But, of course if I do this, the repeater is no longer dynamic which is kinda the point of using it.

How would I go about applying my custom params for each instance via a query without destroying the new instanceStyle and instancePosition items? I have been playing around with python and trying various things, but I am not exactly sure what I should be providing to create the instances via scripting.

1 Like

I usually change my query return format to json, which allows me to do things like this as part of a script transform:

instances = []  # variable can be called anything, as long as the return variable name matches; I just like to have my variable names match what I'm expecting back
for entry in value:
    instance = {}
    instance['param_one'] = entry['id']
    instance['param_two'] = entry['pressure']
    instance['volume'] = entry['volume']
    instances.append(instance)
return instances

if you want to include instanceStyle and instancePosition, just make sure to include them as part of the script transform:

instances = []
for entry in value:
    instance = {}
    instance['param_one'] = entry['id']
    instance['param_two'] = entry['pressure']
    instance['volume'] = entry['volume']
    instance['instanceStyle'] = {'classes': None}
    instance['instancePosition'] = {}  # or put some value in as part of the script
    instances.append(instance)
return instances
2 Likes

I will give this a try. I did use the json format and was going down the road you outline, but was not quite there.

Do you know if the instanceStyle and instancePostion are required (vs optional) to make the Flex Repeater work correctly? It seemed to me without those items the embedded view I was using simply would not display correctly. It would not resize and everything looked very bad with it. If I manually created the parameters then the embedded view worked quite nicely.

I tried this and am having no luck at all. If I just use your example script following my query, I get errors about the array indices needing to be integers.
If I drop the params from the script and just include the two that I need (instanceStyle, instancePosition) the script is ok but returns an empty list. I know the query is in json format and I can see all the data inside of it on the binding preview. I need to preserve the parameter created by the query and add these to into it. What am I missing here?

As another note, I even tried to create the parameters (instanceStyle, instancePosition) by creating some dummy return columns in the query. That similarly returned an empty list following the transform.

That’s because my example was half-baked and not done in an actual environment, and so it won’t work in an actual script. I’m editing it to (hopefully) work right after I post this. As to whether or not the instanceStyle and instancePosition are required - they are not.

Omit the instanceStyle and instancePosition from your query; queries shouldn’t know anything about your project or its structure - it’s on the project to make the data work, and it’s NOT on the data to make the project work.

Fair enough. The fact that they are not required is really throwing me. When I build query as demonstrated in Ignition U, I get back my data and it creates all the needed instances on the screen. But they are completely unusable. I have tried about every combination of settings but the embedded view is tiny, smashed into a one side of the other. The embedded view is a column container and it will not resize no matter what I do with the screen size.

If I delete that column container, drop it back in and do NOT include my query and manually create my instances through perspective, then everything is right with the column container. It resizes and looks right. But this, is not dynamic and I have to create all the instances and params manually.

I was assuming that this issue was being caused by the fact that when I create the query, it was not creating the instanceStyle and instancePostion as part of the instance list in perspective. If that is not the cause, then I am lost once again.

It sounds like there are several things going on here, so I'll try to break it down a little.

The Flex Repeater is going to orient your instances in a single row and expand them from the top down to whatever the View's configured defaultHeight property is set to. You can switch FlexRepeater.props.direction to "column", and then it will render your instances one on top of the other in a column, at which point the instances will span the width of the FlexRepeater, up to whatever the instanced View's configured defaultWidth is set to.

You can toggle the FlexRepeater's useDefaultWidth/Height properties; setting them to false will stretch the instanced Views to be exactly as tall/wide as the Flex Repeater. If the instanced View has a default Width which is wider than the Flex Repeater, you will get horizontal scrollbars. If the width is less than that of the Flex Repeater, the View will scale to fill the Flex Repeater.

So it sounds like you want to set FlexRepeater.props.direction to "column".
If you leave useDefaultWidth as true, then your instanced View will always be the size you originally created it at. If you set useDefaultWidth to false, then your instanced View will span the width of the Flex Repeater. If you ALSO want the instanced View to use its breakpoints to change it layout on different screens, then your FLEXREPEATER must have its width modified, otherwise the width of your instanced View will never change.

Many properties like instanceStyle and instancePosition are optional, and when you see them it's only to provide you access to some value which we've conveniently set to a default value behind the scenes.

instancePosition for example allows you to override the default settings that we MUST have in place for the FlexRepeater to even work. You'll notice that if you add a grow value to instancePosition, and assign it a value of 1, that nothing changes; that's because that property (and value) has always been there - but we allow you to override it if you'd like. Omitting instanceStyle and instancePosition will fall back to using the defaults.

I appreciate what you have put here, but it is not addressing the fact that I can make the flex repeater work perfectly as I expect so long as I manually create the instances by right clicking on the PROPS/Instances in the editor and creating a new instance. I can then click the “+” and add my custom params. These link and work just fine to their associated instances on the screen.

But, if I then bind the instances PROP to a query that returns a list of params (with the same name that I have created manually), the display becomes unusable. Should changing ONLY the instances cause the display to completely change and become unworkable? I have recreated this 5 or 6 times and it always does the same thing.

Thank you for your help.

Could you post a screenshot of how your manual creation appears when finished as well as how your binding appears when finished?

There should be absolutely no difference in functionality whether you supply values through a binding or manually, and so I’m inclined to believe that the structure of the objects in the instances property is not what is expected.

I could also help a bit more if you provide me

  1. the number of params you’re passing to each instance
  2. the desired layout (FlexRepeater in column or width? Do you want the instanced Views to use their default width/height?)
  3. how many instances

I took this to the training department because it is for my certification test. They agreed with me that the two params MUST be passed into the flex repeater to be able to display it correctly. I am having a bad time figuring out how to do that but that is my issue, I guess.

Hello, I don't know if this has been addressed or not, but I have a similar situation, I used your code to script my query, I'm trying to create conveyor instances dynamically based on a fault table and pass the conveyor number parameter in the instance

instances = []
for entry in value:
 Convy_Num = entry['Conveyor_Number']


return instances

When I tried the logic above return me an empty result , any thoughts on this?

That’s because you’re never adding anything to the instances list.
E.g.
instances.append(Convy_Num)

1 Like

Hey @cmallonee, might want to edit your code to add in the instances.append :smile:

2 Likes

You were right, I also added the prefix for the parameter

Find the code below,

headings = [“parameter”, “value”]
instances =

for entry in value:
Convy_Num = entry[‘Conveyor_number’]

  instances.append({"Conveyor_Num":Convy_Num})

return instances

I am working on what sounds like the same problem that the original poster explained. Did you (jcole) ever resolve your issue? I can't @ you since I am a new user so I don't know if you will ever see this but I tried doing all of the suggestions in this thread but like you expressed, nothing works. I am sure it is me as well since I am not a software engineer, yet I have spent days trying to make this work and still cannot. Any help would be much appreciated.

Can you describe what you're trying to do, and what doesn't work ?
If you're using a query, show the query.
If you're using scripts, show the scripts.

The more detailed your issue is, the more likely we are to be able to help you.

Yes. I have a dynamic group of equipment that I need to show specific data in for all within a flex repeater. In the view that I created to use within the flex repeater I have the name, current state, and the current flow rate. I've created 3 view params on that view also. I can manually create the instances and it displays everything ok. However, it doesn't automatically add my view params under each instance, but I can add them manually. To make the instances dynamic, I bound the instances prop to a query that returns the equipment name and returns the data in json format. When I do that, it removes the instanceStyle, and instancePosition and displays the equipment name only since the tag data can't be added to the query. That equipment name populates the view param that my path is set to in the flex repeater which shows all the various equipment views. The issue is that I need to sort them based on the current state (this tag is also a view param) which I have linked to an indirect tag binding on my view that the flex is pointing too. Since that is only receiving an input on that view, I don't have any visibility on it on my flex view and can't sort.

Please let me know if you need more detail and I greatly appreciate your help.

SELECT station_number
FROM stations
WHERE station_number > 0

This is a bit hard to follow, let's try to recap and make things simpler:

You have a flex repeater with a view that takes 3 parameters:

  • name: comes from the query on which the instances prop of the repeater is bound
  • current state: comes from a tag ?
  • current flow rate: comes from a tag ?

The views need to be sorted depending on the current state.

Am I getting this right so far ?

question:

  • What's that tag, and how do read it / compute its path ?

About the instanceStyle and instancePosition properties:
Do you NEED them ? By that, I mean different styles and positions for different instances of the view.
The repeater's style combined with styles set up in the repeated view itself are usually enough.
If not, you can add them in a script transform in your binding.
Just build a new array of dictionaries from the query's result, and add the properties you want to each of them. But I somehow doubt that that's what you really want to do.

Am I getting this right so far ? - Yes. That is correct.

question:

  • What's that tag, and how do read it / compute its path ? The view param is bound indirectly to a tag, with the property being the station_number.

About the instanceStyle and instancePosition properties:
Do you NEED them ? By that, I mean different styles and positions for different instances of the view.
The repeater's style combined with styles set up in the repeated view itself are usually enough.
If not, you can add them in a script transform in your binding.
Just build a new array of dictionaries from the query's result, and add the properties you want to each of them. But I somehow doubt that that's what you really want to do. I don't need the instanceStyle and instancePosition properties. I believe the only other property that I need is the state. If that populated as it does when I manually add an instance, I found that there is a sort function (excuse me if function isn't the correct term) I could use and probably just keep them sorted ascending.