Hi.
I want to activate a script when a page has finished loading in perspective. How can I do that? I have a parameter on the page to which I send a value. I want a script to run when the value of the parameter changes. To solve the problem I use property change script, but the script is not working correct unless the page has finished loading I have been looking into Session Events / Page Startup, but feel like the scope is limited and it is not possible to call on functions that are in the Project library. My solution now is to use a delay timer that is activated when the page starts to load, system.util.invokeAsynchronous(DelayTimer2s).
I dont think there is a way to know, since with all the embeded views and stuff getting loaded in “at random”
A delay is really bad practice.
How is it not possible for you script to work when not everything is loaded?
try using an expresssion structure binding and toggle “wait for all”
with expressions bindings to the properties of whatever component you have that is loading in seperatly
This is I believe a recurrent issue.
Maybe something with an expression binding could help ?
I think there is also something somewhere about parent loaded
that could be useful.
Then there’s the hacky way.
On the properties that need to be loaded before you run your script, you can add a script transform where you set a custom property (something like custom.thisComponentLoaded
) to true, then bind another property to all those and run your script there when everything is true.
There are drawbacks to this obviously, like messing up bi-directional bindings notably, but it can help. Sometimes.
Yea, i hate using delays, it’s a crappy solution. Maybe Expression structure binding will work.
Can explain a little more in detail what I want to do. I have downloaded from Ignition exchange a project for document management (Ignition Exchange | Inductive Automation). When I open the project, I want the current directory to change according to the parameter value i provided. Travis Cox (IA) have created a function called “def selectFolderPath(id, name, pathStr, path):” I’m trying to call this function with property change script on page input parameter, but without delay it wont work…
Please provide the code of your onchange script formated by pressintg </>
def valueChanged(self, previousValue, currentValue, origin, missedEvents):
"""
This function will be called when the value of the property changes.
Arguments:
self: A reference to the component that is invoking this function.
previousValue: The previous value, as a qualified value object.
currentValue: The new value, as a qualified value object.
origin: The origin of the property value. Possible origin values include
Browser, Binding, BindingWriteback, Script, Delegate, Session, Project
missedEvents: A flag indicating that some events have been skipped due
to event overflow.
"""
def updatePage():
import time
time.sleep(2)
selectFolderPath(1, 'Maskinkort', '0:None:Root/0:1:Maskinkort', '0/0')
if (len(currentValue.value)):
system.util.invokeAsynchronous(updatePage)
There are many functions and scripts in the project so I understand that my code may not say much …
def selectFolderPath(id, name, pathStr, path):
payload = {
"id":id,
"name":name,
"pathStr":pathStr,
"path":path
}
system.perspective.sendMessage(messageType="folder-selected", payload=payload)
system.perspective.sendMessage(messageType="document-refresh")
Not related, but instead of invokeAsynchronous()
and a time.sleep()
, you could use invokeLater()
I don’t know the selectFolderPath
function, but I don’t understand why this would depend on things being loaded, considering every argument is hardcoded… This smells weird.
whats in the message handlers?
Tried first with invokeLater, but it didn’t worked for me, maybe syntax error. It’s not in list when you press ctrl+spacebar (system.util+(ctrl+spacebar)
On tree component
def onMessageReceived(self, payload):
"""
This method will be called when a message with the matching type code
arrives at this component.
Arguments:
self: A reference to this component
payload: The data object sent along with the message
"""
self.props.selection = [payload["path"]]
self.props.selectionData = [{"itemPath":payload["pathStr"], "value":{"id":payload["id"], "name":payload["name"], "pathStr":payload["pathStr"]}}]
Property change script on “selectionData”
id = None
name = "Root"
pathStr = "0:None:Root"
selectionData = self.props.selectionData
if len(selectionData):
folder = selectionData[0]
if "value" in folder:
if "id" in folder.value:
id = folder.value.id
name = folder.value.name
pathStr = folder.value.pathStr
self.view.params.id = id
if self.view.params.selectFolder:
self.session.custom.filters.folder.id = id
self.session.custom.filters.folder.name = name
self.session.custom.filters.folder.pathStr = pathStr
ahah im guessing you send out the message before the tree is loaded…
the question is why are you using a message for this?
So i’m guessing you don’t need the whole page to be loaded, only this tree component.
edit: Same question as Victor’s, why use a message ?
Can you recap what’s going on between the param, the tree and the messages ?
aa smart, that’s probably the problem
yea i guess so
I have not coded the function “selectFolderPath” myself. I downloaded the project from exchange. The creator is Travis Cox from Inductive automation
Well yes, why do you use this function for on a property that doesnt seem to affect the outcome of it.
It seems all you want to do is set the inital selected data?
why not set it directly on the tree then?
I found a solution with your help: URL parameter - Session prop - custom property on tree component (property change script - selectFolderPath)
Thx alot for helping me!!!