I added a custom button/plugin to tinyMCE 4.0+ which formatBlocked my text with a specific tag. For example: <h1>my clicked text</h1>
. Everything worked great except for the fact that the button would not activate. And when it did activate, it wouldn't activate when I clicked on the text that was already formatted, (like the Bold button does when you click on bolded text).
In thanks to the countless suggestions from Stackoverflow and because of the complete lack of a proper solution (here and on the tinyMCE Documentation) I wanted to post the solution here. Although you can add any tags that you'd like, for the purposes of this example, I'm going to add <h1>
tags:
//Add the plugin to tinyMCE.init
tinymce.init({
selector: \"div.editable\",
inline: true,
plugins: 'addh1s'
toolbar: 'addh1s'
//etc...
});
//Then create a folder entitled, 'addh1s' in the tinyMCE 'plugins' folder
//and add the plugin.min.js file that contains the following code.
//*Please note that the number '27' below is the number in order of the
//'addh1s' button on my tinyMCE toolbar. In your case it can be the
//number of where your button appears on your toolbar.
tinymce.PluginManager.add('addh1s', function(editor, url) {
editor.addButton('addh1s', {
title: 'Add H1 tags',
image: '../images/h1.png',
onPostRender: function() {
editor.on('NodeChange', function(e) {
if (editor.formatter.match('h1')) {
tinymce.activeEditor.theme.panel.find('toolbar *')[27].active(true);
}
else {
tinymce.activeEditor.theme.panel.find('toolbar *')[27].active(false);
}
});
},
onclick: function() {
tinyMCE.activeEditor.execCommand('FormatBlock', false, 'h1');
}
});
});
I hope this saves you countless frustrating hours!!!
This is exactly what I was looking for! (however I spent a couple of frustrating hours while trying to get there :P)
Just wanted to note down a more reliable and generic way I found to identify the button, to get rid of the customization for the 28th button.
onPostRender: function() {
var _this = this; // reference to the button itself
editor.on('NodeChange', function(e) {
_this.active(editor.formatter.match('h1'));
})
}
I wanted to do this with an element's class, rather than its node type. Here's my solution (uses jQuery, which is included already - this being a Wordpress build )
ed.addButton('add_top_margin',{
title : 'Add extra margin to the top of this element',
text : 'Add Top Margin',
onclick : function(){
ed.dom.toggleClass( ed.selection.getNode(), 'top_margin' );
this.active( !this.active() ); //toggle the button too
},
onPostRender: function() {
var _this = this; // reference to the button itself
ed.on('NodeChange', function(e) {
//activate the button if this parent has this class
var is_active = jQuery( ed.selection.getNode() ).hasClass('top_margin');
_this.active( is_active );
})
}
})
and the css:
.top_margin{
margin-top: 1rem;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With