简体   繁体   中英

Implementing multiple TinyMCE editor with custom button in one page

I'm trying to create a JS library, which modify all textarea tags with data-tiny="TinyMCE" attribute to TinyMCE editors. The number of textarea tags is not predictable.

Custom Buttons will be added to all Editors, and everything is going fine in the execution, except one thing.

THE PROBLEM:

The custom buttons click event, add the content to the last Editor regardless the button of which editor is clicked.

I've attached the jsFiddle here, and the problem has been commented on lines 37 and 38 of js

here is the code :

var tinySelector = "textarea[data-tiny='TinyMCE']";
var tempGroupName;
var menuItems = [];
var tempGroups = ['Test Group'];
var temp = [{
  group: 'Test Group',
  css: '.test {color:red;}',
  title: 'Test Title',
  content: '<div class="test"> hi! </div>'
}];
var tinyContentCSS = "";

var tinys;
var direction = "ltr";

// Get all textarea elements which must be converted to a TinyMCE Editor
try {
  tinys = $("textarea[data-tiny='TinyMCE']").get();
} catch (e) {};

// This function creates a multilevel custom menu and adds it to the Editor
function createTempMenu(editor, editorIndex) {
  var k = 0;
  for (i = 0; i < tempGroups.length; i++) {
    var tempArray = [];
    tempArray[i] = [];
    tempGroupName = tempGroups[i];
    for (j = 0; j < temp.length; j++) {
      k++;
      if (temp[j].group == tempGroupName) {
        tempArray[i].push({
          editor: editor,
          text: temp[j].title,
          content: temp[j].content,
          css: temp[j].css,
          onclick: function() {
            this.settings.editor.insertContent(this.settings.content); // THE PROBLEM
            iframe_id = tinymce.editor.id + '_ifr'; // THE PROBLEM
            // adding styles to the head of the editor
            css_code = this.settings.css;
            with(document.getElementById(iframe_id).contentWindow) {
              var h = document.getElementsByTagName("head");
              if (!h.length) {
                if (DEBUG) console.log('length of h is null');
                return;
              }
              var newStyleSheet = document.createElement("style");
              newStyleSheet.type = "text/css";
              h[0].appendChild(newStyleSheet);
              try {
                if (typeof newStyleSheet.styleSheet !== "undefined") {
                  newStyleSheet.styleSheet.cssText = css_code;
                } else {
                  newStyleSheet.appendChild(document.createTextNode(css_code));
                  newStyleSheet.innerHTML = css_code;
                }
              } catch (err) {
                console.log(err.message);
              }
            }
          }
        });
      }
    }
    menuItems[i] = {
      text: tempGroupName,
      menu: tempArray[i]
    };
  }
  console.log(menuItems);
  return menuItems;
}

// This function gets an element and initialize it as a TinyMCE Editor
function initTinyDefault(strTinySelector, strTinyDir, editorIndex) {
  tinymce.init({
    language: 'en',
    selector: strTinySelector,
    theme: "modern",
    valid_elements: '*[*]',
    plugins: [
      "advlist autolink lists link image charmap print preview hr anchor pagebreak",
      "searchreplace wordcount visualblocks visualchars code fullscreen",
      "insertdatetime media nonbreaking save table contextmenu directionality",
      "emoticons template paste textcolor colorpicker textpattern"
    ],
    toolbar1: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image",
    toolbar2: "print preview media | forecolor backcolor emoticons | ltr rtl | UseTemplates",
    image_advtab: true,
    directionality: strTinyDir,
    paste_data_images: true,
    setup: function(editor) {
      editor.addButton('UseTemplates', {
        type: 'menubutton',
        text: 'Test Button',
        icon: false,
        menu: createTempMenu(editor, editorIndex)
      });
    },
    //content_css: tinyContentCSS,
  });
}


// Run the initialization function on the selected textarea elements one by one
for (i = 0; i < tinys.length; i++) {
  var str = $(tinys[i]).attr('data-tiny-id');
  $(tinySelector + "[data-tiny-id='" + str + "']").val(i);
  initTinyDefault(tinySelector + "[data-tiny-id='" + str + "']", direction, i);
}

Any help would be appreciated.

TinyMCE keeps an array of all instances of TinyMCE on on the page. Try something like this:

tinymce.get(tinymce.editors.length-1).setContent();

The array (from my testing) adds editors to the array in the order you init them in the page so the "last" editor initialized should always be the one that answers to:

tinymce.get(tinymce.editors.length-1)

See this modified JS Fiddle: https://jsfiddle.net/j1fmLc40/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM