# How to avoid using a Timer to delay an action in the UI

**URL:** <https://forum.inductiveautomation.com/t/how-to-avoid-using-a-timer-to-delay-an-action-in-the-ui/108776>\
**Category:** Ignition\
**Tags:** perspective\
**Created:** [July 22, 2025, 3:19pm UTC](https://forum.inductiveautomation.com/t/how-to-avoid-using-a-timer-to-delay-an-action-in-the-ui/108776 "2025-07-22T15:19:50Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ryan\_Deardorff](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ryan_deardorff/32/63815_2.png) [@Ryan\_Deardorff](https://forum.inductiveautomation.com/u/Ryan_Deardorff)\
**Post date:** [July 22, 2025, 3:19pm UTC](https://forum.inductiveautomation.com/t/how-to-avoid-using-a-timer-to-delay-an-action-in-the-ui/108776/1 "2025-07-22T15:19:50Z")

</div>

I sometimes find myself resorting to use of a `Timer` to delay a UI action that I can't get to work otherwise, and it seems like a hack that I shouldn't have to be doing, and wonder if there's another way that I'm missing. Here's the latest example...

I have a text field that is in a hidden flex container. When a checkbox is checked, this container's visibility is toggled so that the text input becomes visible. At that point, I want the text input to become focused. When I try a simple `onChange` script on the visibility of the container, and call `.focus()` on the input, it doesn't work, I'm assuming because while the visibility property itself has become true, the effect of that change has yet to cause the input to be displayed, and so it isn't yet capable of accepting focus. When I add a slight (and entirely arbitrary) delay, it does work:

```python
def valueChanged(self, previousValue, currentValue, origin, missedEvents):
	from threading import Timer
	
	def focus(self):
		self.getChild("User ID").focus()
	
	if currentValue is not None and currentValue.value:
		Timer(0.2, focus, [self]).start()

```

My use of this is usually related to the [lack of an `onLoad` event](https://ideas.inductiveautomation.com/ignition-features-and-ideas/p/perspective-view-onload-event-that-fires-when-the-view-is-done-loading) that can fire when a view is finished loading, but in this case, it's in response to a simple user interaction, and feels especially hacky.

---

<div class="post-metadata">

**Author:** ![jvance](https://avatars.discourse-cdn.com/v4/letter/j/59ef9b/32.png) [@jvance](https://forum.inductiveautomation.com/u/jvance)\
**Post date:** [July 22, 2025, 5:29pm UTC](https://forum.inductiveautomation.com/t/how-to-avoid-using-a-timer-to-delay-an-action-in-the-ui/108776/2 "2025-07-22T17:29:43Z")

</div>

I'm wondering if you could use an `if` statement for this purpose... I've never tried before in ignition but could you possibly open a loop that releases when the component returns?  
Like this:

```python
if self.getChild("User ID"):
   #break loop and call .focus()
else:
   #continue loop

```

Let me know if this works out for you because I've had this issue in the past.

---

<div class="post-metadata">

**Author:** ![Ryan\_Deardorff](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ryan_deardorff/32/63815_2.png) [@Ryan\_Deardorff](https://forum.inductiveautomation.com/u/Ryan_Deardorff)\
**Post date:** [July 22, 2025, 5:59pm UTC](https://forum.inductiveautomation.com/t/how-to-avoid-using-a-timer-to-delay-an-action-in-the-ui/108776/3 "2025-07-22T17:59:35Z")

</div>

I'm pretty sure `self.getChild("User ID")` will always return True as it only tests the existence of the component, not its visibility or potential to receive focus. I did add a system print that confirms this is the case when the visibility `onChange` event fires.

But even if there were a way to check for the appropriate state, a loop like you suggest would block execution of other scripts/events, unless you put in a `sleep`, which is no better than using a `Timer`.

---

<div class="post-metadata">

**Author:** ![tgarrison](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/tgarrison/32/80965_2.png) [@tgarrison](https://forum.inductiveautomation.com/u/tgarrison)\
**Post date:** [July 22, 2025, 6:56pm UTC](https://forum.inductiveautomation.com/t/how-to-avoid-using-a-timer-to-delay-an-action-in-the-ui/108776/4 "2025-07-22T18:56:01Z")

</div>

How about putting the focus call on the OnChange for the visibility property itself? When it goes true, it would then call focus to itself? (I haven't tested this)

---

<div class="post-metadata">

**Author:** ![Ryan\_Deardorff](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ryan_deardorff/32/63815_2.png) [@Ryan\_Deardorff](https://forum.inductiveautomation.com/u/Ryan_Deardorff)\
**Post date:** [July 22, 2025, 7:05pm UTC](https://forum.inductiveautomation.com/t/how-to-avoid-using-a-timer-to-delay-an-action-in-the-ui/108776/5 "2025-07-22T19:05:47Z")

</div>

That's basically what I'm doing, only it's the visibility of the parent container of the input, not the input itself. Its visibility is always True, and wouldn't trigger a change script. I tried making the toggle be its visibility instead of its parent, but got the same results.

---

<div class="post-metadata">

**Author:** ![tgarrison](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/tgarrison/32/80965_2.png) [@tgarrison](https://forum.inductiveautomation.com/u/tgarrison)\
**Post date:** [July 22, 2025, 7:32pm UTC](https://forum.inductiveautomation.com/t/how-to-avoid-using-a-timer-to-delay-an-action-in-the-ui/108776/6 "2025-07-22T19:32:57Z")

</div>

Odd. Just tested it, and yeah.. it needs a slight forced delay. I even tried chaining a couple props together to "build" a delay, and it still didn't work.

---

<div class="post-metadata">

**Author:** ![djs](https://avatars.discourse-cdn.com/v4/letter/d/e47774/32.png) [@djs](https://forum.inductiveautomation.com/u/djs)\
**Post date:** [July 22, 2025, 8:10pm UTC](https://forum.inductiveautomation.com/t/how-to-avoid-using-a-timer-to-delay-an-action-in-the-ui/108776/7 "2025-07-22T20:10:29Z")

</div>

Could you do an `onStartup` script on your text input that checks for the condition and focuses itself, as well as an `onActionPerformed` on the checkbox that focuses the text input if checked? Wouldn't these cover all your bases?

---

<div class="post-metadata">

**Author:** ![Ryan\_Deardorff](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ryan_deardorff/32/63815_2.png) [@Ryan\_Deardorff](https://forum.inductiveautomation.com/u/Ryan_Deardorff)\
**Post date:** [July 22, 2025, 8:25pm UTC](https://forum.inductiveautomation.com/t/how-to-avoid-using-a-timer-to-delay-an-action-in-the-ui/108776/8 "2025-07-22T20:25:13Z")

</div>

`onStartup` is not when I want it to be focused, but even if it was visible from the outset, this would not reliably work to focus it, since that event fires before the view finishes rendering (see [my request for an `onLoad` event](https://ideas.inductiveautomation.com/ignition-features-and-ideas/p/perspective-view-onload-event-that-fires-when-the-view-is-done-loading)).

I tried `onActionPeformed` but that doesn't work, either. I figured it wouldn't since it happens at about the same time as (probably even before) the `onChange` event that I'm placing on the visibility.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [July 22, 2025, 11:16pm UTC](https://forum.inductiveautomation.com/t/how-to-avoid-using-a-timer-to-delay-an-action-in-the-ui/108776/9 "2025-07-22T23:16:46Z")

</div>

You are trying to find a magic wand that resolves the disconnect between jython code running in the gateway and rendering occurring in the browser. Consider using Ben Musson's module to send javascript that both sets the visibility and performs the focus **in the browser**.

---

<div class="post-metadata">

**Author:** ![Chris\_Bingham](https://avatars.discourse-cdn.com/v4/letter/c/e5b9ba/32.png) [@Chris\_Bingham](https://forum.inductiveautomation.com/u/Chris_Bingham)\
**Post date:** [July 23, 2025, 12:31pm UTC](https://forum.inductiveautomation.com/t/how-to-avoid-using-a-timer-to-delay-an-action-in-the-ui/108776/10 "2025-07-23T12:31:26Z")

</div>

Workaround:  
Can you change your enablement logic to utilize other Styles? Either: 1) always show the object(s), albeit in a disabled state (greyed out, etc), 2) Utilize a style which permits events (leave `visibility: true`, instead change `opacity: 0`).

---

<div class="post-metadata">

**Author:** ![dkhayes117](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/dkhayes117/32/68344_2.png) [@dkhayes117](https://forum.inductiveautomation.com/u/dkhayes117)\
**Post date:** [July 23, 2025, 1:21pm UTC](https://forum.inductiveautomation.com/t/how-to-avoid-using-a-timer-to-delay-an-action-in-the-ui/108776/11 "2025-07-23T13:21:25Z")

</div>

The disabled state gives the same issue, though the opacity hack should work.

---

<div class="post-metadata">

**Author:** ![Ryan\_Deardorff](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ryan_deardorff/32/63815_2.png) [@Ryan\_Deardorff](https://forum.inductiveautomation.com/u/Ryan_Deardorff)\
**Post date:** [July 23, 2025, 1:53pm UTC](https://forum.inductiveautomation.com/t/how-to-avoid-using-a-timer-to-delay-an-action-in-the-ui/108776/12 "2025-07-23T13:53:21Z")

</div>

Good thinking, it does work when I use `opacity` instead of `visible`. I'm going to mark @pturmel's response as the solution, though, since it explains the fundamental issue. This solution is still a slight hack, but much better than using a `Timer`.
