bricker
bricker

Reputation: 8941

Dynamically add UI Elements in CKEditor Dialog

I'm trying to trigger a callback to dynamically populate a CKEditor dialog with checkboxes when the dialog is opened. I've read other solutions that use iframes, but this won't work for me because the dialog needs to be populated based on other elements on the same page.

Here is what I have so far. There are no errors, but the dialog is just empty when it opens. I expect the addContents function to fill in the dialog. I've confirmed that dialog.definition.contents does include the contents and elements that I want, but it's just not filling in the actual dialog. What am I missing?

(function() {
    CKEDITOR.plugins.add( 'embeds', {
      icons: 'embed',
      init: function(editor) {
        var self = this,
            elements = [];


        CKEDITOR.dialog.add('EmbedsDialog', function (instance) {
          return {
            title : 'Embeds',
            minWidth : 550,
            minHeight : 200,

            contents: [],

            onShow: function() {
              var dialog = this,
                  elements = [];

              $('#embeds-fields tr').each(function() {
                var title = $(this).find('input[type=text]').val(),
                    url   = $(this).find('input[type=url]').val();

                if(url != "") {
                  elements.push({
                    label : "embed",
                    title : url,
                    type : 'checkbox'
                  });
                }
              });

              dialog.definition.removeContents('embeds');

              dialog.definition.addContents({
                id : 'embeds',
                expand : true,
                elements : elements
              });
            },
          }; // return
        });

        editor.addCommand('Embeds',
          new CKEDITOR.dialogCommand('EmbedsDialog', {
            allowedContent: 'a[*](*)'
          })
        );

        editor.ui.addButton('Embeds', {
          label     : 'Embeds',
          command   : 'Embeds',
          toolbar   : 'embeds'
        });
      } // init
    }); // add
})(); // closure

Upvotes: 2

Views: 4962

Answers (1)

bricker
bricker

Reputation: 8941

Based off of this example, I ended up with this solution, where "main" is the ID of the original content.

CKEDITOR.on('dialogDefinition', function(ev) {
  var dialogName = ev.data.name;
  var dialogDefinition = ev.data.definition;

  if (dialogName == 'EmbedsDialog') {
    var main = dialogDefinition.getContents('main');

    $('#embeds-fields tr').each(function() {
      var title = $(this).find('input[type=text]').val(),
          url   = $(this).find('input[type=url]').val();

      if(url != "") {
        main.add({
          type : 'checkbox',
          label : title,
        });
      }
    });
  }
});

Upvotes: 4

Related Questions