TinyMCE 4.0+ custom button is active and inactive when "Custom formatted" text is clicked

I added a custom button / plugin to tinyMCE 4.0+ that formatted my text with a specific tag. For example: <h1>my clicked text</h1>

. Everything worked fine except that the button was not activated. And when it does activate, it doesn't activate when I click on the already formatted text (like the Bold button when you click on the selected text).

Due to the countless suggestions from Stackoverflow and due to the complete lack of a correct solution (here and in tinyMCE documentation) I wanted to post the solution here. While you can add whatever tags you want, for the purposes of this example, I'm going to add tags <h1>

:

//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');
        }
    });

});

      

Hope this saves you countless frustrating hours !!!

+3


source to share


2 answers


This is exactly what I was looking for! (however I spent a couple of frustrating hours trying to get there: P)

Just wanted to point out a more reliable and general way to detect the button to get rid of the setting 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'));
    })
}

      

+3


source


I wanted to do this with the element class and not the node type. Here's my solution (uses jQuery which is already included - this is 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 css:

.top_margin{ 
    margin-top: 1rem;
}

      

0


source







All Articles