load wordpress wp_editor dynamically (ajax) load wordpress wp_editor dynamically (ajax) wordpress wordpress

load wordpress wp_editor dynamically (ajax)


There maybe hacking involved, however, I tried to minimize them.

To make wp_editor can work in dynamic html (which means without reload page, js changes the page structure), there are two major issues need to take care:

  1. tinymce
  2. qucik-tags

For [tinymce]:

a. need reset UI properly

  • solution is [remove mce instance] -> [get proper mce settings] -> [re-init a new mce instance]

  • in js code (id means textarea id):

    tinymce.execCommand('mceRemoveEditor', true, id);var init = tinymce.extend( {}, tinyMCEPreInit.mceInit[ id ] );try { tinymce.init( init ); } catch(e){}

b. need data write back to textarea before submit

  • solution is [bind click to button] -> on submt :: [turn off mce] -> [turn on submit]
  • in js code:

    jq('textarea[id="' + id + '"]').closest('form').find('input[type="submit"]').click(function(){    if( getUserSetting( 'editor' ) == 'tmce' ){        var id = mce.find( 'textarea' ).attr( 'id' );        tinymce.execCommand( 'mceRemoveEditor', false, id );        tinymce.execCommand( 'mceAddEditor', false, id );    }    return true;});

For [Quick Tags]:

a. Re-init tags

  • [Get settings] -> [setup mouse event] -> [re-init QTags]

b. Switch to proper tab (mce tab or quick tag tab)

  • [switch to current tab mode]

  • both above in js code:

    if ( typeof(QTags) == 'function' ) {    jq( '[id="wp-' + id + '-wrap"]' ).unbind( 'onmousedown' );    jq( '[id="wp-' + id + '-wrap"]' ).bind( 'onmousedown', function(){        wpActiveEditor = id;    });    QTags( tinyMCEPreInit.qtInit[ id ] );    QTags._buttonsInit();    switchEditors.switchto( jq( 'textarea[id="' + id + '"]' ).closest( '.widget-mce' ).find( '.wp-switch-editor.switch-' + ( getUserSetting( 'editor' ) == 'html' ? 'html' : 'tmce' ) )[0] );}

Also, please remember if you use ajax, every time post back mce UI, you need re-do [reset mce UI] and [Qtags] in you js.A easy solution is using js code in you post back html, and detect in php of:

$isAjax = defined( 'DOING_AJAX' ) && DOING_AJAX == true );

About default settings in js value:

  1. mce : tinyMCEPreInit.mceInit

  2. qtags : tinyMCEPreInit.qtInit

If you try to use default setting for widget mode, you need locate default settings.

To get widget template id, in js code:

function getTemplateWidgetId( id ){        var form = jQuery( 'textarea[id="' + id + '"]' ).closest( 'form' );        var id_base = form.find( 'input[name="id_base"]' ).val();        var widget_id = form.find( 'input[name="widget-id"]' ).val();        return id.replace( widget_id, id_base + '-__i__' );}

So you can get settings by:

  1. for mce:

    var init;if( typeof tinyMCEPreInit.mceInit[ id ] == 'undefined' ){    init = tinyMCEPreInit.mceInit[ id ] = tinymce.extend( {}, tinyMCEPreInit.mceInit[ getTemplateWidgetId( id ) ] );}else{    init = tinyMCEPreInit.mceInit[ id ];}
  2. For Qtags:

    var qInit;if( typeof tinyMCEPreInit.qtInit[ id ] == 'undefined' ){    qInit = tinyMCEPreInit.qtInit[ id ] = jq.extend( {}, tinyMCEPreInit.qtInit[ getTemplateWidgetId( id ) ] );    qInit['id'] = id;}else{    qInit = tinyMCEPreInit.qtInit[ id ];}

For the complete code sample, please check : https://github.com/hezachary/wordpress-wysiwyg-widget/blob/master/widget_wp_editor.class.php

If anyone want use wp_editor in menu walk for admin, the principle should be the same.

If you have any question or better solut please comment, thanks.


Working solution:

p.s. you'd have asked at WP.SE: https://wordpress.stackexchange.com/a/192132/33667


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() {     Alert("I have started");    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){             Alert("I have Finished");            tinymce.init(My_New_Global_Settings);             tinyMCE.execCommand('mceAddEditor', false, "My_TextAreaID_22");             quicktags({id : "My_TextAreaID_22"});        }    );}   start_Ajax_request();     // < ---- EXECUTE


I have faced similar issue. I solved the issue by using following
1. Added following filter to open the editor always in visual mode in main page

add_filter( 'wp_default_editor', create_function('', 'return "tinymce";') );



2. In Ajax content used following for editor

wp_editor( $content, "editor_ajax", array('textarea_name'=>"content_ajax",'quicktags' => array('buttons' => 'strong,em,link,block,del,ins,img,ul,ol,li,code,close')));



3. In Ajax content added following JS code

<script src="<?php bloginfo('home')?>/wp-includes/js/quicktags.min.js"</script><script>jQuery(document).ready(function(){    ed_id =  "editor_ajax";    quicktags({id : ed_id,buttons:"strong,em,link,block,del,ins,img,ul,ol,li,code,more,close,dfw"});    tinyMCE.execCommand('mceAddEditor', false, fullId); });</script>