4

I need to add a dynamically imported component, just add a virtual tag to specific place in DOM structure. Unfortunately, every method that I found, didn't solve my problem.

How I try it first:

parent component (Editor.vue):

<template>
  <div>
    <div class="toolbar">
        <button @click="addContainer">ADD CONTAINER</button>
    </div>
    <div id="editor" ref="editor" contenteditable="true">
       //here, when in conteneditable div is coursor I need to add dynamically, programically virtual tag <container />
    </div>        
  </div>
</template>

and javascript

<script>
import container from '../container/Container.vue';

export default {
  name: "editor",
  components: {
    container
  },
  data() {
    return {};
  },
  methods: {
    addContainer(){          
      document.execCommand('insertHTML', false, <container />); // execCommand let me add html in specyfic place, but I have error Unexpected token

    }
  },
};

And child component that has to be adding how many times user need in exactly place then user need (Container.vue)

<template>
  <div
    class="container editor--space"
    @mouseover="highlightIn"
    @mouseout="highlightOut"
    contenteditable="true"
  >
    <div
      class="editor--labelspace"
      v-if="showLabel"
      contenteditable="false"
    >
      container
    </div>
    {{ container }}
  </div>
</template>

and javascript

<script>
export default {
  name: "container",
  data() {
    return {
      showLabel: false,
      container: "Container here ..."
    };
  },
  methods: {
    highlightIn(){
      this.showLabel = true;
    },
    highlightOut(){
      this.showLabel = false;
    }
  }
};
</script>

Maybe someone can give me some idea, how to do this?

2
  • how does your script now that you have inserted the component? Do you store insertion to database? Commented Jan 25, 2020 at 20:03
  • I want to store to database this code: "Some text, some <b>bold text</b>, and inserted image from this component <vue-simple-image :src='images/my_image_name.png' />, another text and html tags." But I can only get from contenteditable this generated html: "Some text, some <b>bold text</b>, and inserted image from this component <img src='images/my_image_name.png' />, another text and html tags.". How can I do that? Commented Jan 25, 2020 at 20:06

1 Answer 1

2

By the help of this: https://stackoverflow.com/a/2925633/7741865 and by dynamically creating the child components, you should achieve what you want. Sample:

addContainer() {
  // dynamically create component, replace 'Child' with your component
  var ComponentClass = Vue.extend(Child);
  var instance = new ComponentClass();
  instance.$mount();

  // get the caret position and insert component at that place
  var sel, range;
  if (window.getSelection) {
    sel = window.getSelection();
    if (sel.getRangeAt && sel.rangeCount) {
      range = sel.getRangeAt(0);
      range.deleteContents();
      range.insertNode(instance.$el);
      // remove the highlight (if you want)
      window.getSelection().removeAllRanges();
    }
  }
}

SANDBOX

Sign up to request clarification or add additional context in comments.

7 Comments

I want to insert image component with click event into contenteditable div. How can I use v-model of that component to generate only <img src=""/> tag? How can I restore that component and insert it again from database?
I voted up this answer. It looks like this is what I was searching for but have a few questions about how to use it in my component.
@webprogrammer, If you want to insert just an image, change the Child template to just have an image, and pass the url to the child. This should get your started: codesandbox.io/s/vue-template-m1ypk What you mean with the database is unclear. If that sandbox doesn't help, consider asking a new question :)
ok, I will ask new question. Thank you for new codesandbox with an image.
I have created extended question to my questions here stackoverflow.com/questions/59849554/… . Can you take a look when you will have a time? Thank you!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.