0

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="row"><label 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.

1 Answer 1

1

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!!

4
  • MDN says that "the value for an id attribute should start with a letter", so why did you or are you sure you want to use a number as the id value?
    – Sally CJ
    Commented Mar 23, 2022 at 7:16
  • 1
    Amazing! You saved me! I spent two days banging my head over this! I changed to logic to use letter and an incrementing number and it finally works now! Thank you so much!!!
    – Badan
    Commented Mar 23, 2022 at 9:28
  • @SallyCJ, perhaps you can have a word on this one too, as it is connected with the above: wordpress.stackexchange.com/questions/404053/…
    – Badan
    Commented Mar 25, 2022 at 16:37
  • I did check that question, but apparently you've already found a solution, so good for you :) Cheers!
    – Sally CJ
    Commented Mar 26, 2022 at 10:05

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.