TinyMCE - disable standard save button - javascript

I try to disable programmatically the standard "save" button of the save plugin
tinymce.init
({
selector: '#editorMain',
plugins: "save,code,textcolor,charmap,searchreplace,paste,wordcount",
height: 400,
setup: function(editor) {
editor.on('keyup',function(e){
console.log(getStats('editorMain').chars);
var body = tinymce.get('editorMain').getBody();
var currentValue=tinymce.trim(body.innerText || body.textContent);
var currentCharsCount=getStats('editorMain').chars;
var limit=10;
var diff=limit - currentCharsCount;
if (diff>-1)
{
$("#chars_left").html(diff + " characters left");
}
else
{
$("#chars_left").html("Your comment is too long");
// here should we disable the save button
}
});
},
I googled for a solution and found that in version 3.x there was an object called "ControlManager". This has been removed in version 4 (the one I currently use)
According to the documentation the following should be implemented to do that:
// In TinyMCE 4 you can use the simpler stateSelector setting
editor.addButton('SomeButton', {
text: 'My button',
stateSelector: 'a'
});
but how can this work for the "save" button ? the save button comes when I use the "save" plugin, this does not have to be programmatically added.

well that was a tough one. This:
tinymce.activeEditor.theme.panel.find('toolbar *')[1];
enables to access the button. then the ".disabled(1)" method.
That's a pity that we cannot access the elements using their names or ids...

If you don't want the functionality of the save plugin simply remove it from the list in the plugins: init options. Use the list shown here.
tinymce.init
({
selector: '#editorMain',
plugins: "code,textcolor,charmap,searchreplace,paste,wordcount",
....

Related

TinyMCE: how to let user mark text when "readonly: true;"

I want to let users select (and copy) text within TinyMCE.
I'm not quite sure, but it seems regarding security that browsers don't allow that.
This Codepen is from the official TinyMCE site:
https://codepen.io/tinymce/pen/NGegZK
Here you can select text.
When you add there the following parameter in the 2nd line of the JavaScript as followed, then you can't longer select text.
readonly: true,
How can I set "readonly: true" and let the user still select text?
I appreciate any help.
I faced this problem too. Moreover, the inability to select text is nothing compared to the inability to click links. I've submitted an issue about this a while ago, but there is still no reaction.
You can use a workaround for now (codepen):
readonly: 1,
setup: function(editor) {
editor.on('SwitchMode', function() {
if (editor.readonly) {
editor.readonly = 1;
}
});
}
It exploits the fact that the event-blocking code uses strict comparison internally (readonly === true) while the rest of the code works fine with any other truthy value, e.g. 1. Of course, this hack might stop working after an update in the future, but it's much better than nothing.
Update: better switch to the inline mode (codepen) if you use this hack. Otherwise clicking links leads to a mess.
I have checked the source code of the lastest nightly and it seems that the behavior is hardcoded. All events are discarded if the editor is in readonly mode. Which means that selection events are discarded too :
var isListening = function (editor) {
return !editor.hidden && !editor.readonly;
};
var fireEvent = function (editor, eventName, e) {
if (isListening(editor)) {
editor.fire(eventName, e);
} else if (isReadOnly(editor)) {
e.preventDefault();
}
};
I might be wrong but I don't think you can change this behavior through customization.
Regards
I solved this issue for achieve readonly mode by myself, I would create an iframe dom node and put the editor's html segment into it.
renderReportPreview = contentHtml => {
const iframe = document.querySelector('iframe[name=preview]')
if (iframe) {
const cssLink = document.createElement('link')
// cssLink.href = 'https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css'
// I prefer semantic-ui, semantic-ui is more like tinyMce style
cssLink.href = 'https://cdn.bootcss.com/semantic-ui/2.3.1/semantic.min.css'
cssLink.rel = 'stylesheet'
cssLink.type = 'text/css'
iframe.contentWindow.document.head.appendChild(cssLink)
// I escape the origin editor's content, so I need decode them back
iframe.contentWindow.document.body.innerHTML = htmlDecode(contentHtml)
const allTables = iframe.contentWindow.document.body.querySelectorAll(
'table'
)
Array.from(allTables).forEach(table => {
// ui celled table for compatible semantic-ui
// table table-bordered for compatible bootstrap
table.className = 'ui celled table table-bordered'
})
this.setState({
previewRendered: true,
})
}
}
More detail on https://github.com/tinymce/tinymce/issues/4575
It was previously possible to select text in readonly mode, until the fix for #4249 broke it in 4.7.12.
We've just started tracking a fix that allows text to be selected and links to be clicked, follow either of the tickets linked here to be updated when we release a fix.

Handle Ctrl+Z (undo/redo) for text editor in single page application

I have single page application which consists of a text editor (kendo Editor). The data in the text editor are replaced somewhat like this
$("#editor").kendoEditor({
resizable: {
content: false,
toolbar: true
}
});
var editor = $("#editor").data("kendoEditor");
var setValue = function () {
editor.value($("#value").val());
};
see demo here.
The Issue:
So I am changing record of A then save it. Then I switch to B. Now if I do Ctrl+Z the text editor shows the record of A. How can I prevent this behavior.
Is a way to remove the undo history on demand, or something which would prevent the text editor replacing text with previous record?
Updated: Better Solution.
I contacted Kendo devs and they provided a neat solution.
var editor = $("#editor").data("kendoEditor");
editor.undoRedoStack.clear();
Note: this function is not documented in the public api and is
may change in newer version. This is working as of version
2016.3.1118
demo
Old Solution.
I ended up destroying and rebinding the widget to the textarea.
http://dojo.telerik.com/OjIZe
$("#destroy").click(function(){
var copy=$("#editor").clone();
$("#editor").data('kendoEditor').wrapper.find("iframe").remove();
$("#editor").data('kendoEditor').destroy();
$("#test").empty();
$("#test").append(copy);
$("#editor").kendoEditor({ resizable: {
content: false, toolbar: true
}
});
});

How to set On Off state for CKEditor custom button

I have added a custom plugin to CKEditor inline to perform bold operation. The plugin is working as expected but the on/off state of button is not working.
When command is executed its state is always TRISTATE_OFF.
CKEDITOR.plugins.add( 'customBold', {
requires: 'toolbar',
icons: 'bold',
hidpi: false,
init: function( editor ) {
var boldCommand = {
exec: function( editor ) {
document.execCommand('bold', false, null);
}
}
editor.addCommand( 'bold', boldCommand );
editor.ui.addButton && editor.ui.addButton( 'Bold', {
label: 'bold',
command: 'bold',
toolbar: 'basic,10'
});
editor.setKeystroke( [
[ CKEDITOR.CTRL + 66 /*B*/, 'bold' ]
]);
}
});
When user selects the bold text I would like to toggle the bold style in toolbar.
You need to call the command.setState method which will set the state of the command which then automatically affects the state of related button.
However, you need to know when to call that method (when the state changes). CKEditor's plugins like the basicstyle plugin use the CKEditor's styles system which let them easily listen on style state changes:
editor.attachStyleStateChange( style, function( state ) {
!editor.readOnly && editor.getCommand( commandName ).setState( state );
} );
You, however, try to use the native commands, which I highly recommend not to. It is not a coincidence that CKEditor implements its own style system and its own commands.
I'm answering this purely because this result constantly came up when I was looking how to apply a style to a CKEditor custom plugin button on the toolbar.
This ended up being fairly simple, although not especially elegant.
Currently, I do my own handling of CKEditor buttons (outside of the plugin.js files). This is because I'm using CKEditor to dynamically create editor instances, which it doesn't seem very well suited to do and I often have to override functions.
Here's how I apply a style to a 'active' button in the editor on the myplugin button action:
//Catch the initial click
$('.parent_element').on('click', '.cke_button__myplugin', function(){
//Apply a gradiant style to the button
$('.cke_button__myplugin').css({'background':' radial-gradient(#FFF, #6E6E6E)'})
//Logic to handle button click
});
This way, you simply apply a style to the button without having to toggle the actual button.png

Get UI button clicked on CK Editor toolbar

I have built a very simple plugin for CK Editor (because apparently that's the only way to add a custom button to the toolbar?)
I'd like to know how I can get the DOM ID of my custom button when it is clicked (or any object representative of the button which will allow me to create a jQuery object)
(function () {
CKEDITOR.plugins.add('myplugin', {
icons: 'myicon',
hidpi: true,
init: function (editor) {
editor.addCommand('mycommand', {
exec : function(editor) {
// get button information
}
});
editor.ui.addButton && editor.ui.addButton('MyCommand', {
label: 'Custom Action',
command: 'mycommand',
toolbar: 'insert,5',
icon: 'myicon'
});
}
});
})();
I'd like to attach my own custom UI element to the toolbar when the button is clicked and I need a relative anchor point in order to display it in the correct position on the screen.
I'm using CK Editor 4.2
In your case, you can access the button with the following code (using jQuery):
$(document).on('click', '.cke_button__mycommand', function(){
// do stuff
});
You can inspect the toolbar with your browser to get more information.

Modify CKEditor link dialog to add custom attribute to links

I am using CKEditor on a website and I need to be able to put a special data attributes on some of the links created through the editor. The user would indicate that they need the special attribute put on the link by checking a checkbox in the link dialog. I have managed to add a checkbox to the link dialog with the following code:
CKEDITOR.on('dialogDefinition', function(ev) {
if (ev.data.name == "link") {
var info = dialog.getContents("info");
info.elements.push({
type: "vbox",
id: "urlOptions",
children: [{
type: "hbox",
children: [{
id: "button",
type: "checkbox",
label: "Button",
commit: function(data) {
data.button = this.getValue()
console.log("commit", data.button, data);
},
setup: function(data) {
this.setValue(data.button);
console.log("setup", data.button, data);
}
}]
}]
});
}
});
Now I have two problems. The first one is that despite me adding the code in the commit and setup functions that should save the state of the checkbox, it's not working. It's as if the data can't hold any other parameters but the ones there by default.
The second problem is that I don't know how to add / remove the data attribute on my links. It seems to me that I should be doing that in my onOk callback on the dialog, however, the link dialog already has an onOk callback, so I'm not sure how I should be proceeding. I, of course, do not want to modify any of CKEditor's files directly.
How can I accomplish these things?
You best option is to modify the plugin. So you need to open the source code and find the file links.js in c:\ckeditor_3.6.5\ckeditor\_source\plugins\link\dialogs\
The source code is quite big (40k) but here you can modify the dialog however you want. When you finish just copy it to your plugins folder, and compress it: http://jscompress.com/
I have done what you need myself. The whole uncompressed file is here: https://gist.github.com/3940239
What you need to do:
First add this line just before the dialog "browse" button is appended. Approx. in line: 547:
{
id: "button",
type: "checkbox",
label: "Button",
setup: function (data) {
this.allowOnChange = false;
if (data.button)
this.setValue(data.button);
this.allowOnChange = true;
},
commit: function (data) {
data.button = this.getValue()
this.allowOnChange = false;
}
},
This part is actually your code. I just copied and pasted it.
Then, go to the onOk function, approx. in line 1211: and after commitContent add this code:
this.commitContent( data );
//My custom attribute
if (data.button)
attributes["custom-attribute"] = "button";
else
attributes["custom-attribute"] = "";
This will modify your link adding the attribute to the element such as text
That's it. Although, you may also like to load the current status of the checkbox. Then, go to the function parseLink . Approx. line 179 to load the attributes:
...
if ( element )
{
retval.button = element.getAttribute('custom-attribute');
var target = element.getAttribute( 'target' );
...
I am exploring the same thing now. What I have decided to do at this point is to:
Get a base ckeditor install without the link plugin
create my own fork of the link plugin, and add my changes to it, then activate and use this plugin within the group that link normally shows up in.
...working with it as a custom plugin (albeit a copy of the original) should alleviate the problem of upgrading. You just simply do not use the original link plugin at all. Copy and rename it, and use your custom copy instead.

Categories

Resources