0

Here's the parent div:

<div
    id="comment"
    placeholder="Your comment"
    class="form-control ellipsesDropdown"
    contenteditable="true"
    @input="CommentChanged($event)"
> <!-- comments are divided into spans and divs with spans containg normal text and divs containing tags -->
    <span>&#8203;</span>
</div>

Now when a user clicks a Tag, I create the Tag as follows:

const newTag = document.createElement('div');

newTag.setAttribute("tabindex", "-1");
newTag.style.cssText = "background-color: rgba(29,155,209,0.1); color: #1264a3; display: inline-block; font-weight: bold;";

const tagContent = document.createTextNode(`@${p}`); // imagine p is an input argument 

newTag.append(tagContent);

// attach on key down event listener 
newTag.onkeydown = function(event) {
    console.log(event)                
};

// add tag to the comment div
document.getElementById("comment")!.appendChild(newTag);

However, I get nothing when I press keys in the tag div, click events do work though. I took a look at How can I use a 'keydown' event listener on a div? and have added the tabindex attribute.

I've also tried attaching the event listener as:

newTag.addEventListener('keydown', function(event) {
   console.log(event);
});

But this still doesn't work.

Any idea about what's going on?

EDIT: As requested, here's a codesandbox link: https://codesandbox.io/s/blue-bird-tdidr

EDIT 2: I've added more code from my project that basically implements to a certain extent what I'm trying to accomplish. Think about Twitter/Instagram/Slack, when you @someone as you're typing the post then perhaps some options appear for who to @ and when you click someone then that "tag" is added to your post. In the example, go ahead and write something, and include @, you'll see a list of options open, click either bread or toast and see it become a tag. What I'm trying to do it add the on keydown EventListener on the Tag so go ahead and see that it doesn't work!

Ayudh
  • 1,673
  • 1
  • 22
  • 55
  • Please create a [small demo](https://stackoverflow.com/help/minimal-reproducible-example) for this using [codesandbox.io](https://codesandbox.io/s/vue) to show the issue happening. – palaѕн May 05 '20 at 07:17
  • I've added a codesandbox link, please have a look – Ayudh May 05 '20 at 07:55

2 Answers2

1

I see you want to create a comment function i guess? But the way you do its not the Vue.js way. Here is a simple comment box example:

let el = new Vue({
   el: "#app",
   template: "",
   data(){
      return {
         comment: "",
         comments: []
      }
   },
   methods: {
      addComment(){
         let txt = this.convertTags(this.comment);
         console.log(txt);
         var d = new Date();
         var n = d.toLocaleTimeString();
         this.comments.push({
            commentText: txt,
            time: n
         });
         this.comment = "";
      },
      clickedTag(tag){
       
        console.log(tag);
      },
      convertTags(str){
         let strArr = str.split(" ");
         let mappedArr = strArr.map(el => {
            if(el.includes("@")){
           
               el = `<span onclick='el.clickedTag("${el.replace("@", "")}")' class='tag'>${el}</span>`;
            }
            return " " +el;
         });
         this.template = mappedArr.join("")
         return this.template;
      }
   }
});
#app {
width: 80%;
margin: 0 auto;

}



.comment {
background: #6c5ce7;
width: 100%;
margin: 5px 0;
color: white;
padding: 8px 5px;
}
input {
  margin: 0 auto;
  width: 100%;
   display: block;
   padding: 5px;
}

.tag {
  color: black;
  background: white;
  padding: 2px;
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div v-for="comment in comments" class="comments">
    <div class="comment">
       <p v-html="comment.commentText"></p>
       <small>{{ comment.time }}</small>
    </div>
  </div>
  <input type="text" v-model="comment" @keyup.enter="addComment">
</div>
bill.gates
  • 14,145
  • 3
  • 19
  • 47
  • Not really a comment function, more like a twitter/slack tagging people function with @... – Ayudh May 05 '20 at 08:08
  • Basically, think about how you're able to Tag someone in Twitter or instagram as you type. The rest of the words remain the same but the @person becomes blue as you type. As you type, you can select people like 'I met @jo..' would open a dropdown where you can select 'John' after which the text would become 'I met @john ...' with `@john` being blue. I understand what you're doing but what I need to use is the contenteditable attribute. One last example is if you have used Slack: basically trying to add/tag people in your posts – Ayudh May 05 '20 at 09:01
  • for me its harder to implement this. unfortunately i cant help you here – bill.gates May 05 '20 at 09:11
  • No problem, stay tuned for a more updated example on codesandbox – Ayudh May 05 '20 at 09:13
0

Apparently I don't need to add an event listener to the divs I'm adding. I can just set their contenteditable attribute to false as user SleepWalker menstions in his answer here: How to delete an HTML element inside a div with attribute contentEditable?

So my answer would then become:

...
newTag.setAttribute("contenteditable", "false")
document.getElementById("comment")!.appendChild(newTag);

This allows me to delete the tag in one go!

Ayudh
  • 1,673
  • 1
  • 22
  • 55