Add new button to WYSIWYG

Nathalie Vallières asked on April 19, 2017 22:21

Hello,

I'm having trouble adding a new button to the CKEditor WYSIWYG bar. I tried following a few documentations, but both solution didn't work. I'm sure it has to do with the complexity of the thing and what I want it to do.

What I need:

I need a new button that when clicked offers 2 textbox, 1 for a question and 1 for an answer, and 1 select for alignment (left or right). When the text is filled in, the client can then insert that into a DIV that will be auto-generated. It will contains a question and the answer. The client wants to put it anywhere he wants, so we have to do it via the editor.

<div class="info-box closed left">
    <span class="corner-orange"></span><span class="exclamation-icon"></span>
    <div class="info-box-content">
        <h4>Question here</h4>
        <p>Answer here</p>
    </div>
    <a href="#" class="open-close"></a>
  </div>

The above is the HTML structure of the DIV that will contains the text inserted (H4 is the question, P is the answer, the class "left" is the alignement).

I have created a new plugin in the plugin folder called "questionanswer" that contains the following files :

/CMSAdminControls/CKeditor/plugins/questionanswer/dialogs/questionanswer.js
/CMSAdminControls/CKeditor/plugins/questionanswer/icons/questionanswer.png
/CMSAdminControls/CKeditor/plugins/questionanswer/plugin.js

In the plugin.js file, I have added the following lines :

config.plugins += ",questionanswer";

config.toolbar_Full = [
    ['questionanswer', '-']
];

Then, in the plugin.js file, I have this as of now (which does not work and was my second iteration, which I tried to copy from a demo example, without success :

CKEDITOR.plugins.add('questionanswer', {
    //lang: 'en',
    icons: 'questionanswer',
    requires: 'widget,dialog,lineutils',
    init: function( editor ) {
        editor.addCommand( 'questionanswer', new CKEDITOR.dialogCommand( 'qaDialog' ) );
        editor.ui.addButton( 'Q&A', {
            label: 'Insert Question & Answer',
            command: 'questionanswer',
            toolbar: 'insert'
        });

        editor.widgets.add('questionanswer', {
            dialog: 'questionanswer',

            init: function () {

            },

            template: '<div class="info-box closed">' + 
                        '<span class="corner-orange"></span><span class="exclamation-icon"></span>' +
                        '<div class="info-box-content">' +
                            '<h4></h4>' +
                            '<p></p>' +
                        '</div>' +
                        '<a href="#" class="open-close"></a>' +
                      '</div>',

            data: function () {

                if (this.data.h4) {
                    element.getElementsByTagName('h4')[0].setText(this.data.h4);
                }

                if (this.data.p) {
                    element.getElementsByTagName('p')[0].setText(this.data.p);
                }

                if (this.data.alignment) {
                    element.className = "info-box closed " + this.data.alignment;
                }
            },

            requiredContent: 'div(info-box)',

            upcast: function (element) {
                return element.name == 'div' && element.hasClass('info-box');
            }
        });

        //CKEDITOR.dialog.add( 'qaDialog', this.path + 'dialogs/questionanswer.js' );
    }
});

And in questionanswer.js :

CKEDITOR.dialog.add( 'questionanswer', function( editor ) {
    return {
        title: 'Question & Answer',
        minWidth: 400,
        minHeight: 200,
        contents: [
            {
                id: 'tab-basic',
                label: 'Basic Settings',
                elements: [
                    {
                        type: 'text',
                        id: 'question',
                        label: 'Question',
                        validate: CKEDITOR.dialog.validate.notEmpty( "Question field cannot be empty." ),
                        setup: function (widget) {
                            this.setValue(widget.data.h4 || '');
                        },
                        commit: function (widget) {
                            widget.setData('h4', this.getValue());
                        }
                    },
                    {
                        type: 'text',
                        id: 'answer',
                        label: 'Answer',
                        validate: CKEDITOR.dialog.validate.notEmpty("Answer field cannot be empty."),
                        setup: function (widget) {
                            this.setValue(widget.data.p || '');
                        },
                        commit: function (widget) {
                            widget.setData('p', this.getValue());
                        }
                    },
                    {
                        type: 'select',
                        id: 'alignment',
                        label: 'Alignment',
                        items: [ 
                            ['Left', 'left'],
                            ['Right', 'right']
                        ],
                        'default': 'left',
                        setup: function (widget) {
                            this.setValue(widget.data.alignment || 'left');
                        },
                        commit: function (widget) {
                            widget.setData('alignment', this.getValue());
                        }
                    }
                ]
            }
        ]
    };
});

I know this is probably not working and it's probably even not close to what I should be doing... I need help in understanding how to correctly add a new interactive button (with the option popup) that the client will be able to fill in and insert into the page. This is what I've got for now, but there are probably errors and invalid stuff in there, I'm still trying to comprehend what I need to do, but I'm starting to get low on time to continue spending time on this issue. If there is anyone who has some experience with adding new plugins to the editor bar, then I will gladly welcome the help.

Thanks!

Correct Answer

Brenden Kehren answered on April 19, 2017 23:19

Instead of modifying the CKEditor, why don't you create a widget and allow that widget to be inserted into the HTML area using the Add Widget icon? A widget can do everything you're looking to do pretty easy without any code modifications.

0 votesVote for this answer Unmark Correct answer

Recent Answers


Nathalie Vallières answered on April 20, 2017 16:03

I also don't have much experience in widgets. Didn't think about that solution. I'll check for more information about it. Thanks for the tip­.

0 votesVote for this answer Mark as a Correct answer

Brenden Kehren answered on April 20, 2017 16:13 (last edited on April 27, 2017 19:06)

Until you learn more about widgets I would not rule it out as a solution, it's much easier than having to code something for that editor.

Another solution would be to create a custom page type and then on the page template add a repeater to display those questions and answers. Again much easier than having to code for that editor

0 votesVote for this answer Mark as a Correct answer

Nathalie Vallières answered on April 20, 2017 16:47

Yeah, I can do that for static elements, I do use a repeater for a few things and that was what I would have done. Unfortunately, the client paid to have something that can be placed anywhere. It's a little Q&A popup thingy. At first, I thought it would be easy to add a button to the editor, but I crashed into that wall. I looked up widgets and it looks like it will be a lot more easier, so I thank you for the suggestion.

I've used the repeater for accordions, tabs and other things, but there's a limited time I can use it without having to put up 5 wysiwyg editors for each page since they are often in the middle or the text. But this widget can't be used in a repeater since she wants to place 2 or even 3 separated by text here and there in the page so I had to come up with a solution that can integrate in the editor. Widgets should be good enough.

I wonder why it can't have an easy out-of-the-box solution like Wordpress. Adding new buttons and functionality in Wordpress is a piece of cake compared to this.

Anyways, thanks again. I've already created my webpart to use as a widget, so I'll see how it goes.

0 votesVote for this answer Mark as a Correct answer

Brenden Kehren answered on April 27, 2017 19:09

Comparing Kentico to Wordpress is like comparing apples to people and expecting a valid comparison. There is no comparison. Kentico has all the tools to create whatever you want, just need to know which tools to use for which solution.

0 votesVote for this answer Mark as a Correct answer

Nathalie Vallières answered on April 27, 2017 19:21

That's for sure. I find Wordpress much easier to develop with, but also much more limited indeed. The environment is much more controlled.

I hadn't touched Kentico for about 3 years, so going back into Kentico after 3 years of developing Wordpress sites is a bit of a challenge, even more so since Kentico has also changed a lot between version 5 and 9. But I still enjoy developing with Kentico.

I have used the widget way and it was perfect for my needs. It was easy to configure and add my module, so I will probably take this approach if I need to do something similar again in the future.

Anyways, thanks for your suggestion, it helped greatly.

0 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.