Home > Software engineering >  Bind to an Element Which Does Not Exist (with no user interaction/click)
Bind to an Element Which Does Not Exist (with no user interaction/click)

Time:09-16

I've been added to an existing project (jQuery, petite-vue ...) and I'm trying to add this simple WYSIWYG to a form textarea.

The textarea does not exist on page load. This is the template code which shows how it's added dynamically. The forum object is the result of an async GET wait fetch request.

<div  v-if="forum.currentGroup && JSON.stringify(forum.currentGroup) != '{}'">
    <div >
        <form @submit.prevent="forum.addThread" method="post" >
            <textarea rows="4"
                      id="summernote"
                      name="question"
                      placeholder="{{ 'forum.ask_your_question' | trans }}"
                      
                      required></textarea>
            <button type="submit" >{{ 'forum.send' | trans }}</button>
        </form>
    </div>
</div>

As per the summernote install direction, the following command simply doesn't work;

    $(document).ready(function() {
        $('#summernote').summernote();
    });

I also tried to access the element when receiveing a response from the fetch request, but it is always logging null in the code below;

        try {
            let response = await fetch(` ... the url ... `, {
                method: 'GET',
            });

            if (response.ok) {
                const json = await response.json();
                if (json.success) {
                    ...

                    let thing = document.getElementById('summernote');
                    console.log(thing);

                    $('#summernote').summernote();

To try and find out what's going on with the document, I ran the following code;

    window.addEventListener('load', (event) => {
        console.log('load');
    });

    document.addEventListener('readystatechange', (event) => {
        console.log(document.readyState);
    });

    document.addEventListener('DOMContentLoaded', (event) => {
        console.log('DOMContentLoaded');
    });

The console log for that code is;

complete
load

The DOMContentLoaded listener never outputs to console. I tried using an on('load') but it never gets called;

    $(document).on('load', '.question', function() {
        alert('blah');
        $('#summernote').summernote();
    });

I have to render the WYSIWYG without user interaction ... when the textarea is added to the page, it should render the wysiwyg editor.

Any ideas? I've been at this for a couple of days and am at a loss.

CodePudding user response:

Create a custom component with the <textarea> inside, and initialise the plugin on mount:

const SummernoteView = {
    mounted() {
        $("#summernote").summernote();
    },
    template: `
        <textarea rows="4"
            id="summernote"
            name="question"
            placeholder="{{ 'forum.ask_your_question' | trans }}"
            
            required></textarea>
    `,
};

export default SummernoteView;

Remember to import and declare it in the parent component:

import SummernoteView from './SummernoteView';

// your parent component
{
  data() { ... },
  methods: { ... }
  components: {
    'summernote-view': SummernoteView
  }
}

In your template:

<div  v-if="forum.currentGroup && JSON.stringify(forum.currentGroup) != '{}'">
    <div >
        <form @submit.prevent="forum.addThread" method="post" >
            <summernote-view/>
            <button type="submit" >{{ 'forum.send' | trans }}</button>
        </form>
    </div>
</div>

More on Vue Components.

  • Related