Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic menu for a RichCombo box in CKEditor

I've written a plugin which adds a RichCombo box to my CKEditor. I want to be able to update the content in the ListBox within this RichCombo

Here's my code.

var merge_fields = [];

CKEDITOR.plugins.add('mergefields',
{
    requires: ['richcombo'], //, 'styles' ],
    init: function (editor) {
        var config = editor.config,
           lang = editor.lang.format;

        // Gets the list of tags from the settings.
        var tags = merge_fields; //new Array();

        // Create style objects for all defined styles.
        editor.ui.addRichCombo('tokens',
        {
            label: "Merge",
            title: "title",
            voiceLabel: "voiceLabel",
            className: 'cke_format',
            multiSelect: false,

            panel:
            {
                css: [config.contentsCss, CKEDITOR.getUrl(CKEDITOR.skin.getPath('editor') + 'editor.css')],
                voiceLabel: lang.panelVoiceLabel
            },

            init: function () {
                // this.startGroup("mergefields");
                for (var this_tag in tags) {
                    this.add(tags[this_tag], tags[this_tag], tags[this_tag]);
                }
            },

            onClick: function (value) {
                editor.focus();
                editor.fire('saveSnapshot');
                editor.insertText(value);
                editor.fire('saveSnapshot');
            }
        });
    }
});

Unfortunately this list is not update when merge_fields changes. Is there a way to reinitialize the plugin, or failing that remove it and re-add it with updated content?

Note Id prefer NOT to have to remove the entire editor and replace it, as this looks very unpleasant to the user

UPDATE

As requested, here's a jsfiddle to help

http://jsfiddle.net/q8r0dkc4/

In this JSFiddle, you'll see that the menu is dynamically created the first time it is accessed. It should should the checkboxes which are selected. However, every subsequent time it is accessed, it keeps the same values and is not updated. The only way to update it is to reinitialise the editor using the reinit button I have provided, but this causes the editor to disappear and reappear, so I don't want to have to do this.

200 points of a bounty to someone who can make the dropdown dynamically update EVERY TIME it is called.

like image 596
roryok Avatar asked Oct 15 '14 14:10

roryok


People also ask

How does CKEditor work with list items?

It receives the value of the list item, which gets split out into the id and name. These are used to create a link, which is inserted as HTML into the editor screen at the carat. The call to saveSnapshot creates a save point, allowing the Undo plugin to be used if desired. CKEditor makes it easy to modify the editor's configuration.

What is the CKEditor drop-down plugin?

rescaled, optimized, responsive and delivered through a CDN. This plugin provides the main class that includes a set of methods used for constructing drop-downs like Styles, Format, Font Size and Font Family to be used in the CKEditor UI. This is an official plugin provided and supported by CKEditor developers.

How to modify CKEditor's configuration?

CKEditor makes it easy to modify the editor's configuration. In the root directory of the CKEditor installation is a file called config.js, which is called every time an instance of the editor is initialized. Normally, the function it holds is empty; it is here that we add the plugin and set up the menu to show it.

How do I install CKEditor add-ons?

This is an official plugin provided and supported by CKEditor developers. You can submit bug reports directly to its GitHub issues tracker and discuss any integration issues on StackOverflow. The recommended way to install all CKEditor add-ons is to create a custom build by using Online builder.


1 Answers

How about using CKEditors custom events something like this ?

First get reference to CKEditors instance

var myinstance = CKEDITOR.instances.editor1;

Since the checkboxes are outside the scope of CKEditor add a change handler to checkboxes

$(':checkbox').change(function () {
    myinstance.fire('updateList'); // here is where you will fire the custom event
});

Inside plugin definition add a event listener on the editor like this

editor.on("updateList", function () { // this is the checkbox change listener
  self.buildList(); // the entire build is created again here
});

Instead of directly attaching events on checkboxes (which are outside the scope of CKEditor) inside the plugin, I am using CKEditor's custom events. Now the editor instance and checkboxes are decoupled.

Here is a DEMO

Hope this helps

Update

Option 2

Plugin's methods can directly be called like this

$(':checkbox').change(function () {
    CKEDITOR.instances.editor1.ui.instances.Merge.buildList(); //this method should build the entire list again
});

Even though this seems very straightforward, I don't think it is completely decoupled. (But still works)

Here is a demo for option 2

like image 133
Dhiraj Avatar answered Oct 13 '22 00:10

Dhiraj