Dynamically Change/Animate Docked View Handle Icon

New page, new Dock configuration. Altering the Docked View only changes the current Docked View configuration for your current page. Navigating to a new Page results in that page loading its own configuration.

Ok. So it reverts back to the shared settings set on the page configuration. Does the dock re-open when the new page is loaded?

If the new page has the Docked View set to be visible, the Docked View should expand during (after) the navigation process. If the Docked View is expanded before the navigation but onDemand is the Display type, then it will collapse.

The docked view is a shared dock, inherited by all pages. Didn't know each page could set the dock's display property.

If the properties all revert back to the shared settings, this alterDock function isn't particularly useful.

The settings are inherited by each page, and can be overridden by manually placing a new Docked View configuration on a given page which uses the same View. When a Page starts up, it uses the inherited configuration. There's no static/running definition for a Docked View between pages; each Page starts with a fresh Docked View based on the configuration defined int he Designer.

Ok, I think I've got a new direction to go here then. How can I get a session prop into the Page Startup script?

page.session.props.XXXX

Error says "session" is not defined.

def onPageStartup(page):
	westDock.setProps(page.session.custom.dock_behavior)

Could you post the stacktrace? I have a working example we use for testing which utilizes such a reference.

def onPageStartup(page):
	if page.props.path == '/events/session/pagestartup':
		page.session.custom.page_obj.page_id = page.props.pageId
		page.session.custom.page_obj.path = page.props.path
		page.session.custom.page_obj.session_id = page.session.props.id
		page.session.custom.page_obj.invocation_count = page.session.custom.page_obj.invocation_count + 1
com.inductiveautomation.ignition.common.script.JythonExecException
Traceback (most recent call last):
  File "<function:onPageStartup>", line 2, in onPageStartup
NameError: global name 'session' is not defined

	at org.python.core.Py.NameError(Py.java:261)
	at org.python.core.PyFrame.getglobal(PyFrame.java:265)
	at org.python.pycode._pyx65.onPageStartup$1(<function:onPageStartup>:2)
	at org.python.pycode._pyx65.call_function(<function:onPageStartup>)
	at org.python.core.PyTableCode.call(PyTableCode.java:173)
	at org.python.core.PyBaseCode.call(PyBaseCode.java:306)
	at org.python.core.PyFunction.function___call__(PyFunction.java:474)
	at org.python.core.PyFunction.__call__(PyFunction.java:469)
	at org.python.core.PyFunction.__call__(PyFunction.java:464)
	at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:846)
	at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:828)
	at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.runFunction(ProjectScriptLifecycle.java:832)
	at com.inductiveautomation.ignition.common.script.ScriptManager$ScriptFunctionImpl.invoke(ScriptManager.java:1009)
	at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$AutoRecompilingScriptFunction.invoke(ProjectScriptLifecycle.java:897)
	at com.inductiveautomation.perspective.gateway.script.ScriptFunctionHelper.invoke(ScriptFunctionHelper.java:147)
	at com.inductiveautomation.perspective.gateway.script.ScriptRunner.run(ScriptRunner.java:23)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
	at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at com.inductiveautomation.perspective.gateway.threading.BlockingWork$BlockingWorkRunnable.run(BlockingWork.java:58)
	at java.base/java.lang.Thread.run(Unknown Source)
Caused by: org.python.core.PyException
Traceback (most recent call last):
  File "<function:onPageStartup>", line 2, in onPageStartup
NameError: global name 'session' is not defined

	... 22 more

Ignition v8.1.23 (b2022121308)
Java: Azul Systems, Inc. 11.0.16.1

def onPageStartup(page):
	westDock.setProps(page.session.custom.dock_behavior)

westDock project script:

def setProps(dock_strategy):

	target_dock_id = 'nav'
	auto_dock_props = {'handle':'autoHide', 'display':'onDemand'}
	manual_dock_props = {'handle':'show', 'display':'visible'}

	if dock_strategy == 'auto':
		target_dock_props = auto_dock_props
	else:
		target_dock_props = manual_dock_props
		
	system.perspective.alterDock(target_dock_id, target_dock_props)
	system.perspective.openDock(id=target_dock_id)
	

If I pull it out of the function call it seems to work ok:

def onPageStartup(page):
	dock_strategy = page.session.custom.dock_behavior
	westDock.setProps(dock_strategy)

However, it still doesn't seem to fire for every page. If I use this script on a view's onStartup script it does work. However, even then it doesn't work as expected.

That's not the error I would expect to see based on the code you provided. Did you save before you tried what I supplied?

That stacktrace would be what I would expect if you had something like this, because nowhere before that line was session defined:

def onPageStartup(page):
    session_id = session.props.id

To verify, I just ran the following code myself without issue:

def onPageStartup(page):
	sessionId = page.session.props.id
	system.perspective.print(sessionId)
    system.perspective.print(session.props.id)

and got the following stacktrace:

Error running page.onPageStartup(page): Traceback (most recent call last): File "<function:onPageStartup>", line 4, in onPageStartup NameError: global name 'session' is not defined

What you're hitting here is an unfortunate terminology issue which I see all of the time and which I FULLY understand.

the onPageStartup script fires one time when you open Perspective Page in a tab. It does NOT fire every time you perform page navigation. Watch the pageId during the life of your session; the pageId does not change as you navigate between pages because what's really going on is we're just swapping out the View on the back-end and applying any rules from the Page Configuration.

Reverting back to westDock.setProps(page.session.custom.dock_behavior) now it does work without the error, so not sure what was going on there. I know I had been saving frequently to test things, but I guess that could've been the issue.

However, it's still not quite working for me.

Ok, so how can I get the dock to alter every time I change views?

I did get it to work by manually adding the script

westDock.setProps(self.session.custom.dock_behavior)

to every view's onStartup script. Just wish there was a nicer way to do it. And even then, navigating back to the page you're already on still auto-closes the dock.

I understand where the confusion came in: it's page.onStartup() vs view.onStartup()

There's not a way I'm familiar with to do that, aside from editing the onStartup Event of each individual View.

One way you could manage this which is not the "best" solution is to have a timer script for your project which periodically broadcasts a Message. Then, in your Docked View, configure a listener for this message. When the Docked View hears the message, invoke alterDock based on some criteria, like page dimensions, or device type.

Was thinking maybe I'd call my westDock.setProps() function from the docked view when the menu tree is clicked, but this must execute before the view is actually changed.

And my call to system.util.invokeLater() says invokeLater doesn't exist. Has it been removed?

No, it has not. What's the exact stacktrace?

It is only available in Vision Client scope.

1 Like

com.inductiveautomation.ignition.common.script.JythonExecException
Traceback (most recent call last):
  File "<function:runAction>", line 2, in runAction
AttributeError: 'com.inductiveautomation.ignition.common.script.Imm' object has no attribute 'invokeLater'

	caused by org.python.core.PyException
Traceback (most recent call last):
  File "<function:runAction>", line 2, in runAction
AttributeError: 'com.inductiveautomation.ignition.common.script.Imm' object has no attribute 'invokeLater'


Ignition v8.1.23 (b2022121308)
Java: Azul Systems, Inc. 11.0.16.1

Dang. I see that in the documentation now