How to run a JS function after DOM is complete && server connect is done?

I need to execute a javascript function AFTER both:

  • A server connect is finished loading
  • The DOM is finished loading

How do I do that?

More info:

  1. I have a function that initiates Tiny MCE. It replaces a textarea with the Tiny MCE editor.
function initTinymce(content) {
    // document.onreadystatechange = function () {
    //     if (document.readyState == "complete") {
    console.log('LOADING INIT TINY MCE');
    var globalContent = content;

    tinymce.init({
        selector: 'textarea#tinyEditor',
        setup: function (editor) {
            editor.on('init', function (e) {
                editor.setContent(globalContent);
                editor.save();
            });
            editor.on('change', function () {
                editor.save();
            });
        },
        min_height: 500,
        plugins: [
            'advlist', 'autolink', 'lists', 'link', 'image', 'charmap', 'preview',
            'anchor', 'searchreplace', 'visualblocks', 'code', 'fullscreen',
            'insertdatetime', 'media', 'table', 'help', 'wordcount', 'powerpaste'
        ],
        toolbar: 'undo redo | blocks | ' +
            'bold italic backcolor | alignleft aligncenter ' +
            'alignright alignjustify | bullist numlist outdent indent | ' +
            'removeformat | help',
        content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:16px }'
    });
}
  1. I have a server connect that loads data from the database, this data will populate the textarea that TinyMCE will initiate on.
    For example, itā€™ll populate: ā€œMy text from the databaseā€.

  2. I put a dynamic event ā€˜on successā€™ on the server connect, that does a RunJS to trigger the function:

  3. The server connect is finished faster than the DOM changes to the ā€œcompleteā€ status (and thus load all the elements and the tinyMCE JS library).

  4. The result: the editor isnā€™t loaded, it still looks like a regular textarea:

If I run the function initTinymce() in console,it does load in the editor:

So I conclude that the issue is that the server action is loaded (which I need to pre-populate) but the DOM isnā€™t completed yet.

I need to run the function after BOTH the DOM is complete and the server connect is done. How?

For the runJS step, does that produce the console log message in the second line of the function? Just wondered if the function is not running at all.

Hey Ben, yes it does produce that console.log

The ā€˜interactiveā€™ and ā€˜completeā€™ are coming from:

    document.onreadystatechange = function () {
console.log(document.readyState)
}

Which I put there to try get this stuff working with the document.readyState.

So it does run the function. Yet the function doesnā€™t do what I expect, probably because the element is not loaded (I am guessing this is the case, not sure how to check. Although I did read that the ā€˜interactiveā€™ state of the DOM means that all the html elements are loaded).

You could add a line after the complete one using dmx.parse to call the SC

Try a while loop, combined with a flow.

The flow is on a content page, and set to Auto Run.

The while condition is while the server connect does not have ā€œdataā€, meaning it has not finished running.

Hmm I want the SC to load ASAP though, itā€™s the one used to populate all the fields in the CMS, for example these:

You mean to change it like this, right?:

  1. Create a function that will run when document == ā€˜completeā€™ (so DOM is ready)
  2. use dmx.parse to run the SC to get the data
  3. use the ā€˜on successā€™ on the SC to initialize tinyMCE (like I have it now)

I think that would fix it, but again - it is not preferred because of this server action loading all the other data and thus this would add a delay that makes the UI look a bit laggy to the user.
Perhaps any other suggestions :smiley: ? Appreciate the help so far!

@mebeingken going to test this out

Sorry Iā€™m not sure what you mean.

If I understand you correctly, youā€™re making a flow that autoruns. It checks every 10 ms if the server action is ready (by checking if the data is there).

But I think I would have the same issue: if I do it this way, the DOM could still not be ready.

OR does the flow only run once the DOM is ready?

You are probably correct.

Hereā€™s an updateā€¦

Add a toggle element named dom_loaded to the layout.

Add this javascript that will check the toggle when the DOM is loaded:

  window.addEventListener('DOMContentLoaded', (event) => {

    dmx.parse("dom_loaded.check()")
  });

Change the while condition to also make sure the toggle is checked:

2 Likes

Appreciate it, will try this as soon as I wake up tomorrow!

I feel that dmx.parse line looks odd, Iā€™m guessing checked returns if itā€™s checked rather than actually changing the value of it

Perhaps you meant check()? Donā€™t have Wappler to test right now

2 Likes

Yep, youā€™re correct! WIll edit original.

1 Like

Thank you so much @mebeingken - couldnā€™t figure this out and on a very tight deadline. You donā€™t know how much stress youā€™ve alleviated.

It works well!

1 Like

Nice!

2 Likes