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;
}
Related
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 have a Span that I have attached TinyMCE to so that I can do inline editing. When I make changes I want to post the changed content back to my Web API call as a json object.
Using X-Editable I was able to do this but I am trying to get away from WYSIHTML5.
This is my Jquery code to init TinyMCE and attach a function to the Save event.
$(document).ready(function () {
tinyMCE.init({
selector: ".editable",
inline: true,
plugins: "preview autoresize save",
toolbar1: 'preview | save',
menubar: "edit insert | tools",
autoresize_min_height: 100,
resize: 'both',
statusbar: true,
save_enablehendirty: true,
setup: function (editor) {
editor.on('SaveContent', function () {
MySaveFunction;
});
},
menu: {
edit: { title: 'Edit', items: 'undo redo | cut copy paste pastetext | selectall ' },
tools: { title: 'Tools', items: 'spellchecker code' }
}
});
One of the issues I'm running into is that the SaveContent tries to post the whole page and all I really want to do is post the contents of the active editor that I am using.
Does anyone know of a good example on how to post from a save in a specific TinyMCE edit area?
A click event on #open_dialog triggers a jQuery UI dialog with a ajax request to /ajax/request/url/
I want to initiate Tinymce on a textarea that is beeing sent back from the ajax request.
With the following code I get the log message "ajax done!" every time i click #open_dialog (and the ajax request is done) but Tinymce is only loaded the first time the dialog is opened. How come? And how do I initiate tinymce every time the dialog is loaded?
$('#open_dialog').click(function() {
$.when($.ajax("/ajax/request/url/")).done(function() {
console.log("ajax done!");
tinymce.init({selector:"textarea",
toolbar: "undo redo cut copy paste | bold italic underline | bullist numlist | table | styleselect | removeformat ",
plugins: "paste, table",
paste_word_valid_elements: "b,strong,i,em,h1,h2,table,tr,td,th",
menubar: false,
statusbar: true,
resize: "both"
});
});
});
Finally solved it by removing old DOM and old editors. ee_body below is the DOM id of the textarea.
$(document).ready(function() {
tinymce.init({
mode:"none",
toolbar: "undo redo cut copy paste | bold italic underline | bullist numlist | table | styleselect | removeformat ",
plugins: "paste, table",
paste_word_valid_elements: "b,strong,i,em,h1,h2,table,tr,td,th",
menubar: false,
statusbar: true,
resize: "both"
});
});
$('#open_dialog').click(function(){
//Remove old editors and DOM-elements
tinymce.EditorManager.execCommand("mceRemoveEditor", false, "ee_body");
$('#ee_body').remove();
// When ajax request to new email is done, load Tinymce
$.when($.ajax("/ajax/request/url/")).done(function() {
tinyMCE.execCommand("mceAddEditor", true, "ee_body");
});
});
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"
});
});