Set focus on component after user interaction

I’m using Polaris. ember-cli: 6.3.1 node: 20.19.4 os: win32 x64

And I want to set the focus to a component after the user has created a tag. This is a partial code block: if you need more, please ask.

My issue is that this won’t build. Everything I’ve read says that I don’t need to import ref and that ember-ref-modifier should already be installed and part of the base ember build package.

The desired effect is when the user types in the input, and presses enter, the application builds the tag, updates the display and then the user can add another tag. This works now but I want the focus to go back to the input field so the user can just type text, hit enter, and repeat without having to click on the input field again, and again.

So there are two actual questions. One, is this even the correct approach? Two, if it is, can you give a hint as to why I’m not getting it to work?

Attempted to resolve a modifier in a strict mode template, but that value was not in scope: ref:

|
|  {{ref this.setInputElement}}
|
  @tracked inputElement = null;
  @action
  setFocus() {
    this.inputElement?.focus();
  }
  @action
  setInputElement(element) {
    this.inputElement = element;
  }

 <template>
    <div class='flex flex-wrap gap-1' ...attributes>
      <LabelValue @label='Tags' @colectomy={{true}} />
      {{#each @tags as |tag index|}}
        <TagDisplay
          @tag={{tag}}
          @onDelete={{fn this.onDelete index}}
          @color={{this.colorBar index}}
        />
      {{/each}}
      <InputText
        class='text-xs max-w-32 max-h-5'
        @onEnterKeyDown={{this.onEnter}}
        @onBlur={{this.onEnter}}
        @value={{this.newTag}}
        data-test-user-tag-editor-input
        {{ref this.setInputElement}}
      />
    </div>
  </template>

FWIW i’ve never heard this. Not that i’m a super expert and would have heard everything but… I’d fully expect to need to install the package and import the modifier.

The answer is keep it simple stupid. Make sure the element in question has a unique id. Then set focus using that id.

setFocusToInput() {

setTimeout(() => {

  // Use the unique id for the TextInput

  const elementId = 'Tag-input-field-' + this.args.encounterId;

  const element = document.getElementById(elementId);

  if (element) element.focus();

}, 100);

}

Another simple approach is to put the displayed tags into a different DOM tree, so that the input element isn’t being rerendered. Then you shouldn’t need to manage the focus at all.

It’s also possible you can avoid the need for focus management if you flip the display order (input before the #each).

I had created something similar for an Ember 3.28 app, with a hard requirement that the user just be able to type and press enter to add items without needing to refocus, etc.

How would this work for focus after user action?

  1. The user is presented with an empty input field.
  2. They type a string, and hit enter.
  3. Then I process that string, add it to a list of visible things.
  4. Lastly the focus needs to be forced back to the input field in step one. Lather, Rinse, Repeat.