Search code examples
javascriptjqueryvuejs2v-for

Vue v-for autofocus on new textarea


I'm making a blog and would like the user to be able to create new textareas when they hit enter and for it to autofocus on the newly created textarea. I've tried using the autofocus attribute, but that doesn't work. I've also tried using the nextTick function, but that doesn't work. How do I do this?

<div v-for="(value, index) in content">
    <textarea v-model="content[index].value" v-bind:ref="'content-'+index" v-on:keyup.enter="add_content(index)" placeholder="Content" autofocus></textarea>
</div>

and add_content() is defined as follows:

add_content(index) {
    var next = index + 1;
    this.content.splice(next, 0, '');
    //this.$nextTick(() => {this.$refs['content-'+next].contentTextArea.focus()})
}

Solution

  • You're on the right path, but this.$refs['content-'+next] returns an array, so just access the first one and call .focus() on that

    add_content(index) {
      var next = index + 1;
      this.content.splice(next, 0, {
        value: "Next"
      });
      this.$nextTick(() => {
        this.$refs["content-" + next][0].focus();
      });
    }
    

    Working Example

    var app = new Vue({
      el: '#app',
      data() {
        return {
          content: [{
            value: "hello"
          }]
        };
      },
      methods: {
        add_content(index) {
          var next = index + 1;
          this.content.splice(next, 0, {
            value: "Next"
          });
          this.$nextTick(() => {
            this.$refs["content-" + next][0].focus();
          });
        }
      }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    
    <div id="app">
      <div v-for="(value, index) in content">
        <textarea v-model="content[index].value" v-bind:ref="'content-' + index" v-on:keyup.enter="add_content(index);" placeholder="Content" autofocus></textarea>
      </div>
    </div>

    Also, your value in the array seems to be an object rather than a string, so splice in an object rather than an empty string