Change Script Focus in 8.3

Title: Ignition Perspective 8.3 – self.focus() works from button events but not property change or startup scripts

I'm using Ignition 8.3 (Perspective) and trying to automatically set focus to a Text Field when an Embedded View loads.

The Text Field is the first input in a four-digit authentication screen. Ideally, when the operator navigates to this screen, the cursor should automatically be placed in the first field so they can immediately begin entering their code.

I'm using the documented focus() method:

self.focus()

I've tested several approaches with the following results:

  • Button onActionPerformed: Works correctly.

  • Button onMouseEnter: Works correctly.

  • Text Field onStartup: Does not focus the field.

  • Property-change script: Executes, but does not focus the field.

  • Message handler: Executes, but does not focus the field.

I also have a reset function that clears all four inputs and calls focus() on the first field. When invoked from a button, both the reset and focus work. When invoked from a property-change script, the inputs reset correctly, but focus is never applied.

I've confirmed the component path is correct, and the scripts are executing using print statements.

This initially appeared to be an Embedded View loading/timing issue, but I've also been unable to get automatic focus working when testing the authentication view independently.

Has anyone successfully used self.focus() from a property-change script or onStartup event in Ignition Perspective 8.3?

Is this a known limitation related to the event context or browser rendering, or is there a recommended way to automatically focus a Text Field after a view loads without requiring user interaction?

Any suggestions would be appreciated!

See the browser constraint discussed here:

Unfortunately there is no onLoad event yet that can be used to trigger such things once every part of a view is finished rendering, which is often necessary for things like .focus() to work. There is a request for it that one can vote for:

In lieu of that, I have often found the easiest way to ensure focus happens when I want it to is to use time.sleep():

import time

def focusMe():
	time.sleep(0.5)
	self.focus()
	
system.util.invokeAsynchronous(focusMe)

Always use system.util.invokeAsynchronous() when using .sleep(), because it blocks the thread that it runs on. It's a hack that uses an estimate of how much time will be required for the view to finish loading, and is not ideal, so if you can figure out another event that would invoke it at the right time, then do that.

I saw the topic you referenced while I was troubleshooting. I tried to implement focusing on a parent but wasnt sure if I was implementing correctly and didnt make progress. My text field is in flex containers root>Main>Code and has name digit_1. Tried setting focus on each in turn to get down to my text field but got errors about None types. That's when I created my topic here.