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.
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 wrote plugin for TinyMCE 4 and added into setup function.
This plugin works well but it shows me a message error float inside editor. I don't know why.
error message
This file is called customConfig
import Export2Doc from '../config/plugins/export/plugin';
export default {
setup: function(editor){
editor.addButton('mybutton', {
type: 'menubutton',
text: 'إستخراج الي',
// icon: false,
menu: [{
text: 'Pdf',
onclick: function() {
window.open('preview');
}
},
{
text: 'Docx',
onclick: function(){
Store.dispatch('getDocumentContents').then( response =>{
let contentString = "";
Store.state.documents.documentContents.forEach(element => {
if(element.content != ""){
console.log(element.content, element, response);
contentString += '<br style="page-break-after: always; clear: both" />'+element.content;
}
});
Export2Doc.excute(contentString, 'atroha');
});
},
}]
});
}
}
Then inside editor it looks like this :
import customConfig from "./customConfig";
const config = {
selector: "#editor",
directionality: "rtl",
branding: false,
height: 500,
theme: "modern",
// toolbar: 'mybutton',
plugins:
"mybutton fullscreen charmap hr anchor searchreplace wordcount pagebreak print preview image table "+
"anchor advlist lists tinymcespellchecker a11ychecker "+
"imagetools mediaembed link contextmenu directionality "+
"save autosave",
// toolbar1:
// "table | image | bold link | alignleft aligncenter alignright | ltr rtl | numlist bullist | outdent indent | references | threads",
// fullscreen pagebreak preview |
// plugins:
// "advlist autolink link image lists charmap print preview hr anchor pagebreak spellchecker"+
// "searchreplace wordcount visualblocks visualchars code fullscreen insertdatetime media nonbreaking"+
// "save table contextmenu directionality emoticons template paste textcolor",
// toolbar2: " media | forecolor backcolor emotions | help",
toolbar1: ' table insertfile undo redo mybutton save | styleselect | bold italic | alignleft | ltr rtl | aligncenter alignright alignjustify '+
'| bullist numlist outdent indent | link image | print preview media fullpage | forecolor backcolor emoticons | references | threads',
image_advtab: true,
// language: "ar_EG",
menubar: true,
autosave_ask_before_unload: true,
setup: customConfig.setup,
}
export default config;
I try to hide the message but I can't.
That error message means that TinyMCE is looking for your plugin (mybutton) in the place it looks for all of its standard plugins and the plugin is not found in that location.
The issue is that you have not actually created a plugin for TinyMCE in the code you show - you appear to create toolbar button via code.
To move this forward you have two options...
Use the setup function in your TinyMCE configuration and create the toolbar button in that function. You can then add the toolbar button to your toolbar configuration setting. In this scenario you are not creating a plugin so you don't add anything to the plugins configuration setting.
Create a proper TinyMCE plugin and load that plugin using the plugins configuration setting. The plugin can register a toolbar button on the toolbar as it loads.
If you choose option 1...
Assuming your code is wired together correctly you can just remove your attempt to load a plugin called mybutton (there is no such plugin) and instead add mybutton to the toolbar1 configuration setting. This will explicitly add your defined toolbar button to the TinyMCE toolbar.
If you choose option 2...
As you are using the TinyMCE Cloud platform to load TinyMCE you need to use the external_plugins configuration option to load your custom plugin from some location on your server. You can't host a custom plugin on the TinyMCE Cloud platform and just adding a plugin to the plugins configuration option will tell TinyMCE to load it from the same place it loads all its other plugins.
If you want to look at this second option here is the documentation on how to create a proper plugin for TinyMCE:
TinyMCE 5: https://www.tiny.cloud/docs/advanced/creating-a-plugin/
TinyMCE 4: https://www.tiny.cloud/docs-4x/advanced/creating-a-plugin/
i'm using tinymce RTF editor on my website. i want to disable copy/paste option in tinymce textarea. i found this method on stackoverflow but it didn't work for me.
How to Prevent/disable copy and paste in Tinymce
document.addEventListener('paste', function(e){
e.preventDefault();
});
You should be able to use paste_preprocess if you include the paste plugin. If you're using paste_preprocess, make sure you're passing it as an option to tinymce.init(), and also including the plugin. For example:
tinymce.init({
selector: "textarea",
plugins: [
"advlist autolink lists link image charmap print preview anchor",
"searchreplace visualblocks code fullscreen",
"insertdatetime media table contextmenu paste"
],
paste_preprocess: function (plugin, args) {
console.log("Attempted to paste: ", args.content);
// replace copied text with empty string
args.content = '';
},
toolbar: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image"
});
See this updated fiddle for an example.
Earlier answers suggesting to replace args.contents = '' do not actually prevent a paste operation, they rather alter the contents of the paste to an empty string which still gets pasted.
TinyMCE Event Doc
This actually prevents the paste completely.
paste_preprocess: (plugin, args) => {
args.stopImmediatePropagation();
args.stopPropagation();
args.preventDefault();
});
As previously answered, you can use paste_preprocess. However, you'll need to add paste to plugins.
Example:
tinymce.init({
...,
plugins: [
"paste"
],
paste_preprocess: function (plugin, args) {
console.log(args.content);
args.content = '';
}
});
You can intercept paste in the tinymce.init
paste_preprocess: function(plugin, args) {
console.log(args.content);
args.content = '';
}
I'm building a javascript app that will be displaying a live-updated discussion thread. It will regularly poll the server for new data, and write it to the page. For posting comments and replies, we are trying to use the TinyMCE WYSIWYG editor, which converts a textarea into a nice HTML editor. This is my first experience with this editor. The app relies heavily on jQuery, so we are using TinyMCE's jQuery plugin to make it easier to work with.
Here's the issue... Every time our code generates a new textarea, we attach an editor to it. The first one shows up and works perfectly. When we add more, the TinyMCE code will hidfe the textarea, but won't generate the editor, and I don't know why.
I've gone ahead and built out a simple working example on jsFiddle:
http://jsfiddle.net/HUHKT/
function addTextArea(){
// find where the textareas will be placed
var container = $('#textareaContainer');
container.append( newTextArea() );
container.append( $(document.createElement('hr')) );
}
// define some configuration settings for the editor
var editorConfig = {
// Location of TinyMCE script
script_url: 'http://tinymce.cachefly.net/4.0/tinymce.min.js',
// setup parameters
menubar: false,
statusbar: false,
toolbar: 'bold italic underline | bullist numlist | undo redo | removeformat'
}
function newTextArea(){
var textarea = $(document.createElement('textarea'))
.attr('id',(new Date()).getTime()) // give it a unique timestamp ID
.val( 'This text area added # ' + new Date() )
.tinymce(editorConfig); // apply the WYSIWYG editor
return textarea;
}
Any help would be appreciated. Thank you.
You should add class for the new text area, then apply tinymce on that class every 5 sec
Here is an update to your jsfiddle that works
function timerElapsed(){
// limit this example so we don't fill up the page with too many textareas
if( $('#textareaContainer').find('textarea').length < 4 ){
addTextArea();
}
// define some configuration settings for the editor
var editorConfig = {
// Location of TinyMCE script
script_url: 'http://tinymce.cachefly.net/4.0/tinymce.min.js',
// setup parameters
menubar: false,
statusbar: false,
toolbar: 'bold italic underline | bullist numlist | undo redo | removeformat'
}
$('.tinymce-txt').tinymce(editorConfig);
}
function addTextArea(){
// find where the textareas will be placed
var container = $('#textareaContainer');
container.append( newTextArea() );
container.append( $(document.createElement('hr')) );
}
function newTextArea(){
var textarea = $(document.createElement('textarea'))
.attr('id',(new Date()).getTime()) // give it a unique timestamp ID
.val( 'This text area added # ' + new Date() )
.attr('class', 'tinymce-txt');// apply the WYSIWYG editor
return textarea;
}
$('#btnAdd').click( function(){ addTextArea(); } );
// set up the regular "polling" code
setInterval(function () {
timerElapsed();
}, 5000);
// NOTE: I also tried a repeating setTimeout function and had the same problem
http://jsfiddle.net/HUHKT/5/
`$('.tinymce-txt').tinymce(editorConfig);`
did not work with me, I replaced it with
tinymce.EditorManager.execCommand('mceAddEditor', false, uniqeId);
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"
});
});