Is it possible for the Vue.js application to show the component right where the cursor is located in the textarea?

I am looking to create a Vue.js component with the following capabilities:
As the user types in the textarea, I want the component to display recommended words.
For instance, if the user types the letter s, I want a dropdown list to appear with words starting with s at the cursor's position in the textarea.
Is this functionality achievable?
If so, how can it be implemented?

Answer №1

While it's not feasible to detect the cursor position directly, I managed to implement your concept using Vue.js and CSS. Here is a simplified version of the code snippet:

Vue.component('autocomplete', {
          data() {
return {
content: "",
words: [
"lorem",
"ipsum",
"dolor",
"sit",
"amet",
"consectetur",
"adipisicing",
"elit"
],
showAutoCompl:false

};
},
computed: {
contentWords(){
return this.content.split(/ |\r|\r\n|\n/)
}
,
foundWords() {
return this.words.filter(word => {
return this.contentWords[this.contentWords.length-1] ? word.startsWith(this.contentWords[this.contentWords.length-1]) : "";

});
},
lines(){
return  this.content.split(/\r|\r\n|\n/);
}

},
methods: {

typeText(e) {

this.content && this.foundWords.length ? this.showAutoCompl = true : this.showAutoCompl = false;
var div = document.getElementById("autocmpl");
div.style.marginLeft = (10 + this.lines[this.lines.length-1].length * 7) + "px";
div.style.marginTop = (this.lines.length * 8) + "px";

},
chooseWord(word){
     if(this.content.search("\n") === -1){
     this.content = this.content.substring(0, this.content.lastIndexOf(" ") + 1) + word;
     }else if(this.content.lastIndexOf(" ") > this.content.lastIndexOf("\n")) {
     this.content = this.content.substring(0, this.content.lastIndexOf(" ") + 1) + word;

     }else{
     this.content = this.content.substring(0, this.content.lastIndexOf("\n") + 1) + word;

     }
     this.showAutoCompl = false;
 }

},
  template: `<div >
<div class="autocomplete" id="autocmpl" v-show="showAutoCompl">
<div class="autocomplete-item" v-for="word in foundWords" @click="chooseWord(word)">
{{word}} 
</div>
</div>
<textarea  @input="typeText" id="textarea1" cols="50" rows="10" v-model="content">
</textarea>
</div>
`
})

new Vue({
  el: "#app"
 
})
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

del {
  color: rgba(0, 0, 0, 0.3);
}


.autocomplete {
margin: 0;
margin-left: 10px;

padding: 10px;
box-shadow: 1px 1px 5px #444;
background: #fff;
position: absolute;
z-index: 5;
}
.autocomplete-item {
padding: 5px;
cursor: pointer;
}
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

<div id="app">
<autocomplete></autocomplete>
</div>

For a more concise implementation, here is the Single File Component version:

<template>
<div >
<div class="autocomplete" id="autocmpl" v-show="showAutoCompl">
<div class="autocomplete-item" v-for="word in foundWords" @click="chooseWord(word)">
{{word}} 
</div>
</div>
<textarea  @input="typeText" id="textarea1" cols="50" rows="10" v-model="content">
</textarea>
</div;

</template>

<script>
export default {
data() {
return {
content: "",
words: [
"lorem",
"ipsum",
"dolor",
"sit",
"amet",
"consectetur",
"adipisicing",
"elit"
],
showAutoCompl:false

};
},
computed: {
contentWords(){
return this.content.split(/ |\r|\r\n|\n/)
}
,
foundWords() {
return this.words.filter(word => {
return this.contentWords[this.contentWords.length-1] ? word.startsWith(this.contentWords[this.contentWords.length-1]) : "";

});
},
lines(){
return  this.content.split(/\r|\r\n|\n/);
}

},
methods: {

typeText(e) {

this.content && this.foundWords.length ? this.showAutoCompl = true : this.showAutoCompl = false;
var div = document.getElementById("autocmpl");
div.style.marginLeft = (10 + this.lines[this.lines.length-1].length * 7) + "px";
div.style.marginTop = (this.lines.length * 8) + "px";

},
chooseWord(word){
     if(this.content.search("\n") === -1){
     this.content = this.content.substring(0, this.content.lastIndexOf(" ") + 1) + word;
     }else if(this.content.lastIndexOf(" ") > this.content.lastIndexOf("\n")) {
     this.content = this.content.substring(0, this.content.lastIndexOf(" ") + 1) + word;

     }else{
     this.content = this.content.substring(0, this.content.lastIndexOf("\n") + 1) + word;

     }
     this.showAutoCompl = false;
 }

}
};
</script>

<style>
.autocomplete {
margin: 0;
margin-left: 10px;

padding: 10px;
box-shadow: 1px 1px 5px #444;
background: #fff;
position: absolute;
z-index: 5;
}
.autocomplete-item {
padding: 5px;
cursor: pointer;
}
</style>

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

Building a web application using the Nuxt.js framework and Express generator

Seeking help to seamlessly integrate an express app generated with express generator into my nuxt.js application. Came across this https://github.com/nuxt-community/express-template, although it seems to only cover basic express applications. Any recomme ...

The method piSession.buildPageInteractionSession is not valid

Hey there! I am facing an issue with a simple AJAX call to a PHP file. The request should be sent to the server and return back in an HTML input field. Unfortunately, I have not been able to resolve this error so far. Below is the code snippet: HTML: ...

Guide to updating information in Firestore using Node.js, embedded in a map array

Encountered an issue with the following error message: Error: Unable to access 'set' property of undefined. I am attempting to update the endTime field in my script for each user, calculate total hours worked, and then update the 'totalTi ...

React Router integration problem with Semantic UI React

Just diving into ReactJS and encountering a problem with using "Menu.Item" (from Semantic UI React) and React Router. I won't include my imports here, but rest assured they are all set up correctly. The constructor in my "App.jsx" looks like this: ...

Create efficient images using Node.js and express using sharp or canvas

Struggling with optimizing image rendering using node, express, and sharp. Successfully implemented an upload method with Jimp for images over 2000px wide and larger than 2mb in file size. While many libraries can achieve this, Jimp was more memory-effici ...

Error with JavaScript slideshow The slideshow using JavaScript seems to

I'm currently utilizing a script from the WOW Slider (free version) that looks like this: var slideIndex = 0; function showSlides() { var i; slides = document.getElementsByClassName("mySlides"); dots = document.getEle ...

What is the best way to conceal the initial column using jquery?

Is there a way to automatically hide the first column of data as it loads from a csv file using jquery and AJAX? I know you can do this using onclick function, but I prefer to have it automatically hidden. How can I achieve this? Below is the sample CSV d ...

Sequencing requests and processing data in Node.js through event handling

Is there a way to combine the responses from two requests into one single JSON response? The goal is to have an array containing both {response1JSON} and {response2JSON}, with each response streaming data that needs to be read. function getSongs() { c ...

Connecting a string array to the navigation bar

Need Assistance with AngularJS: In my controller, I have a string array that looks like this: var app = angular.module('myApp', []); app.controller('mycontroller', function($scope) { $scope.menuitems =['Home','About&apos ...

The Ajax search box displays results from the most recent query

Hey there, I need some assistance with a request: var searchResults = new Array(); var ajaxRequest = function (value, type) { if (typeof(type) === "undefined") type = "default"; var ajaxData = { "title" : value, "limit" : ...

Can SailsJS be used exclusively for API processes?

Can SailsJS be used solely as an API? After downloading the Sails project, is it possible to exclude the views and focus only on utilizing Sails as an API? ...

Execute asynchronous JavaScript request

When a user types something into the input id=2, an ajax function triggers. Here is the HTML: <input id="2" type="text" onkeyup="posttitulo(this.value)" /> And here is the SCRIPT: function posttitulo(value){ $.post("getdata/posttitulo.php",{p ...

Why is the error message "Invalid field name: '$conditionalHandlers' in 'collaborators..$conditionalHandlers'" popping up now?

Currently, in my Node/Express/Mongoose application (latest versions), I am working on a feature that involves "Projects" with a list of "collaborators" identified by the IDS of "Users". To simplify complex aggregations, I have decided to store these IDS as ...

Save information from an HTTP request made with a manually entered URL

As I delve into the world of web development, a particular issue has me stuck. My current project involves implementing a user password reset feature. The process goes like this: the user receives an email with a URL containing a unique token, clicks on th ...

Using ReactJS to Deconstruct Data within Class Components

I have a file named Context.js with the following content: const AppContext = createContext({ // ... color palette scheme color1: '#ADBDDB', color2: '#7F8EB2', color3: '#546287', color4 ...

What is the quickest way to update object data in Vue.js in real-time?

<div v-if="!item.editNickname" @click="item.editNickname=true, item.tmpNickname=item.nickname" >{{item.nickname}}</div> <v-text-field v-model="item.tmpNickname" v-if="item.editNickn ...

Issue with docker-composer module not being detected specifically on windows operating system

We are currently in the process of setting up a container running node.js with docker (specifically docker-compose, as we plan to incorporate mongodb later). Our approach involves copying the package.json in the Dockerfile and then creating a volume mount ...

The functionality of the calculator, created using HTML and JavaScript, is impeded on certain devices

I developed a web-based app that functions as a simple calculator for calculating freight/shipping prices to Venezuela. The app allows users to select between 1 to 4 packages, and choose different types of freight including air (normal, express) and mariti ...

Completely triggering a forced refresh on a single page application, disregarding cache, service workers, and all other

After experimenting with service workers on my Vue-built website, I made a critical error that has left Safari on my iPhone displaying only a blank page. To troubleshoot the issue, I connected my phone to my Mac and utilized Safari's inspector tool t ...

Saving an array to a text file with a new line delimiter can easily be achieved using Types

I have an array of plain strings that I need to save to a text file. However, I'm encountering an issue where the strings are being saved as comma separated values instead of new lines. Here is the data I currently have: https://i.sstatic.net/r3XVr.j ...