I'm using tabs component of JQuery UI 1.8, and I'm loading content of tabs via ajax (html content). In one of this tabs I'm using tinyMCE component, and when I load this tab the first time, the tiny initializates correctly but if I navegate to other tab and I recall the tab again the tiny breaks down.
This occurs when the import of tiny_mce.js is outside the contents of tabs. When I move the import into tab call, the tiny didn't load because it seems to be not initialized.
The question is: how can initialize tiny in an ajax tab?
Thanks in advance.
When I was having similar problems with TinyMCE and switching between ajax loaded tabs I found this wonderful piece of code at Ready4State so I thought I would share as I hope it helps others.
This will remove all instances of TinyMCE on the page.
var i, t = tinyMCE.editors;
for (i in t){
if (t.hasOwnProperty(i)){
t[i].remove();
}
}
Then you can safely reinitialize TinyMCE.
Personally I carry out the above code before using a switch statement to handle each ui.index, and I have a function that performs the initialisation for TinyMCE. So I just call that function in each of the relevant case statements.
Hope this helps someone else.
It might be worth re-initialising tiny MCE every time you switch back to the tab with the editor in. You can use the "select" event on the tab object.
$( ".selector" ).tabs({
select: function(event, ui) {
// initialise Tiny MCE here
}
});
You may have to destroy any previous instances of / references to the editor before re-initialising.
You need to shut down your tinymce instances before you switch to another tab else the editor element with that id will be blocked.
Remove the control before you switch the tab using
// the_editor_id equals the id of the underliing textarea
tinyMCE.execCommand('mceRemoveControl', false, the_editor_id);
I found the solution to my problem. The initialization of tinymce must be in load event of jquery tabs, like this:
$("div#tabs").tabs ({collapsible: false
,selected: -1
,fx: {opacity: 'toggle'}
,load: function (event, ui) {
// Tab with tinyMCE
if (ui.index == 0) {
tinyMCE.init({mode: "none",
theme: "advanced",
theme_advanced_toolbar_location: "top",
theme_advanced_toolbar_align: "left"
});
tinyMCE.execCommand ('mceAddControl', false, 'text_area_id');
}
else {
tinyMCE.triggerSave();
tinyMCE.execCommand('mceFocus', false, 'text_area_id');
tinyMCE.execCommand('mceRemoveControl', false, 'text_area_id');
}
}
});
I hope this helps others. Besides, if the content of the textarea is load via ajax, the command:
tinyMCE.triggerSave();
is not necesary.
Well, spent 3 hours on the same problem today... with Jquery UI 1.10 and TinyMCE 4.
The problem is, when unselected, the content of the ajax panel isnt removed from the DOM but just hidden. That means the textarea could be more than 1 time in the DOM (navigating the panels). => Death of tiny MCE...
There is no event in Jquery 1.10 to catch an "unselected panel". You have to deal with the before load event.
So the idea is to empty each "ajax loaded" panel before to load a panel. The code :
$( "#list_onglet_lecteur" ).tabs({
beforeLoad:
function( event, ui ) {
$("#list_onglet_lecteur div[role=tabpanel]").each(function(){
if($(this).attr("id") != "list_onglet_lecteur-accueil")$(this).empty();
});
$(ui.panel).html('<div style="width:100%;text-align:center"><img src="/images/ajax_loader_big.gif" alt=""></img><br />Chargement de l\'onglet</div>');
ui.jqXHR.error(function() {
ui.panel.html("Echec du chargement de l'onglet. Merci d'actualiser la page.");
});
}
})
Note i havn't find the way to make the difference between "ajax loaded panels" and "pre-loaded panels"...
That's a shame because you have to add each "pre-loaded panel" ids into the code...
Anyway, that resolve the tiny MCE problem. No need to init into the load event, and use the mceRemoveControl/mceAddControl commands.
Just init the tinyMCE edit in the "ajax loaded tab panel" view :
$(function() {
tinyMCE.init({
height : 300,
mode : "specific_textareas",
editor_selector : "mceEditor",
theme : "modern",
language : 'fr_FR',
plugins: [
"advlist autolink lists link image charmap print preview anchor",
"searchreplace visualblocks code fullscreen",
"insertdatetime media contextmenu paste moxiemanager"
],
toolbar: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image"
});
});
Related
I'm trying to set the content of the TinyMCE editor but I'm not having much luck. I've tried both setting the HTML beforehand and initializing the editor, and setting the content after the editor is initialized but to no avail - I'm able to reproduce that one in this fiddle (I can't reproduce setting the content first because it uses variable HTML from the database to set it).
Pretty much what I'm trying to do is this with my own code:
Editor.innerHTML += '<label>Description</label><br><div id="AC-Description">' + data.Data.Description + '</div><br><br>'; // Editor is just a div & data is a json object return from an ajax call
tinymce.init({
selector: '#AC-Description'
});
tinymce.activeEditor.setContent(data.Data.Description); // does not work, same as in example fiddle.
tinymce.get('AC-Description').setContent(data.Data.Description); // does not work either, same as in example fiddle
Before the editor is initialized, the data.Data.Description does show text in the DIV and then TinyMCE ignores it when it initializes.
I'm just at a lost, especially since it isn't working on JSFiddle too. Anyone else have issues with this before and/or am I just missing something?
Try to set the content when the editor has been initialized by listening to the init event like:
tinymce.init({
selector: '#Editor'
});
tinymce.get('Editor').on('init', function(e){
e.target.setContent('test');
});
Without seeing running code I can't say for sure but the issue here is almost certainly a timing issue of when your JavaScript run.
The TinyMCE init() function is asynchronous. When you call init() it takes some time for the process to complete. In your code example you are immediately trying to call either activeEditor or get() but there is likely no initialized editor so both of these attempts are failing.
The correct way to make sure that TinyMCE is fully initialized is to rely on the init event. This event is fired after TinyMCE is fully initialized and ready for interaction.
To load content via the init() you can do something like this:
tinymce.init({
selector: "textarea",
plugins: ["advlist autolink lists ..."],
toolbar: "undo redo | bullist numlist ...",
setup: function (editor) {
editor.on('init', function (e) {
//this gets executed AFTER TinyMCE is fully initialized
editor.setContent('<p>This is content set via the init function</p>');
});
}
});
This worked for me:
import tinymce from 'tinymce';
tinymce.init({
selector: 'textarea', // change this value according to your HTML
toolbar: ' bold italic underline bullist',
menubar: '',
width : "926",
placeholder: $('.annotation-session').data('placeholder'),
plugins: 'lists',
lists_indent_on_tab: false,
setup: function (editor) {
editor.on('init', function (e) {
editor.setContent(window.userNotes.note);
});
}
});
//If you want you can set on startup line 12 - 14
//And also on another funcion doing this:
//Empty
tinymce.activeEditor.setContent('');
if (yourVariable !== '') {
tinymce.activeEditor.setContent(yourVariable)
}
<input type="text" class="annotation-session">
I have a page with tons of tinymce enabled text areas which it is taking a huge amount of time to load. It apparently is requesting the same css file (content.min.css) once per textarea.
So is there a way to speed up a page that has this big number of tinymce areas?
I'm initializing each one independently because I'm setting each editor with an independent function.
tinymce.init({
theme: 'modern',
plugins: 'link lists code textcolor',
toolbar1: 'undo redo ...',
menubar: false,
forced_root_block: false,
selector:'textarea[unique_id=' + unique_id + ']',
setup : function(ed) {
var change_func = function(e) {
input.val(ed.getContent());
debounce_func();
}
ed.on('keyup', change_func);
ed.on('change', change_func);
}
});
Thanks!
EDIT:
I wondered if initializing all at once would be better, so I made it to initialize all textareas with a single call to tinymce.init but it did not make any improvement
If you are using the standard approach to loading TinyMCE it will have to load that CSS for each editor as each one is in a separate iFrame which is (effectively) like a separate browser window. They can't share the CSS across the iFrames.
If you use inline mode instead the CSS would be loaded once as there is only ever one instance of the editor actually invoked on the page.
I'm using tinyMce (the native one, not the angular ui directive)with my angular app. The text area which tinyMce converts to an html editor is located in a partial view (i'm using angular route). The problem is that the first time the app visits the partial view everything is ok, however the next times the user chooses this view the text are is not converted to tinyMce editor.
So my question is how do I make tinyMce initialization code hit each time the user visits the partial?
I saw similiar questions but didn't understand any of the solutions....
Here is my init tinyMCE code which is located in the controller of the partial view:
angular.module('sam').controller('groupMailController', ['$http', '$log', '$routeParams', 'User', function($http, $log, $routeParams, User) {
tmp = this;
//a factory which passes paramteres cross controllers
this.user = User;
//get list of building objects
this.availableBuildings = _.values(this.user.buildings);
$log.log('init meee !!');
tinymce.init(
{selector:'textarea',
directionality : 'rtl',
plugins: ["advlist autolink lists link image charmap print preview anchor",
"searchreplace visualblocks code fullscreen",
"insertdatetime media table contextmenu paste directionality"],
toolbar: "undo redo | styleselect | bold italic | link image | alignleft aligncenter alignright | ltr rtl"});
}]);
You can remove the current active editor before calling init().
if (tinyMCE.activeEditor != null)
tinymce.EditorManager.execCommand('mceRemoveEditor', true, 'myTextArea');
tinymce.init({
selector: "#myTextArea"
});
Or you can use TinyMCE Angular plugin. Here is the info :
https://github.com/angular-ui/ui-tinymce
This is a late answer for those who may have the same issue. The problem is that tinymce is still keeping the old instance of the editor and initializing it again won't work. So the solution consist of deleting that instance on scope destroy event.
$scope.$on('$destroy', function() {
var tinyInstance = tinymce.get('#myTextArea');
if (tinyInstance) {
tinyInstance.remove();
tinyInstance = null;
}
});
Hope this will help
Changing the textarea's id when routing, forces the tiny-mce angular module to refresh and re-create the editor.
I have this settings for tinyMCE:
tinymceOptions = {
inline: true,
resize: false,
plugins: "textcolor",
selector: "div.editing",
toolbar: "forecolor backcolor",
fixed_toolbar_container: ".my-toolbar"
}
and that worked as I it should be, but doesn't satisfy my needs, what I want is a fixed external toolbar for multiple editor instances that will not disappear when focus is lost (blur event) which not the case with this settings.
Note:
removing the inline: true has no effect!?
If you want the toolbar to be external, and you don't want to auto-focus it, here's what you do:
tinymceOptions = {
inline: true,
resize: false,
plugins: "textcolor",
selector: "div.editing",
toolbar: "forecolor backcolor",
fixed_toolbar_container: ".my-toolbar",
init_instance_callback: function (editor) {
// This will trick the editor into thinking it was focused
// without actually focusing it (causing the toolbar to appear)
editor.fire('focus');
},
setup: function (editor) {
// This prevents the blur event from hiding the toolbar
editor.on('blur', function () {
return false;
});
}
}
I'm looking for the same thing here. I have a somewhat hacky approach that I discovered on the TinyMCE forums and am currently looking for a better approach.
By throwing an error after the blur event is fired it prevents TinyMCE's cleanup from removing the editor.
tinymce.init({
menubar: false,
plugins: "advlist autolink lists link image charmap print preview anchor searchreplace visualblocks code fullscreen insertdatetime media textcolor table contextmenu paste wordcount",
toolbar: [
"undo redo removeformat searchreplace code",
"styleselect fontsizeselect forecolor",
"bold italic underline strikethrough superscript subscript",
"alignleft aligncenter alignright alignjustify | outdent indent blockquote",
"bullist numlist table | link image media"
],
selector: '.selected .inline-preview',
inline: true,
autofocus: true,
fixed_toolbar_container: 'section[data-sidebar-text-controls] > div',
init_instance_callback: function () {
tinymce.activeEditor.focus();
},
setup: function (editor) {
editor.on('blur', function () {
throw new Error('tiny mce hack workaround');
});
}
});
My understanding is each editor has it's own toolbar.
When using 'fixed_toolbar_container' it simply displays the current editor's toolbar in that container.
If no editor is selected it can't know which editor's toolbar you want displayed - sadly it doesn't yet have mind reading capabilities ;)
A possible work-around for you would be to somehow make sure an editor is always selected, therefore a toolbar will always be displayed. Sorry, no time to figure out how but maybe others can expand (blur()/focus() maybe?).
With an editor initialized with auto_focus: true, and the following in the css will force the tool bar to always be visible. Though the toolbar does not exist until focus is made on the editor.
.mce-tinymce.mce-tinymce-inline.mce-container.mce-panel {
display: block !important;
}
I am trying to get the mention plugin to work with TinyMCE. The problem is: whenever I enable the plugin, I get the dreaded "tinymce is not defined" error. I think it may be loading the plugin "too soon", but I don't know how to delay the plugin load until TinyMCE is fully loaded.
Here's how I have the the init() configured:
$(document).ready(function(e) {
tinymce.init({
selector:'textarea.update',
menubar:false,
toolbar:"undo redo | bold italic | bullist numlist | link unlink",
width:'100%',
plugins: "link,mention",
mentions:
{
source: [
{ name: "Michael" },
{ name: "Erica" },
{ name: "Sloan" }
]
}
});
});
The Text area is
<textarea class="update"></textarea>
If I remove the mention option and the "mention" from the plugins list, it works fine. As soon as I put the plugin back into the "on" mode, it breaks.
How do I fix this?
The problem (as leakim571 so astutely pointed out) was that I was using CacheFly instead of hosting my own copy. When I got rid of the cachefly reference, downloaded the whole tinymce package, and put the mention plugin in that package, everything started to work perfectly.