[Vuejs]-How could the vuejs app display the component at the location of the textarea cursor?

0πŸ‘

βœ…

It’s not possible to detect the cursor position, but i had simulate your idea by using Vue.js and CSS and i reached to do that, you could improve it

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){
     //    console.log(this.content.lastIndexOf("\n"))

     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.5.17/dist/vue.js"></script>

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

The following code is for single file component :

<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){
     //    console.log(this.content.lastIndexOf("\n"))

     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>

Leave a comment