25

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.

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?

4
  • did you tried to do a ajax call via admin-ajax.php? If no make a function with your code then call it via admin-ajax.php
    – Sisir
    Commented May 10, 2012 at 15:56
  • Does this suggestion help? If so, it is not a WordPress question. :)
    – fuxia
    Commented May 10, 2012 at 16:52
  • @Sisir, If I am reading your suggestion correctly, then it didn't work. I used this to call the Ajax form: $('#sph-tabs-section-tab'+newTab).load('/wp-admin/admin-ajax.php?action=sph_add_editor'); and then added a function that returns wp_editor(). It gets called with no problem, but it still only returns the editor with no buttons. (exact same results as item 1 in the OP) Commented May 10, 2012 at 17:44
  • Once initialized TinyMCE cannot be moved around in DOM. You must remove it, move in DOM and initialize again. Similar code but for frontend comments here on my blog: techytalk.info/… Comments form is moved when user clicks reply/cancel reply.
    – user20106
    Commented Sep 5, 2012 at 22:46

8 Answers 8

7

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.

6

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.

2
  • 1
    tinymce is an external resource, so I think they might think tinymce's own docs cover it - tinymce.com/docs - but pretty poor on examples ... Also you must include tincemce scripts for this answer to work ! (simpliest way is to output one dummy PHP wp_editor() with tinymce arg set to true :-)
    – jave.web
    Commented Apr 20, 2016 at 20:34
  • thanks mate... this works for me as well - after returning the data from ajax I just initialize that... ;)
    – Sagive
    Commented Jul 2, 2019 at 8:55
4

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
2

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();
2
  • 3
    Please explain how does this work? This does not work. I tried it. Commented Jul 18, 2012 at 18:09
  • After adding the ajax content which contains the textarea I want tinyMCE on (response), call the tinymce_textareas function which initialises tinyMCE on the new textareas.
    – Steven
    Commented Jul 18, 2013 at 10:46
1

The the usable solution from @toscho on github. He build this nice result also for a question here, see his answer for more details.

1
  • This requires a library for use - T5 ... not a WP-only solution Commented Jan 17, 2015 at 0:57
0

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

0

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

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.

3
  • Please share a gist how this code can help, and then add the link for further details. Link-only answers become invalid if the link is broken - I hope you understand. :) Commented Apr 15, 2015 at 3:34
  • That link is broken right now and I don't have any context behind the answer. (One of the many reason why "just a link" answers are bad)
    – Sudar
    Commented Jul 6, 2015 at 16:51
  • This works but has some issues, when you select text or visual it creates duplicate text areas within the editor
    – Drmzindec
    Commented Jul 28, 2017 at 14:14

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