I'm trying to create a custom plugin for TinyMce.
This is my code so far:
(function() {
var redactor = (function(domGlobals) {
'use strict';
var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
var setupButtons = function(editor) {
editor.ui.registry.addToggleButton('link', {
text: 'My button',
tooltip: 'My button',
onAction: function() {
alert('My Button');
}
});
};
var Controls = {
setupButtons: setupButtons,
};
global.add('redactor', function(editor) {
Controls.setupButtons(editor);
});
function Plugin() {}
return Plugin;
}(window));
})();
This is my init:
tinymce.init({
selector: '#editor',
plugins: 'redactor',
toolbar: 'redactor',
menubar: 'redactor'
});
My editor renders without any button and no JS error on it.
What am I doing wrong? I tried to emulate some of the plugins but I cant get it to work.
Seems that I needed to search a little bit more in the documentation. I have to add each button manually to the toolbar:
tinymce.init({
selector: '#editor',
plugins: 'redactor',
toolbar: 'redactorBtn1',
menubar: 'redactor'
});
and each name should be unique for the plugin:
So, the code for my plugin:
(function () {
var redactor = (function (domGlobals) {
'use strict';
var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
var setupButtons = function (editor) {
editor.ui.registry.addToggleButton('redactorBtn1', {
text: 'My button',
tooltip: 'My button',
onAction: function () {
alert('My Button');
}
});
};
var Controls = {
setupButtons: setupButtons,
};
global.add('redactor', function (editor) {
Controls.setupButtons(editor);
});
function Plugin () {
}
return Plugin;
}(window));
})();
If you want to add more buttons to the toolbar, you have to put them one by one:
toolbar: 'redactorBtn1 redactorBtn2',
Its old code, at tinyMCE they change everything now and then. A good example is the code plugin. Copy this code plugin to a directory named: custom. Change the names code in the plugin.js file to custom and add custom to the plugins array and the toolbars string in tinymce.init function and you are ready to go.
Related
I'm trying to implement inside tinymce a custom button, that when clicked, would add a class around the selected text.
I've tried this :
editor.ui.registry.addButton('fwnormal', {
text: 'N',
class: 'nongras'
});
But it doesn't work, I get an error Could not find valid *strict* value for "onAction"
Any idea how can I do that?
https://www.tiny.cloud/docs/configure/content-formatting/
Use the codes like these:
tinymce.init({
selector: "#mytextarea",
tinymce options: ... ,
toolbar: "add_class",
setup: function(editor) {
editor.on("init", function(e) {
tinymce.activeEditor.formatter.register("new_class", {
selector: "p,div,h1,h2,h3,h4,h5,h6", // choose elements
classes: "myclass",
styles: { ... },
attributes: { ... },
}); // close formatter.register
}); // close editor.on init
editor.ui.registry.addButton("add_class", {
tooltip: "new class",
icon: "edit-block", // look editor-icon-identifiers page
onAction: function() {
tinymce.activeEditor.formatter.apply("new_class");
}
}); // close registry.addButton
}, // close setup function
}); // close tinymce.init
Or try these codes:
tinymce.init({
selector: "#mytextarea",
tinymce options: ... ,
toolbar: "add_class",
setup: function(editor) {
editor.ui.registry.addButton("add_class", {
tooltip: "new class",
icon: "edit-block", // look editor-icon-identifiers page
onAction: function() {
var element = tinymce.activeEditor.selection.getNode();
tinymce.activeEditor.dom.setAttrib(element, "class", "myclass");
}
}); // close registry.addButton
}, // close setup function
}); // close tinymce.init
Custom classes are set in the style_formats https://www.tiny.cloud/docs/configure/content-formatting/
example
tinymce.init({
selector: 'textarea',
style_formats: [
{title: 'Class name', selector: 'p', classes: 'myclass'}
]
});
http://fiddle.tinymce.com/Slhaab
I am trying to create toolbar button in TinyMCE with options that are derived from the array. I've followed the examples on Tiny's website and the button is getting generated as expected. Here is the code:
var mergeFields = {one: "first", two: "second", three: "third"};
tinymce.init({
selector: 'textarea',
menubar: false,
toolbar: 'mergefields',
setup: function (editor) {
editor.ui.registry.addMenuButton('mergefields', {
text: 'Merge Fields',
fetch: function (callback) {
var items = [];
for (var fieldName in mergeFields) {
var menuItem = {
type: 'menuitem',
text: mergeFields[fieldName],
onAction: function() {
// The problem: this function always inserts the last element of the array
// instead of the expected fieldName associated with this menuItem
editor.insertContent(fieldName);
},
};
items.push(menuItem);
}
callback(items);
},
});
}
});
<script src="https://cloud.tinymce.com/5/tinymce.min.js?apiKey=XXXXX"></script>
<textarea>Editor</textarea>
The problem happens when one of the options is selected and the anonymous function assigned to onAction property is executed -- it always inserts "three" into the document (presumably because after running through the whole array, fieldName is set to "three"). How can I make the onAction handler insert the right value into the document?
This needs to work in TinyMCE 5.
I've found a similar question here: Adding custom dropdown menu to tinyMCE and insert dynamic contents, but it was referring to TinyMCE 4 and unfortunately the provided answer does not work for TinyMCE 5.
Thanks for your help!
I had the same problem.
I solved it using value+onSetup
https://jsfiddle.net/stvakis/tjh7k20v/8/
var mergeFields = {
one: "first",
two: "second",
three: "third"
};
tinymce.init({
selector: 'textarea',
menubar: false,
toolbar: 'mergefields',
setup: function(editor) {
editor.ui.registry.addMenuButton('mergefields', {
text: 'Merge Fields',
fetch: function(callback) {
var items = [];
for (var fieldName in mergeFields) {
var menuItem = {
type: 'menuitem',
text: mergeFields[fieldName],
value:fieldName,
onSetup: function(buttonApi) {
var $this = this;
this.onAction = function() {
editor.insertContent($this.data.value);
};
},
};
items.push(menuItem);
}
callback(items);
},
});
}
});
I want to add custom tool in kendo editor.
It is pretty good in jQuery method via directive, But have problem with model binding.
It seems I have to use angular method like this:
<textarea naccordion id="htmleditor" ng-model="Model._Active.Paragraph" class="editor" k-options="accordion" k-encoded="false" kendo-editor k-tools="['fontName','bold','italic','underline','strikethrough','fontSize','justifyLeft','justifyCenter','justifyRight','justifyFull','foreColor','insertUnorderedList','insertOrderedList','indent','outdent','createLink','unlink','insertImage','cleanFormatting','backColor','viewHtml','formatting']"></textarea>
So, I put my k-options code in controller:
$scope.accordion = {
tools:
{
name: "accordion",
tooltip: "Accordion items",
exec: function (e) {
var editor = $(this).data("kendoEditor");
editor.exec("inserthtml", {
value: "<accordion close-others='true'><accordion-group is-open='Model._openSettings'><accordion-heading>[Title]</accordion-heading><br>[Text]</accordion-group></accordion>"
});
}
}
};
It is not work.
I do not know what is accordion scope is right or no?
Any idea?
tools needs to be an array:
$scope.accordion = {
tools:[
{
name: "accordion",
tooltip: "Accordion items",
exec: function (e) {
var editor = $(this).data("kendoEditor");
editor.exec("inserthtml", {
value: "<accordion close-others='true'><accordion-group is-open='Model._openSettings'><accordion-heading>[Title]</accordion-heading><br>[Text]</accordion-group></accordion>"
});
}
}
]
};
I'm trying to use bootstrap-markdown and everything works fine except I can't call the plugin via JavaScript. For instance:
$("#content").markdownEditor({
autofocus: false,
savable: false,
iconlibrary: 'fa',
resize: 'vertical',
additionalButtons: custom_buttons, // an array defining custom commands
onPreview: function (e) {
var content = e.getContent();
console.log('content', content);
}
});
Does anyone has any ideas what might be the case? Couldn't find anything useful on the web or repo's github page. And yes I've already included markdown.js and to-markdown.js which weren't mentioned in the docs at all but it was quick find anyway.
All I need now is to call the editor, add a couple of custom toolbar buttons (image upload, code block insert etc.) and be done with it.
Code snippets, links & live fiddles are much appreciated :)
For some reason, changing the order of script references fixed this.
Here's the order now:
lib/markdown.js
lib/bootstrap-markdown.js ,
lib/to-markdown.js
And here's my initialization:
$(function () {
var custom_buttons = [[
{
name: "insertCode",
data: [{
name: "cmdInsertCode",
toggle: "toggle",
title: "Insert Code",
icon: "fa fa-fire",
callback: function (e) {
var selected = e.getSelection(),
content = e.getContent();
// e.replaceSelection(chunk);
// var cursor = selected.start;
//e.setSelection(cursor, cursor + chunk.length);
console.log('cmdInsertCode clicked');
}
}]
}
]];
$("#content").markdown({
autofocus: false,
savable: false,
iconlibrary: 'glyph',
resize: 'vertical',
additionalButtons: custom_buttons,
onShow: function (e) {
console.warn('e:editor shown');
}
});
});
Kudos :godmode:
I try to implement Summertnote editor. Here is the JS code:
$(document).ready(function() {
//Summernote
//var te_markdown = document.getElementById("code-markdown");.
var textarea = document.getElementById("code");
var HelloButton = function (context) {
var ui = $.summernote.ui;
// create button
var button = ui.button({
contents: '<i class="fa fa-child"/> Hello',
tooltip: 'Ciao!',
click: function () {
// invoke insertText method with 'hello' on editor module.
context.invoke('editor.insertText', 'hello');
}
});
return button.render(); // return button as jquery object
}
function autoFormat() {
var totalLines = editor.lineCount();
editor.autoFormatRange({line:0, ch:0}, {line:totalLines});
}
$('#st-editor').summernote({
lang: 'it-IT', // set italian language
height: 350, // set editor height
width: 350, // set editor width
minHeight: null, // set minimum height of editor
maxHeight: null, // set maximum height of editor
dialogsFade: true, // set fade on dialog
prettifyHtml: false,
toolbar: [
['mybutton', ['hello']]
],
buttons: {
hello: HelloButton
},
codemirror: { // codemirror options
mode: "text/html",
lineNumbers: true,
lineWrapping: true,
extraKeys: {"Ctrl-Q": function(cm){ cm.foldCode(cm.getCursor()); }},
foldGutter: true,
theme: 'monokai',
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
}
},
focus: true set focus to editable area after initializing summernote
});
I get the code here: http://summernote.org/deep-dive/#custom-button
So, In this example I want to simply put a "Hello" string clicking the button but it gives me an error "TypeError: context is undefined". Can someone help me?
Thanks
Instead of
context.invoke('editor.insertText', 'hello');
use
$('#st-editor').summernote('editor.insertText', 'hello');
works only if you have one editor of course. I'm still searching how to get this context thingy passed. Maybe something with onInit, but I couldn't get it working yet.
#wessel code works, for multiple ids I do an iteration using jQuery each:
Make sure oyu attach an id attribute to all editors:
if ($('.summernote').length) {
var blockQuoteButton = function(itemId) {
var ui = $.summernote.ui;
var button = ui.button({
className: 'note-btn-blockquote',
contents: '<i class="fa fa-quote-right">Quo</i>',
tooltip: 'Blockquote',
click: function() {
$('#' + itemId).summernote('editor.formatBlock', 'blockquote');
}
});
return button.render();
}
$('.summernote').each(function(k, item) {
let itemId = $(item).attr('id');
$('#' + itemId).summernote({
height: 100,
toolbar: [
['style', ['style']],
['font', ['bold', 'italic', 'underline']],
['para', ['ul', 'ol']],
['mybutton', ['blq']]
],
buttons: {
blq: blockQuoteButton(itemId)
}
});
});
}
This issue appeared in version 0.8.12. Reverting back to 0.8.10 fixes it
Inside package.json specify
"dependencies": {
...
"ngx-summernote": "0.7.0",
"summernote": "0.8.10",
...
},
and run npm install afterwards. It works after that