0

The component I'm working on shall, when its finished , be a textarea or contenteditable div, where text followed by a hashtag is highlighted/ or in something like a chip.

At the moment I'm working with a contenteditable div, surrounded by another component that suggests keywords. In that component is a v-model

My goal is to put the text after the #, in a span.

<template>
    <at :ats=['#'] v-model="vmodel">
        <div contenteditable @keypress.enter="highlight"></div>
    </at>
<template>

This does not what I want, since it adds the text at the beginning of the div. So for example when I write: "Hello #Something" I get: "#Something Hello"

<script>
import At from 'vue-at'
export default {
components: { At },
   data() {
     return { vmodel: '', };
   },
methods: {
   highlight(){
      this.vmodel = this.vmodel.replace(/\B#([^ ]+)/g,"<span class='highlight-Text'>$&</span>")
   }
}
</script>

How do I manipulate the vmodel, for example add a span to the text while typing, that it doesnt output gibberish?

Jon
  • 11
  • 3
  • what does the `at` component do with its v-model? – Roy J Feb 11 '19 at 18:32
  • It just passes it to the div component. Writing documents.activeElement.innerHtml = documents.activeElement.innerHtml.replace(/\B#([^ ]+)/g,"$&") Does the same job, but I want to avoid using the Dom.- and it's the same problem – Jon Feb 11 '19 at 19:20

1 Answers1

0

I think your problem is the regex. You are putting the whole match ($&) inside the span. That includes the hash. I'm not sure exactly how you want it done, but this puts the hash back where it was and puts the part after the hash inside the span.

new Vue({
  el: '#app',
  components: {
    at: {
      props: ['value'],
      template: '<div>{{value}}<slot></slot></div>'
    }
  },
  data() {
    return {
      vmodel: 'Something#-else',
    };
  },
  methods: {
    highlight() {
      this.vmodel = this.vmodel.replace(/(#\B)([^ ]+)/g, "$1<span class='highlight-Text'>$2</span>");
      console.log("New vmodel", this.vmodel);
    }
  }
});
.highlight-Text {
  border-radius: 5px;
  color: black;
  background-color: #5297f1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <at v-model="vmodel">
    <div contenteditable @keypress.enter="highlight">editable stuff</div>
  </at>
</div>
Roy J
  • 42,522
  • 10
  • 78
  • 102
  • Thank you. However this is not what I meant. The hashtag can be included. Changing the vmodel like this does not work. When I type for instance : Hello #Roy - I get - #Roy Hello. When keypress and not keypress enter ist activated: olleH yoR#. Somehow the old text appears after my new text. – Jon Feb 12 '19 at 08:42
  • Could you describe in complete detail what vmodel should contain, what the contenteditable should contain, what you type, and what you expect to happen? – Roy J Feb 12 '19 at 11:42
  • the v-model equals the innerHtml of the div. the div works like a textarea with a v-model. but it contains Html: i type: "Hello Roy this is a test" I get :
    Hello Roy
    this is a test
    inside the div/ v-model. when I press # my code scans the text and replaces the # with a # but, after that the cursor goes back to the beginning of the entire text. When I type a # I want the cursor to stay where I last typed something. that for example when I write #Thomas i get: #Thomas
    – Jon Feb 12 '19 at 12:28
  • When the value is updated, the entire value is replaced. The system has no way to know where the cursor belongs. You will have to keep track of that and place it yourself as part of the update process. [This question](https://stackoverflow.com/questions/1064089/inserting-a-text-where-cursor-is-using-javascript-jquery) may be helpful. – Roy J Feb 12 '19 at 12:55
  • @RoyJ, do you know how to insert component into `contenteditable`, store inserted string to database and recreate from database inserted content within editor again? – webprogrammer Jan 28 '20 at 09:00
  • @webprogrammer That is a complicated question for a comment. – Roy J Jan 29 '20 at 14:32
  • @RoyJ, I have created question about this https://stackoverflow.com/questions/59849554/how-to-insert-vue-component-into-contenteditable-div . Can you take a look at it? Thank you! – webprogrammer Jan 29 '20 at 14:46
  • @RoyJ, is it possible what I want to achieve with vue and contenteditable? – webprogrammer Feb 13 '20 at 22:08
  • 1
    @webprogrammer I think it should be possible, but I haven't done anything like it. The tricky part is making Vue manage something inside a contentEditor. You might make the contentEditable the Vue parent with dynamic children. [this answer](https://stackoverflow.com/questions/39516731/dynamic-html-elements-in-vue-js/39519105#39519105) may be useful. – Roy J Feb 18 '20 at 20:05
  • @RoyJ, I have created another question about editor concept with vue. Can you take a look (of course if you are interested)? Here a link https://stackoverflow.com/questions/60355574/hot-to-prevent-contenteditable-input-event-and-set-model-value-instead-in-vue . – webprogrammer Feb 22 '20 at 18:50