React Focus on an Input Field

Hi,

First thing, pardon on the title of this post for I can't find a better title for it.

Anyway, I have two IFs on the screen showing a different set of form. Just imagine it as a wizard type form that users need to fill in. These IF are controlled by a variable StepNumber to show or not. Then I have this screen action when the Save button on the first form is clicked:

One minor requirement is to set the focus to the Input box on the next form. The JS fuction on that Focus client action is working perfectly. Its just that in this case, it seems that when the StepNumber gets updated, the screen does get updated yet in time for the Focus action to pick up. Which means, that the Input that needs to be focused is null or net yet rendered.

Thoughts?

Thanks,

JC

Is this a Mobile or Reactive Web app?

What's the code for the Focus client action look like?


Hi JC,

If I’m not mistaken, the screen is only rendered at the end of the flow or when there is something asynchronous happening, like a server action. A possible workaround there is to do a JavaScript with single $resolve() statement before setting the focus, not sure if that would work. Maybe that focus action should be changed to include that. 

Cheers,

Tiago Simões

G. Andrew Duthie wrote:

Is this a Mobile or Reactive Web app?

What's the code for the Focus client action look like?


just this:

document.getElementById($parameters.ElementId).focus();


Tiago Simões wrote:

Hi JC,

If I’m not mistaken, the screen is only rendered at the end of the flow or when there is something asynchronous happening, like a server action. A possible workaround there is to do a JavaScript with single $resolve() statement before setting the focus, not sure if that would work. Maybe that focus action should be changed to include that. 

Cheers,

Tiago Simões

Hi Tiago,

I am sorry but I don't know how to implement this :)

I tried a more conventional approach but didn't work as well:

When this is on OnReady, it only works on the first render. Meaning if I flip back and forth to the different web block (defined by the stepnumber), it doesn't work anymore. If I do this on OnRender, it always sets focus on the field even if you are typing on another one.


Hi JC,


You have 2 options:

1- Using the autofocus extended attribute or



2- Use the $resolve() built-in function to trigger a render


Cheers,

Tiago Simões

Hi Tiago,

Not sure if it is just mine but the images doesn't load?

Thanks,

JC

Solution

Hi JC,

Maybe try with a different browser?
option 1 - add a “autofocus” attribute to the inputs with the value True or

option 2 - on the JavaScript add a “$resolve();” line before the line to set the focus

Solution

Hi Tiago,

The $resolve(); worked.

Question is, can I add this safely on my reusable focus JS?

Regards,

JC

Yes, that will make your JavaScript generated code to be compiled with promises and it will render the screen immediately when the data changes. 

The only downside is that if you use $resolve() you will not be able to use that inside functions, but I'm provably there will be no use cases to set the focus inside a function.

Well the only use case I have is this:



Edit: I removed it eventually. When I did it, OutSystems complained with my OnReady events that calls the Focus action:

Performance Suggestion
'OnReady_FocusInput' contains accesses to the local storage or server, which delays the screen's render. To avoid performance issues, use Aggregates or Data Actions instead.

Hi Juan Carlos,

You can safely ignore those warnings in the OnReady. 

Accesses to server on the in OnInitialize delay the render, the ones in OnReady do not. That warning was there also to teach developers transitioning from Traditional Web not to abuse these events to be used like Preparations. But that one about OnReady we'll probably remove it in the future.

Cheers,
Tiago Simões

Hi Juan,

Alternatively you can encapsulate the $ready() on a separate client action (e.g. called RenderScreenImmediatly) and only call that in client actions that do not call the server and you need to trigger a render before the end of the action. On the OnReady you would not need to call that action.

Cheers,
Tiago Simões

Tiago Simões wrote:

Hi Juan,

Alternatively you can encapsulate the $ready() on a separate client action (e.g. called RenderScreenImmediatly) and only call that in client actions that do not call the server and you need to trigger a render before the end of the action. On the OnReady you would not need to call that action.

Cheers,
Tiago Simões

The reason why I did put it on the OnReady is because it just happens once when I instantiate the block on the screen. Other few cases are when I have multiple steps inside the block that goes forward or backward that I need to focus on an input in that form.

test

Other than this example, I am not sure when to put that RenderScreenImmediately other than the OnReady. I guess I will just wait for that "But that one about OnReady we'll probably remove it in the future."

Thanks!