I know I can add buttons in TinyMCE 4 using addButton . But when I use addButton and enter a title for it, only an empty button is shown in the editor with a tooltip that contains the content of title. How do I add a title, that is actually shown in the menubar, like for the save button?
// Create and render a button to the body element
tinymce.ui.Factory.create({
type: 'button',
text: 'My button'
}).renderTo(document.body);
I found the solution, thanks to Eslam.
You actually just set the 'text' value of addButton:
$('#site_content').tinymce({
setup : function(ed) {
ed.addButton('name', {
text : 'TEXT',
onclick : function() {
}
});
}
});
The documentation of TinyMCE is just awful at some parts, if you'd ask me
Related
I started creating my own CK5 Editor plugins, and am now stuck at the plugin for creating a custom call-to-action button.
What I want
I've created a button in the editor toolbar to create a new button. What I want to happen is that a button element is created, and the user is able to edit it's textual content.
<button> [this must be editable text] </button>
Where I got stuck
So I made it so far that a button element is created as soon as I click on the action in the toolbar. But as soon as I start typing, the button disappears and a paragraph is created. It looks like the cursor is inside the button element though. I've been reading through the API documentation for a while now, but I didn't get any further.
My code so far
First I register the callToAction schema
const schema = this.editor.model.schema
schema.register('callToAction', {
isObject: true,
allowWhere: '$block',
inline: true
})
Then I define the converters
conversion.for('upcast').elementToElement({
model: 'callToAction',
view: {
name: 'button',
classes: 'cta-button'
}
})
conversion.for('dataDowncast').elementToElement({
model: 'callToAction',
view: {
name: 'button',
classes: 'cta-button'
}
})
conversion.for('editingDowncast').elementToElement({
model: 'callToAction',
view: (modelElement, viewWriter) => {
/* The Button element is editable on selection */
const button = viewWriter.createContainerElement('button', {
class: 'cta-button',
})
/* Makes the element editable */
return toWidgetEditable(button, viewWriter)
}
})
I Also created a command to execute the creation of the button element
function createCallToAction(writer) {
const callToAction = writer.createElement('callToAction')
return callToAction
}
The actual question
How can I create the button with a standard placeholder text, let's say Enter text, and let the user edit this text inside the button? I've searched the internet for answers, looked at other plugins, but didn't get the solution I need.
Hope someone can help me, or at least send me in the right direction.
Thanks in advance
I believe, toWidgetEditable(button, viewWriter) does not change the 'editability' of an element, it just creates the widget. So when you create a container-element with:
const button = viewWriter.createContainerElement('button', {
class: 'cta-button',
})
This cannot later on 'become' editable.
Instead, create an editable element with:
const button = viewWriter.createEditableElement('button', {
class: 'cta-button',
})
So I'm thoroughly confused as how to make a custom SummerNote button which will allow me to either add classes to an already inserted HTML element (i.e. links) or even wrap selected text in something like:
<button class="btn btn-primary"> **selected text** </button>
From the Summernote Deep Dive it shows how to create a custom button that inserts static text and I understand how to implement it. However, I can't seem to figure out how to make it dynamic for whatever text is selected. I've tried replacing the 'text' part of the example after context.invoke call but it doesn't convert the text to html, it just prints it.
The need is for creating links as buttons. Ideally I'd wish to access the Insert Link dialog already built into SummerNote to make buttons that will insert links with predefined classes but I'm not sure how complicated that would be.
Does anyone have any suggestions?
var bsButton = function (context) {
var ui = $.summernote.ui;
// create button
var button = ui.button({
contents: 'Btn',
tooltip: 'Create Button',
click: function () {
// invoke insertText method with 'hello' on editor module.
context.invoke('editor.insertText', '<button class="btn btn-primary"></button>');
}
});
return button.render(); // return button as jquery object
}
I've reviewed a ton of different posts but I haven't gotten much further than the example for what I'm trying to accomplish. Thanks in advance to anyone who takes the time to help.
As I was doing more research I stumbled upon Summernote's 'Awesome Summernote' GitHub page which led me to a plugin, summernote-addclass. While this doesn't necessarily answer the heart of the question (i.e. achieving this same thing without a plugin) but it does exactly what I need to do. Maybe this will help someone else in the future. Enjoy!
By using jQuery in summernote callback method onInit I have added custom class for custom button
Here is my custom button code:
var AddPage = function(context) {
var ui = $.summernote.ui;
var button = ui.button({
contents: '<i class="fa fa-plus"/> Add Page',
tooltip: "Set a New Page",
class: "btn-primary",
click: function() {
addPage();
}
});
return button.render();
};
And i use callback methods to add custom class btn-primary to the button
$("#editor").summernote({
airMode: false,
dialogsInBody: false,
toolbar: [["mybutton", ["customButton"]],
buttons: {
customButton: AddPage
},
callbacks: {
onInit: function(e) {
var o = e.toolbar[0];
jQuery(o)
.find("button:first")
.addClass("btn-primary");
}
}
});
});
I think this may be helpful for anyone, even if this is not gud answer.
I am trying to create a card that would have action on clicking "select" button and still have scrollable text, something like:
var card = new UI.Card({
title: 'Title',
body: 'long text goes here...',
action: {
select: 'images/refresh.png',
backgroundColor: 'white'
},
scrollable: true
});
card.on('click', function(e) {
if (e.button == 'select') {
//some code
}
});
if executed like this - icon in action bar is visible and "click" event runs, but "scrollable: true" no longer has effect. If I comment "action" property - "click" event still runs and this time "scrollable: true" is working, but of course no icon is displayed. Is it a bug or is it by design? How can I have best of both worlds - display icon for "select" and keep card scrollable?
Thanks to this question, I've made a commit that will allow you to use the action bar layer and scroll layer at the same time: https://github.com/pebble/pebblejs/commit/04f926f137395a0ebd0faaab8b0722da9aa75a7d.
I'll update this answer when the commit is merged into CloudPebble.
Edit: Added a fiddle example- http://fiddle.tinymce.com/EZbaab/2
I currently have a page with a tinyMCE instance on it and three separate textareas that inherit it.
I have a custom menu that has clickable sub-menu items on it (generated using Django), that when clicked, insert content into the currently active tinyMCE editor (textarea). The trouble is, this happens regardless of WHICH editor toolbar was clicked. So for example if I click the top editor's toolbar item, but have the bottom editor focused, the text gets pasted into the bottom editor.
I need to either force the editor that has it's toolbar clicked to become focused when a menu item is clicked (which happens for the default buttons like bold, italic, underline, but not for my custom menu items)
or I need to pass the instance id of the editor that was clicked into the function that pastes in the text somehow. The difficulty is I'm struggling to find any reference to these two tasks in the documentation.
The tinyMCE init code:
tinyMCE.init({
forced_root_block : false,
force_br_newlines : true,
force_p_newlines : false,
mode : "textareas",
theme : "advanced",
plugins : "contextmenu,paste,save,-stdpara",
theme_advanced_buttons1 : ",bold,italic,underline,cleanup,|,undo,redo,|,cut,copy,paste,|,stdpara",
theme_advanced_buttons2 : "",
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left",
force_br_newlines : true,
force_p_newlines : false,
forced_root_block : '',
});
(Where stdpara is my custom menu plugin):
The menu code (stripped out the django and just added some random data:
tinymce.create('tinymce.plugins.StandardParagraphPlugin', {
createControl: function(n, cm) {
switch (n) {
case 'stdpara':
var c = cm.createSplitButton('stdparagraph', {
title : 'Standard Paragraph',
image : 'img/para.png',
});
c.onRenderMenu.add(function(c, m) {
m.add({title : 'Standard Paragraphs', 'class' : 'mceMenuItemTitle'}).setDisabled(1);
category_menu = m.addMenu({title : 'Some Title'});
category_menu.add({title : 'Some sub-title', onclick : function() { tinyMCE.activeEditor.execCommand('mceInsertContent',false,'The Text') });
}});
return c;
}
return null;
}
});
I need to either force the editor that has it's toolbar clicked to
become focused when a menu item is clicked (which happens for the
default buttons like bold, italic, underline, but not for my custom
menu items)
This is correct, but the problem lies here
tinyMCE.activeEditor.execCommand('mceInsertContent',false,'The Text')
This will execute the command on the active Editor. tinyMCE.activeEditor gets reset when the user clicks into the editor for example.
It will be better to address the editor to which the drop-down belongs to.
It is somewhat tricky and does not look very elegant, but as long as tinymce does not change the button logic and naming it will be proof for tinymce updates. See my tinymce fiddle here: http://fiddle.tinymce.com/IZbaab/1
For future troubleshooters
The second parameter of createControl(n, cm) - so, the 'cm' parameter- is the contentManager.
To get the current editor, you can simply call cm.editor
To insert content: cm.editor.execCommand('mceInsertContent', false, 'my text')
Don't know if it helps, but I select the respective Text-Field like:
tinyMCE.get('yourtextareaid').execCommand('mceInsertContent', false, 'bla');
I'm testing a tooltip plugin and it will display a tooltip on mouseover. I'm trying to make the tooltip appear with an onclick, which I'm struggling and need your help.
I'm currently using a jquery piece so it will activate a modal window, thanks to #pointy, when the links within the tooltip is clicked. Can something like this be included with jQuery?
Demo: http://jsbin.com/eliwa3
Here is the page code that calls the functionality and tooltip content
<script>
dw_Tooltip.defaultProps = {
sticky: true,
klass: 'tooltip',
showCloseBox: true,
klass: 'tooltip2', // class to be used for tooltips
closeBoxImage: 'http://www.google.com/apps/images/x.png',
wrapFn: dw_Tooltip.wrapSticky
};
dw_Tooltip.on_show = function() {
$(".modalPageWide").colorbox({
width:"800px",height:"610px",opacity:0.6,iframe:true
})
};
dw_Tooltip.content_vars = {
tooltip_popup: {
content: 'Click a link to continue' +
'<ul><li>Link 1</li>' +
'<li>Link 2</li>' +
'<li>Link 3</li>' +
'<li>Link 4</li></ul>',
klass: 'tip'
}
}
</script>
As shown below, when a link includes a reserved class "showTip", it will activate the tooltip on mouseover. Also included is a compound class (of my choice) that will call the tooltip content
Example
Here's the logic that makes the tooltip work: Tooltip logic
basically all you would need to do it something like
$('a.tooltip_popup').click(function(e){
e.preventDefault();//so link doesn't take you to where ever it's supposed to
//code that brings the tooltip up
});