Effortless expansion of textarea following data insertion in Vue

In my Vue project, I am fetching a JSON array from an API and displaying its content in a list of textareas using v-for.

Whenever a user focuses on a textarea or edits the text within it, I want the textarea to automatically resize to fit the content.

<div v-for="post in posts">
<textarea v-model="post.body" rows="1" @focus="resizeTextarea" @keyup="resizeTextarea"></textarea>
</div>

resizeTextarea(e) {
  let area = e.target;
  area.style.overflow = 'hidden';
  area.style.height = area.scrollHeight + 'px';
}

Despite my limited knowledge of Vue, I have been struggling to find a way to automatically resize all textareas after loading data from the API since there is no @load event for textareas.

I attempted to achieve this by using a watcher on the data, but it seems like a lengthy workaround.

Does anyone have a more efficient solution? Thank you!

Visit this link for reference.

Answer №1

If you're looking to dynamically resize a textarea element in your Vue component, one approach is to create a separate component specifically for managing the resizing logic. Here's an example that demonstrates this using single-file components:

// DynamicTextarea.vue
<template>
  <textarea
    v-model="value"
    ref="textarea"
    rows="1"
    @focus="resize"
    @keyup="resize"
  >
  </textarea>
</template>

<script>
  export default {
    props: {
      value: {
        type: String,
        required: true,
      }
    },
    mounted() {
      this.resize();
    },
    methods: {
      resize() {
        const { textarea } = this.$refs;
        textarea.style.height = `${textarea.scrollHeight - 4}px`;
      }
    }
  }
</script>

In the parent component template:

<template>
  <div v-for="post in posts">
    <DynamicTextarea v-model="post.body" />
  </div>
</template>

<script>
  import DynamicTextarea from './DynamicTextarea.vue';

  export default {
    components: {
      DynamicTextarea,
    }
    // Other script content
  }
</script>

Please note: If you are working with Vue 3, ensure that you replace value with modelValue in the child component.

Another option is to utilize a watch method as an alternative solution. Here is an example of how you could implement this:

watch: {
  posts() {
    // Ensure the view updates before applying changes
    this.$nextTick(() => {
      [...document.querySelectorAll('textarea')].forEach(textarea => {
        this.resizeTextarea({ target: textarea });
      });
    });
  }
}

Answer №2

If you want to enhance the functionality, consider utilizing the ref attribute:

<div id="app">
    <div v-for="post in posts" ref="container">
        <textarea v-model="post.body" rows="1" @focus="resizeTextarea" @keyup="resizeTextarea" ></textarea>
    </div>
</div>

To complete this setup, don't forget to insert the following code snippet at the end of the mounted() method:

this.$nextTick(() => {
    this.$refs.container.forEach(ta => {
        ta.firstChild.dispatchEvent(new Event("keyup"));
    });
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The Canvas renderer in Three.js is struggling to properly utilize the map and color properties

While attempting to utilize both the map and color properties at the same time with the canvas renderer, I have encountered a problem where only one of them will work properly. Additionally, when the cube to which the image is applied rotates, the image ...

Navigation Bar Revamp

Check out the colorful navigation bar on this page: The navigation bar appears distorted when I zoom in/out. Is there a way to resolve this issue? ...

Transferring data from localStorage to PHP server

After conducting research and referring to a book that delves into Ajax calls to PHP and the transfer of data between browser and server, I stumbled upon useful resources such as this guide on passing saved localStorage web data to a php script, which alig ...

What causes RangeError: Maximum call stack size exceeded when Element UI event handlers are triggered?

I'm currently working on setting up a form and validating it with Element UI. Despite closely following the documentation, I am encountering an issue where clicking or typing into the input boxes triggers a RangeError: Maximum call stack size exceeded ...

The argument type of '() => JQuery' cannot be assigned to a parameter type of '() => boolean'

Having trouble writing a jasmine test case for my method due to an error: spec.ts(163,18): error TS2345: Argument of type '() => JQuery' is not assignable to parameter of type '() => boolean' Any suggestions on how to resolve ...

I am perplexed as to why none of the scripts I attempt to use are effective in changing the active item

I am struggling to change the active item in my bootstrap navbar. I came across a similar question on this topic: Bootstrap navbar Active State not working Despite trying all of the suggested solutions, none seem to work for me and I can't figure out ...

Execute a function in Jquery Mobile after transitioning to a new page

Upon successful login, my goal is to change the page and then load a map using two separate functions. The first function handles the login process and redirects to the home page, while the second function is responsible for showing the map. function doLo ...

Move the displayed output in a two-dimensional space

Explore this straightforward example showcasing a cube centered at the world's origin. The camera captures the cube directly, making it appear in the center of the rendered 2D image with only its front face visible. I desire the ability to adjust the ...

Web Scraping ASU Courses using Node.js

I'm a beginner when it comes to Node.js, so please forgive me if I sound confused. Currently, I am attempting to scrape course information from ASU's course catalog (https://webapp4.asu.edu/catalog/) using tools like Zombie, Node.IO, and the HTT ...

What is the best way to adjust for additional spacing created by a scrollbar using CSS?

Is there a way to maintain alignment between two elements on a webpage, even when a scrollbar disrupts the layout? This challenge arises when one element needs to be aligned with another, but the appearance of a scrollbar throws off the alignment. How can ...

Perform a string comparison in JavaScript

I'm a bit confused about why this is not working as expected. Below you'll find an example of the .ajaxComplete method that seems to be causing issues. My goal is to compare the URL from which the action originates with the URL where I want the c ...

What is the best way to continuously call a URL using jQuery until the desired result is obtained?

I have a jQuery script that interacts with a Jenkins web server to initiate a build process. The duration of this build process is unknown, and one way to determine if the build is completed is by checking the JSON API for the status key "building." If thi ...

What is the process of querying both a collection and a subcollection in Firebase using AngularFire?

I have a structure in my firebase database that looks like this: /profiles/{uid}/displayName /email /otherAttribues /roles/{roleName}/someAttribute /someOtherAttribute The reason ...

Node: Exploring folders through recursive traversal

Node.js is a new world to me, and I'm determined to grasp its async behavior and callback structure. Here's where I'm currently struggling: // IMPORT ------------------------------------------------------------------------ fs = r ...

The content in an app using Ionic and Angular is being obstructed by the bottom tabs, preventing users

I am facing an issue with my Ionic and Angular app. When I place tabs at the bottom of my page, outside the ion-content, the scrolling stops working inside the ion-content and the fab button, which is located inside the ion-content, ends up covering the ta ...

Error: The term "Image" is unrecognizable

I'm in the process of creating a website where I want to display images via links. If the image is missing or only 1 pixel wide, I need the site to show an alternative image. My technology stack includes Jade/Pug and JS. Before rendering the links on ...

The loading sequence of Vuetify CSS for buttons is inconsistent in the production build, leading to functionality problems

I am currently working on a Vue application that utilizes a Vuetify "bottom navigation" component as shown below: <v-bottom-navigation app fixed grow color="#121212" class="bottom-navigation" > <v-btn text tile v-for="menuI ...

Learn how to display a tooltip for every individual point on a Highcharts network graph within an Angular

I am currently working on developing network graphs using highcharts and highcharts-angular within my Angular application. I have successfully managed to display the graph with datalabels, but now I need to implement tooltips for each point or node on the ...

Trouble encountered when attempting to override styles in Material UI's TableRow

I am attempting to customize Material UI's default styles in order to create a margin between each TableRow. Despite my efforts, it appears that the override is not being reflected in the user interface. ...

After completing the purchase, direct the user back to the HomePage

Currently, my development stack involves Reactjs for the UI and Java with Spring Boot for the backend. I have a specific question regarding user redirection after a purchase. For example, how can I direct the user back to the HomePage if they click the b ...