WP Editor does not Initialize Correctly When Form Elements are Removed from the DOM

I am using js code to add and remove form elements and to initialize the wp_editor on the dynamically added textareas with js. The wp editor is initializing correctly when I am only adding elements with the add button. However, when I click remove, the last wp editor does not fully initialize (top toolbar is missing). I recorded a short video of the problem: WP Editor Not initializing Correctly.

Here is the code I am using to add and remove the elements:

function addNewStep() {
    //get all steps
    const steps = document.getElementsByClassName('step');
    const lastStep = steps[steps.length - 1];

    // get last step input fields
    const lastStepFields = lastStep.getElementsByClassName('form-field');
    const lastTextArea = lastStepFields[1];

    // remove wp editor from last textarea to be able to copy it
    if (typeof wp.editor != undefined  isShowWpEditor) {
        wp.editor.remove(lastTextArea.id);
    }

    //new table body wrapper
    const tbody_element = document.createElement('tbody');
    tbody_element.className = 'step';

    //create the new step
    let newStep = lastStep.cloneNode(true);
    table.appendChild(newStep);

    table.insertBefore(newStep, lastStep)

    // loop through last step fields to increment ids
    for (let i = 0, n = lastStepFields.length; i  n; i++) {
        const field = lastStepFields[i];
        // set the id and name attribute
        if (i == 0) {
            // some logic
        } else if (i == 1) {
            //reinitialize the wp editor that we removed before
            if (typeof wp.editor != undefined  isShowWpEditor) {
                wp.editor.initialize(field.id, {
                    tinymce: {
                        plugins: 'paste,lists,link,media,wordpress,wpeditimage,wpgallery,wpdialogs,wplink,textcolor,colorpicker',
                        toolbar1: 'bold italic underline strikethrough | blockquote bullist numlist | alignleft aligncenter alignright alignjustify',
                        toolbar2: 'formatselect forecolor link unlink',
                        textarea_rows: 5
                    },
                    quicktags: true,
                    mediaButtons: true,

                });

                // increment textarea id
                newId = +(field.id.replace('id_', '')) + 1;
                field.id = 'id_' + newId;
                // create a new instance of the wp editor on the new textarea that we have just created dynamically
                wp.editor.initialize(field.id, {
                    tinymce: {
                        plugins: 'paste,lists,link,media,wordpress,wpeditimage,wpgallery,wpdialogs,wplink,textcolor,colorpicker',
                        toolbar1: 'bold italic underline strikethrough | blockquote bullist numlist | alignleft aligncenter alignright alignjustify',
                        toolbar2: 'formatselect forecolor link unlink',
                        textarea_rows: 5
                    },
                    quicktags: true,
                    mediaButtons: true,

                });
            }

        }
    }

}

function removeStep() {
    const steps = document.getElementsByClassName('step');
    const lastStep = steps[steps.length - 1];
    lastStep.remove();
}

jQuery('#stg_steps').click(function(e) {
    e.preventDefault();
    addNewStep();
    counter++;
});

jQuery('#stg_remove_steps').click(function(e) {
    removeStep();
    counter--;
})

Everything is working, apart from the buggy wp editor initialization (toolbar is completely missing) when you have clicked the remove button beforehand.

Topic wp-editor Wordpress

Category Web


I finally figured out what the issue was. Apparently, when you remove the textarea element from the DOM, you also need to remove the wp editor that has been attached to it. (if you decide to re-add the textarea to the DOM later) I found out that even though the textarea is successfully removed, its id is still stored in the tinyMCEPreInit object and this causes problems with the dynamic wp editor initialization. Removing the wp editor with its corresponding textarea id fixed the issue for me:

function removeStep() {
    const steps = document.getElementsByClassName('step');
    const lastStep = steps[steps.length - 1];
    const lastTextArea = lastStep.getElementsByClassName('form-field')[1];
    lastStep.remove();
    if (typeof wp.editor != "undefined") {
        wp.editor.remove(lastTextArea.id);
    }
    counter--;
}

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.