How to set focus on a new input

I have multiple text inputs, only one of which is editable at a time. The input is visible only when being edited, otherwise it is replaced with styled text. I seem to be unable to set focus on the text input after it is first created. I have tried several suggestions I have found on the web, but none of them have seemed to work.
FWIW, I’m building the same app with React, Vue, and now Aurelia. It appears Aurelia holds the most promise, but is the hardest to learn…

1 Like

Is this v1 or v2?

how are you doing this at the moment?

I seem to be unable to set focus on the text input after it is first created

Note that if there’s binding involved in the input creation, it may take a tick or a frame to have the input rendered (attached to the document), before you can focus on it.

Thanks.
I’m using v1

My simplified class in Typescript is:

export class TextInput {
    @bindable user_puzzle_entry_state: UserPuzzleEntryState
    hasFocus: boolean
    bind(bindingContext: Object, overrideContext: Object) {
        this.hasFocus = (this.user_puzzle_entry_state.state === "input")
    }
    user_puzzle_entry_stateChanged() {
        this.hasFocus = (this.user_puzzle_entry_state.state === "input")
    }
}

And the simplified HTML is:

<input type="text" focus.bind="hasFocus" value.bind="user_puzzle_entry_state.text" input.delegate="onAnyInput($event)" change.delegate="onInputChange($event)" keydown.delegate="onkeydownEndIfEnter($event)" blur.trigger="deactivateCharInput()" />
1 Like

i’m pretty sure it has to do with timing, had a similar situation once. try wrapping the focus set inside a setTimeout to force it onto the next macro task

1 Like

@zewa666 Thanks. Your suggestion allowed me to set the focus appropriately.

Here are my changes:

I replaced the this.hasFocus = ... lines with: this.setFocusDelayed()
and added :

    setFocusDelayed() {
        setTimeout(() => {
            this.hasFocus = (this.user_puzzle_entry_state.state === "input")
        },5)
    }

I don’t know the Aurelia internals yet, so I picked 5ms.

1 Like

@bigopon Thanks. Your suggestion helped.
But I don’t understand what a “frame” is. Can you please explain?

1 Like

Unfortunately, although this appears to have solved the focus problem, it is not working in every case.
This an example of why I said: “(Aurelia) is the hardest to learn…”

And now I realize I’m also having a problem with setting blur(), it only seems to work sometimes.

1 Like

Hello @psnider! Instead of using a setTimeout try setting the focus flag inside the attached lifecycle hook instead of bind. If it still does not work, can please share an example app (you may choose to do so using https://gist.dumber.app/).

1 Like

I created a Dumber Gist at: Focus & Blur not working as hoped
I hope this helps. If you click multiple times on the two text areas: “a” and “z”,
you should see the problems within a few clicks.
Using the Dumber Gist, I experience both focus and blur problems within three or so clicks.

The symptoms are:

  • eventually both input fields will be active at the same time (blur not handled correctly)
  • sometimes the insert cursor is not present in a text input field (focus not handled correctly)

Thanks for your help and time.

1 Like

BTW, this is the first time I tried something like Dumber Gist.
The documentation was lacking on the github repo,
but just working through it on the Dumber Gist site was a pretty decent experience.
Dumber Gist is really helpful!

1 Like

I have tried your code. The desired effect requires the following change.

diff --git IdTextEntryInput.ts

deactivateCharInput() {
  console.log("deactivateCharInput()")
+ this.hasFocus = false;
  this.ea.publish(new AuMsgTextEntryStateChanged(this.div_id, "display"))
}

Because you are setting the focus based on the hasFocus, and as between the detachment and re-attachment of the CE there is no change of that state, it seems that the focusing of the input was not working as expected.

3 Likes

Yes, of course, thank you.
Somehow I was thinking that focus and blur are not managed by my app, but by the browser.
So I overlooked that this state would push the UI do odd things, and that I needed to reset it myself.

I appreciate your time to investigate and share your results.

2 Likes