How to focus v-textarea programatically in vuetify and typescript?

Viewed 14918

Seems like impossible now, I tried some crazy stuff like:

(this.refs.vtextarea as any).textarea.focus()

((this.refs.vtextarea as Vue).$el as HTMLElement).focus()

etc...

Javascript source is hardly readable for me but it's sad to had to do it like this...

Int this some basic stuff, or am I missing something obvious ?

PS: well I see textarea element somewhere there in hierarchy... Maybe I can access by some basic dom child element access way... but this will be like writing worst code of my life.

9 Answers

Vuetify does not always work when focusing input, even with $nextTick.

This is how we do it generically for both input and textarea. We actually use this code with the ref set to our form in order to focus the first visible textarea or input. However, you can target just the widget that suits your needs.

mounted() {
  this.$nextTick(() => {
          const theElement = this.$refs.myRef         
          const input = theElement.querySelector('input:not([type=hidden]),textarea:not([type=hidden])')
          if (input) {
            setTimeout(() => {
              input.focus()
            }, 0)
          }
  });
}

The delay for $nextTick and setTimeout is negligible, often required, and will save you time and time again.

You don't need to exclude type=hidden either, but it can't hurt.

If the ref is not an HTMLElement, but instead a VueComponent, you may need to use this.$refs.myRef.$el to get the DOM element.

I got mine to work with this:

mounted() {
    this.$nextTick(() => {
      setTimeout(() => {
        this.$refs.descriptionDescription.$refs.input.focus()
      })
    })
  },

Combination of code from @Thomas and @Steven Spungin

<template>
   <v-text-area
      ref="myTextArea"
   />
</template>

<script>
   ...
   created () {
      this.$refs["myTextArea"].$refs.textarea.focus()
   }
</script>

I did it like this for text-fields. I think it should work the same way.

you can use the autofocus property

<v-text-field
                        autofocus
                        label="Insert Document Number*"
                        single-line
                      ></v-text-field>

work for me

setTimeout(() => {
   this.$refs.textNote.$refs.input.focus()
})

This is plain JavaScript, not TypeScript, but this works for me:

<v-textarea ref="entry"></v-textarea>


<script>
export default {
    mounted() {
        this.$refs["entry"].focus();
    }
}
</script>

I got it working for my v-text-field with:

setTimeout(() => this.$refs.YOURVTEXTFIELDREF.$refs.input.focus(), 100); 

Edited in new answer: https://codepen.io/cby016/pen/eQXoBo

Try adding $el after the reference. Like so:

this.$nextTick(() => this.$refs.cancelTestDialog.$el.focus())

Also make sure 'ref' is defined as an attribute on the component.

Vue refs work by adding a ref="<customName>" attribute on a component, which you can select by using this.$refs..

OLD: You need to wait a tick before the textarea is drawn. You could use tricks like setTimeout or use this Vue function:

this.$nextTick(() => { this.$refs.<name>.focus() })

Nexttick basically does the same as setTimeout

My solution is this for now:

(this.$refs.<name>.$el.childNodes[0].childNodes[0].childNodes[0].childNodes[0] as HTMLElement).focus()

But as I said in question before I tried it this way, it's as ugly as it can be. But.. works.

Related