Renetik
Renetik

Reputation: 6373

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

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.

Upvotes: 10

Views: 28246

Answers (12)

Thomas Psik
Thomas Psik

Reputation: 81

There is a property for this on v-text-field called autofocus (and other input components). It accepts a boolean.

https://vuetifyjs.com/en/api/v-text-field/#props-autofocus

Upvotes: 0

Robert Benyi
Robert Benyi

Reputation: 1757

Autofocus and tabindex did the trick for me. You can also add the last tabindex to your save button

<v-form
      @submit.prevent="saveStuff"
    >
            <v-text-field
              ...
              autofocus
              tabindex="1"
            />
          </v-col>
          <v-text-field                 
              tabindex="2"
            />
          </v-col>
</vform>

Upvotes: 0

Richard Strickland
Richard Strickland

Reputation: 1841

vuetify 3.x update: using Steven Spungin's answer above - you just need to add .$el to the ref to get the internal reference like so:

   <v-text-field
      label=""
      prepend-inner-icon="mdi-magnify"
      variant="outlined"
      hint="enter search text"
      v-model="searchTerm"
      @change="SearchSourceStore.search(entityName, searchFields)"
      @keydown.enter="SearchSourceStore.search(entityName, searchFields)"
      :loading="SearchSourceStore.loading"
      focused
      clearable
      ref="searchInput"
    >
    </v-text-field>

mounted: function () { this.$nextTick(function () { // Code that will run only after the // entire view has been rendered

  const theElement = this.$refs.searchInput.$el;
  const input = theElement.querySelector(
    "input:not([type=hidden]),textarea:not([type=hidden])"
  );
  if (input) {
    setTimeout(() => {
      input.focus();
    }, 0);
  }
});

},

Upvotes: 2

Renetik
Renetik

Reputation: 6373

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.

Upvotes: 0

Cuesto
Cuesto

Reputation: 141

you can use the autofocus property

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

Upvotes: 13

niko
niko

Reputation: 116

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

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

Upvotes: 1

Magmatic
Magmatic

Reputation: 1949

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>

Upvotes: 2

DokiCRO
DokiCRO

Reputation: 4705

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

Upvotes: 10

mean.cj
mean.cj

Reputation: 123

work for me

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

Upvotes: 1

Steven Spungin
Steven Spungin

Reputation: 29149

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.

Upvotes: 12

Olaf
Olaf

Reputation: 1122

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

Upvotes: 0

Thomas
Thomas

Reputation: 2536

<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.

Upvotes: 3

Related Questions