How to load wp_editor() through AJAX/jQuery

I have a theme that is custom developed and really complex. One of the things that I have is multiple content areas where users can specify content for specific tabs. I load multiple instances of the WordPress editor through the wp_editor() function. It works perfectly. (This is all on the admin side, in the “Page” post type)

However, I began making a few improvements, including the ability to add/remove tabs dynamically (before, I loaded 6 editors on the page). Users may have 1-7 tabs.

Read More

When users add a tab, it needs to add an instance of the editor to the page. However, no matter what I try, I cannot get it to load and display correctly.

Here are the 2 things that I have tried so far:

  1. Create a php file that has the admin bootstrap included, and then loading the editor with wp_editor(). I then do a jQuery $.load to call the page and include the resulting HTML in the area that it needs to display. This doesn’t really work, however, as the editors formatting buttons disappear (it’s worth noting, that pulling the page up directly, the editor displays and functions perfectly)
  2. Loaded the editor on the page, inside a hidden div, and then once a tab is added, use jquery to move it into place. This loads the editor in tact, but you cannot use any of the editor buttons (they display, but don’t do anything), and you can’t put your cursor in the text area (curious, however, that switching to HTML mode allows typing and some interaction with the HTML mode buttons)

So the question is, has anyone had any luck adding editors through AJAX calls? Any advice?

Related posts

Leave a Reply

8 comments

  1. To get the quicktags to show up, you need to re instantiate them within your ajax oncomplete handler.

    quicktags({id : 'editorcontentid'});
    

    My ajax success handler looks like this;

    success: function(data, textStatus, XMLHttpRequest){
                //append editor to dom
                $('#container').append($(data).html());
                //init quicktags
                quicktags({id : 'editorcontentid'});
                //init tinymce
                tinymce.init(tinyMCEPreInit.mceInit['editorcontentid']);
            }
    

    I’ve managed to get the editor to load by first calling a static function that creates the editor and caches it as variable. I run the editor creation method on init. This seems to get wordpress to enque all the required scripts.

    Its important that when you create your editor instance, that you set it to use tinymce, that way the tinymce js file is enqued as well.

  2. After struggling with it, found the solution which works, in a callback after you add new element:

    tinymce.execCommand( 'mceAddEditor', true, element.id );
    

    Its strange that there is zero documentation inside codex.

  3. Finally, working solution:

    add action in wordpress, lets say My_Action_Name (also note, textarea ID My_TextAreaID_22 ):

    add_action('wp_ajax_My_Action_Name', function(){
        wp_editor( $_POST['default_text'], 'My_TextAreaID_22',      $settings = array( 'tinymce'=>true, 'textarea_name'=>'name77', 'wpautop' =>false,   'media_buttons' => true ,   'teeny' => false, 'quicktags'=>true, )   );    exit;
    });
    

    now, in Dashboard, execute this function (note, using of My_TextAreaID_22 and My_Action_Name):

    function start_Ajax_request() { 
        My_New_Global_Settings =  tinyMCEPreInit.mceInit.content;       // Get default WordPress SETTINGS  ( I cant confirm, but if you will need to change target ID, then add this line:  My_New_Global_Settings.selector = "My_TextAreaID_22";   )
        jQuery.post(ajaxurl,
            { action: "My_Action_Name",     default_text: "Hello World"}, 
            function(response,status){ 
                tinymce.init(My_New_Global_Settings); 
                tinyMCE.execCommand('mceAddEditor', false, "My_TextAreaID_22"); 
                quicktags({id : "My_TextAreaID_22"});
                // tinyMCE.execCommand( 'mceAddEditor', true, element.id );
            }
        );
    
    }   
    start_Ajax_request();     // < ---- EXECUTE
    
  4. You need to call the editor init again once you add your ajax textarea, I did it like this:

    $.fn.tinymce_textareas = function(){
      tinyMCE.init({
        skin : "wp_theme"
        // other options here
      });
    };
    

    Then call your function after your ajax, like this:

    $('#my_new_textarea_container').html(response).tinymce_textareas();
    
  5. I managed it in this way:

    1. First you need to call wp_editor at the main page, where from you call ajax. But you must wrap it in hidden div:
    
        <div style="display:none">
        <?php
        wp_editor( '', 'unique_id', array(
            'media_buttons' => false,
            'textarea_rows' => 10,
            'teeny' => true,
        ) );
        ?>
        </div>
    

    Id must be rundom and unique. Settings must be the same as the settings in your ajax editor.

    1. Second you need call this in ajax response:


    wp_editor( '', '[set id as you need]', array(the same settings as in the main page) );
    _WP_Editors::editor_js(); //this print editor init code

  6. This will work on admin pages.

    To append a new wp editor to a container by JS AJAX:

    1) Create an wp_ajax function in functions.php to return the wp_editor

    2) Create a jQuery script to request a new text editor and append it to a container, for this case, when pressing a button

    PHP File

    function yourprefix_get_text_editor() {
        $content = ""; // Empty because is a new editor
        $editor_id = $_POST["text_editor_id"]; // Random ID from AJAX JS call
        $textarea_name = $_POST["textarea_name"]; // Name from JS file
        $settings = array(
            'textarea_name' => $textarea_name
        );
        wp_editor($content, $editor_id, $settings);
        wp_die(); // Mandatory wp_die
    }
    add_action('wp_ajax_yourprefix_get_text_editor', 'yourprefix_get_text_editor');
    

    JS Script (jsfile.js)

    jQuery(function($) {
    $("someelement").click(function(e) { // To Add an Editor from a button click
        var target = themeajax.ajax_url; // Passed from wp_localize_script
        var editor_id = "editorid"; // Generate this dynamically
        var textarea_name = "textareaname" // Generate this as you need
        var data = {
            'action': 'yourprefix_get_text_editor',
            'text_editor_id': editor_id,
            'textarea_name': textarea_name
        }
        $.post(target, data, function(response) {
            container.append(response); // Use your logic to get the container where you want to append the editor
            tinymce.execCommand('mceAddEditor', false, editor_id);
            quicktags({id : editor_id});
        });
    }
    });
    

    Enqueue scripts call:

    function yourprefix_admin_scripts($hook) {
        wp_enqueue_script('your-slug', get_stylesheet_directory_uri() . '/path/to/jsfile.js', array('jquery'), null, true);
        wp_localize_script('your-slug', 'themeajax', array(
            'ajax_url' => admin_url('admin-ajax.php')
        ));
    }
    add_action('admin_enqueue_scripts', 'yourprefix_admin_scripts');
    
  7. Use this code, hope it will help:

    wp_editor( '', 'custom_editor_id' );
    _WP_Editors::enqueue_scripts();
    print_footer_scripts();
    _WP_Editors::editor_js();
    

    More detail can be found here.