How to create WP Editor using javascript

I am trying to create some kind of repeated fields and for that, I want to create a new wp editor with some unique ID.

So my question is there any way to create wp_editor using any js? same as we get using ?php wp_editor() ? WordPress function.

I have tried using

tinyMCE .init( { mode : "exact" , elements : "accordion_icon_description_"+response.success.item_count });

but it prints very basic editor which is I think not same as of WordPress post content field editor

Topic post-content editor posts Wordpress javascript

Category Web


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

did the trick for me. Thanks to Goran Jakovljevic's answer on: How to load wp_editor via AJAX


WP 5.3.2

Currently building a plugin with Ajax page loading, needed to get data from multiple WP editors that are dynamicly loaded.

NOTE: Below example is for the wp-admin area, if you want this for the front-end you may need to extend.

1. Make sure editor scripts are loaded with:

add_action( 'admin_enqueue_scripts', 'load_admin_scripts');
function load_admin_scripts() {
  // Do NOT load it on every admin page, create some logic to only load on your pages
  wp_enqueue_editor();
}

2. Get editor textarea with Ajax (PHP):

function your_ajax_get_editor_callback() {
  // Note: every editor needs its own unique name and id
  return '<textarea name="my-wp-editor" id="my-wp-editor" rows="12" class="myprefix-wpeditor">The value from database here :-)</textarea>';
}

3. Use Ajax JS script to load and remove the WP editors on Ajax success callback.

I'm still playing around with all the available tinymce plugins, see TinyMCE docs and note that WP has renamed some of them. Check wp-includes/js/tinymce/plugins. In the example below I've added fullscreen, a handy plugin that's default off.

var active_editors = [];

function ajax_succes_callback() {
  remove_active_editors();
  init_editors();
}

function remove_active_editors() {
  $.each( active_editors, function( i, editor_id ) {
    wp.editor.remove(editor_id);
  }
  active_editors = [];
}

function init_editors() {

  $.each( $('.myprefix-wpeditor'), function( i, editor ) {

    var editor_id = $(editor).attr('id');
    wp.editor.initialize(
      editor_id,
      {
        tinymce: {
          wpautop: true,
          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'
        },
        quicktags: true,
        mediaButtons: true,
      }
    );

    // Save id for removal later on
    active_editors.push(editor_id);

  });

}

4. Get the content from each editor with:

function get_editor_content() {

  // NOTE: in my app the code below is inside a fields iteration (loop)

  var editor_id = $(field).attr('id');

  var mce_editor = tinymce.get(editor_id);
  if(mce_editor) {
    val = wp.editor.getContent(editor_id); // Visual tab is active
  } else {
    val = $('#'+editor_id).val(); // HTML tab is active
  }

}

Pointers:

  • Use wp.editor.initialize(editor_id_here) on a clean <textarea>, do not use wp_editor() for html output.
  • Make sure you remove the editor with wp.editor.remove(editor_id) if its no longer present in the dom. If you do not do this, the editor init will fail when you load the editor (dynamicly) for a second time.
  • Getting the editor content is different for each tab (Visual / HTML)

NOTE: The above code samples are not fully tested and may contain some errors. I have it fully working in my app. It's purely to get you going.


You need to use wp_enqueue_editor(); first to output the editor scripts, stylesheets, and default settings. You can find this documented here wp_enqueue_editor()

You need to remove true from function like so: wp.editor.initialize(editorId);


Thanks to Jacob Peattie's comment I can answer this using JS only. Actually we did something similar, but prior 4.8 and it wasn't this easy, so we did use wp_editor() in the end. But now, you can do so using wp.editor object in JavaScript. There are 3 main functions

  1. wp.editor.initialize = function( id, settings ) {

Where id is

The HTML id of the textarea that is used for the editor. Has to be jQuery compliant. No brackets, special chars, etc.

and settings is either an object

{
    tinymce: {
        // tinymce settings
    },
    quicktags: {
        buttons: '..'
    }
}

with these TinyMCE settings. Instead of any of the 3 objects (settings itself, tinymce or quicktags) you can use true to use the defaults.

  1. wp.editor.remove = function( id ) {

Is quite self-explanatory. Remove any editor instance that was created via wp.editor.initialize.

  1. wp.editor.getContent = function( id ) {

Well, get the content of any editor created via wp.editor.initialize.


Usage could look like so

var countEditors = 0;
$(document).on('click', 'button#addEditor', function() {
    var editorId = 'editor-' + countEditors;
    // add editor in HTML as <textarea> with id editorId
    // give it class wp-editor
    wp.editor.initialize(editorId, true);
    countEditors++;
});
$(document).on('click', 'button.removeEditor', function() {
   // assuming editor is under the same parent
   var editorId = $(this).parent().find('.wp-editor');
   wp.editor.remove(editorId);
});

As the content will be automatically posted, it is not needed in this example. But you could always retrieve it via wp.editor.getContent( editorId )

About

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