I am trying to figure out how to dynamically add instances to a flex repeater in a Perspective View.
I've not seen much in the way of how to do this, but the one thread seemed to indicate there may be a bug in the functionality or not yet added functionality. Link
I did use the tolist() method to print the content of my one instance (manually entered) to the system log. This is what that looked like:
QV[{displayVal=[value, Good_Unspecified, Wed Dec 31 18:00:00 CST 1969 (941)], instancePosition=QV[{}, Good_Unspecified, Wed Dec 31 18:00:00 CST 1969], instanceStyle=QV[{classes=[, Good_Unspecified, Wed Dec 31 18:00:00 CST 1969 (941)]}, Good_Unspecified, Wed Dec 31 18:00:00 CST 1969]}, Good_Unspecified, Wed Dec 31 18:00:00 CST 1969]
I'm not sure what to make of that output!
The actual Instance of the Flex Repeater looks like the attached image.
So, how can a script be used to add instances to a Flex Repeater? What about SQL Queries, would they have to be wrapped in a script or is there a way to directly populate instances using queries? What other ways are there to dynamically populate these?
Here’s what I ended up doing to programatically add instances; I run this in a message handler on my FlexRepeaters.
# Check if the instances list is empty.
# If the instances list is empty, create a new list. Otherwise, load the current list.
if (self.props.instances == None):
currentInstances = []
else:
currentInstances = self.props.instances.tolist()
newInstance = {
# Put your instance properties here.
}
currentInstances.append(newInstance)
self.props.instances = currentInstances
Rather than directly manipulating the query into the right output format, you would probably be best served with a script transform that takes the query output and manipulates it into the required shape.
Also, regarding the odd script output and (imo) weird behavior of tolist, I actually just submitted changes yesterday that make the property trees much more friendly to script around; for instance, you can just directly append() a dictionary to them, and it will automatically wrap it into the required shape.
Could you please elaborate on the changes you submitted, and specifically how this will help with dynamic instance creation for the view canvas in perspective?
This was almost 2 years ago, but basically property trees pretend to be native Python data structures much better now - you can use standard Python dictionary methods on them, update them with the values from standard python dictionaries, etc. So you don’t (in theory) need to use any hidden conversion methods - you just make the dictionary form of whatever properties you want, then directly return it from your transforms/etc.
Thank you for getting back with me. I don’t quite understand how to reference the instance properties of the view canvas in the dictionary. Does the path to a particular property go on the left side of the colon in a dictionary entry?
So, what I would generally recommend doing is binding instances (the root property) to whatever your dynamic data source is (if you have one) - your query, tag, property, whatever. Then add a script transform to it, which returns that list of dictionaries with the right property ‘shape’ for the view canvas:
return [
{
"position": "relative",
"top": str(i * 100) + "px",
"viewPath": "inner",
"viewParams": {
"label": name
},
"left": "0px",
"bottom": "auto",
"right": "auto",
"zIndex": "auto",
"width": "auto",
"height": "auto",
"style": {},
}
for i, name in enumerate(value)
]
In this case my script is obviously not doing a whole lot, because my input array is very simple, but if you had a query binding bringing in a dataset you’d likely have a lot more parameters to pass in.
My Input Array is the Dynamic one. I used the Canvas Template Repeater in Ignition. Here is the code I used during startup the windows.
# get the numbers of the Interlocks for the each type
intlresults = system.tag.browse(mtrpath+'/Interlocks', {'typeId': 'PointType/AcesysV8INTL'})
intlcount = intlresults.getReturnedSize()
# Interlocking Title
if intlcount > 0:
row = ['INTLTitle','Title','{"TitleText":"Interlocking"}','0','0','0','0','Wrap','0']
intldata.append(row)
# Interlocking Data
for intlresult in intlresults.getResults():
intlfullpath = intlresult['fullPath']
dummyintl = dummyintl + 1
intlparam = '{"Tag_Path":"' + str(intlfullpath) + '"}'
intlname = 'INT' + str(dummyintl)
row = [intlname,"Interlock",intlparam,"0","0","0","0","Wrap","0"]
intldata.append(row)
like this I have more data then finally
# Finally Set the pydataset to Canvas Template dataset
system.gui.getParentWindow(event).getComponentForPath('Root Container.Interlock Container.Interlock Canvas').templates = system.dataset.toDataSet(intlheaders,intldata)
I am trying to convert this code to the perspective. Here intlcount is the dynamic one. I am trying to find the tag path of the specified UDT type and binding to the canvas.