Add media button always inserts media on the next wp_editor instance when created dynamically

This is a really weird issue. I am trying to store data from a form in a plugin settings page and allow users to add html code with wp_editor. The users can dynamically add as many fields as they want to the form (and wp_editor fields, respectively). The problem is that when the user tries to add the media on a particular wp_editor, the media is added on the next wp_editor field instead. For example, if you have 2 wp_editor fields on the page and try to add image on the first one, it gets added on the second one.

This code adds the wp_editor within the form:

?php for ( $step = 1; $step = $steps; $step++ ) : ?
    tbody class=step
        tr valign=top
            th scope=rowlabel for=?php echo esc_attr( 'stg_tour[description_' . $step . ']' ); ??php esc_html_e( 'Step Description', 'simple-tour-guide' ); ?/label/th
            ?php
            $content  = isset( $tour_options[ 'description_' . $step ] ) ? $tour_options[ 'description_' . $step ] : '';
            $settings = array(
                'textarea_name' = esc_attr( 'stg_tour[description_' . $step . ']' ),
                'editor_class'  = 'form-field',
                'wpautop'       = false,
                'textarea_rows' = 5,
            );
            td?php wp_editor( wp_kses_post( $content ), $step, $settings ); ?/td
        /tr
    /tbody
?php endfor; ?

The following js function can add another set of fields, including another wp_editor

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');

    // remove wp editor from last step to be able to copy it
    if (typeof wp.editor != undefined){
        wp.editor.remove(lastStepFields[1].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 and provide unique 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) {
            field.name = stg_tour[description_ + counter + ']';
            field.value = '';
            field.id = +field.id + 1;

            //reapply the wp editor
            if (typeof wp.editor != undefined){
                wp.editor.initialize(field.id - 1, {
                    tinymce: {
                        wpautop: false,
                        plugins: 'charmap colorpicker compat3x directionality fullscreen hr image lists media paste tabfocus textcolor wordpress wpautoresize wpdialogs wpeditimage wpemoji wpgallery wplink wptextpattern wpview',
                        toolbar1: 'bold italic underline strikethrough | bullist numlist | blockquote hr wp_more | alignleft aligncenter alignright | link unlink | fullscreen | wp_adv',
                        toolbar2: 'formatselect alignjustify forecolor | pastetext removeformat charmap | outdent indent | undo redo | wp_help',
                        textarea_rows : 5
                    },
                    quicktags: true,
                    mediaButtons: true,

                });
                
                wp.editor.initialize(field.id, {
                    tinymce: {
                        wpautop: false,
                        plugins: 'charmap colorpicker compat3x directionality fullscreen hr image lists media paste tabfocus textcolor wordpress wpautoresize wpdialogs wpeditimage wpemoji wpgallery wplink wptextpattern wpview',
                        toolbar1: 'bold italic underline strikethrough | bullist numlist | blockquote hr wp_more | alignleft aligncenter alignright | link unlink | fullscreen | wp_adv',
                        toolbar2: 'formatselect alignjustify forecolor | pastetext removeformat charmap | outdent indent | undo redo | wp_help',
                        textarea_rows : 5
                    },
                    quicktags: true,
                    mediaButtons: true,
                });
            }
        }
    }
}

Please note everything else is working correctly and data is stored. However, the image is not being inserted on the correct place and this is driving me crazy. If there is only one wp_editor, the image never gets inserted and is missing from html. No errors in console. Please help.

Topic wp-editor media-library Wordpress

Category Web


Apparently the problem was that the id did not start with a letter and this caused all kinds of problems. Adding an incrementing number after the string fixed the issue:

<td><?php wp_editor( wp_kses_post( $content ), 'id' .$step, $settings ); ?></td>

The credits for the answer should go to @Sally CJ. Thank you!!

About

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