Making a custom spoiler-plugin for CKEDITOR

In this article, we are going to observe popular HTML editor — CKEDITOR and show how to create a custom plugin bootstrap-spoiler.

When Smart Gamma develop the admin part of our web apps, we often face a need to integrate various HTML editors. This is the best way to let the user, who is not familiar with web development, to fill his website with content and change interface. However, oftentimes we see that editors just don’t have the functionality we need.

This plugin is going to use bootstrap.css styles. That is why we need to set it for our editor and our final page with content. The structure of our plugin is next:

In the dialogs folder we create a spoiler.js file, which will create a dialogue window that inputs HTML content to our page.

CKEDITOR.dialog.add( 'spoiler', function( editor ) {
// Functions that hide/unhide our content
function toggle( element ) {
 element.setStyle('display',((element.getStyle('display')=='none' )?'':'none'));
}
function setSwitcher( element )
{
   var content = element.getParent().getLast();
   toggle( content );
}
//Function for creating HTML container.
function createSpoiler(className) {
  var spoilerContainer = editor.document.createElement( 'div',
                { 'attributes' : { 'class': 'panel '+ className } }
        );
  var spoilerTitle = editor.document.createElement( 'div',
        {'attributes':{ 'class': 'spoiler-header panel-heading clickable' } }
      );
 
  var spoilerContent = editor.document.createElement( 'div',
                { 'attributes' : { 'class': 'panel-body' } }
        );
// We put onclick event on spoilers header to hide/unhide the content (current event works only inside the editor)
  spoilerTitle.on( 'click', function( event ) {
     setSwitcher( event.sender );
  });
  spoilerTitle.appendHtml( '<br>' );
  spoilerContent.appendHtml( '<p><br></p>' );
  spoilerContainer.append( spoilerTitle );
  spoilerContainer.append( spoilerContent );
  return spoilerContainer;
}
// We configure our dialogue window (insert our content with a description and a radio button to choose the spoiler type).
    return {
        title: 'Create spoiler.',
        minWidth: 400,
        minHeight: 100,
        contents: [
            {
                id: 'spoiler-dialog',
                label: '',
                title: '',
                elements: [
                    {
                        type : 'html',
                        html : 'This dialog window lets you create bootstrap-                                                spoiler for your website.'
                    },
                    {
                        type: 'radio',
                        id: 'spoiler-type',
                        label: 'Select the type of spoiler',
                        items: [
                            [ 'Spoiler Success', 'panel-success' ],
                            [ 'Spoiler Warning', 'panel-warning' ],
                            [ 'Spoiler Danger', 'panel-danger' ],
                            [ 'Spoiler Info', 'panel-info' ]
                        ],
                        style: 'color: green',
                        'default': 'panel-success',
                    }
                ]
            }
        ],
// After pressing the “OK” button we  call the function that we created earlier and then we insert next HTML code to our editor.
        onOk: function() {
            var spoiler = createSpoiler(this.getValueOf( 'spoiler-dialog',                                                 'spoiler-type' ));
            editor.insertElement( spoiler );
        }
    };
});
The dialogue window is ready. Now let’s get to the plugin

CKEDITOR.plugins.add( 'spoiler' , {
// We configure all possible languages and choose the icon that will be outputted on our tool bar
   lang: 'en,ru',
   icons: 'spoiler',
   init: function( editor ) {
      var pluginName = 'spoiler';
      var path = this.path;
      if ( editor.blockless )
         return;
      function getDivWithClass( className )
      {
         var divs =  editor.document.getElementsByTag( 'div' ),
            len = divs.count(),
            elements = [],
            element;
         for ( var i = 0; i < len; ++i ) {
            element = divs.getItem( i );
            if ( element.hasClass( className ) ) {
               elements.push( element );
            }
         }
         return elements;
      }
        // We register the dialogue window
      CKEDITOR.dialog.add( pluginName, path + 'dialogs/' + pluginName + '.js' );
        // We should connect our dialogue window with the pluginName command
        // pluginName command is given after we press the icon on the tool bar editor.addCommand( pluginName, new CKEDITOR.dialogCommand( pluginName ) );
        // Here we add the button to our toolbar
        editor.ui.addButton( 'Spoiler', {
         label: editor.lang.spoiler.toolbar,
         command: pluginName
      });
        
        //  We add events to hide/unhide the content on click
      editor.on( 'mode', function() {
         if ( this.mode != 'wysiwyg' ) {
            return;
         }
         var elements = getDivWithClass( 'spoiler-header' ),
            len = elements.length;
         for ( var i = 0; i < len; ++i )
         {
            elements[i].on( 'click', function( event ) {
               var element = event.sender.getParent().getLast();
               element.setStyle( 'display' , ( ( element.getStyle('display') == 'none' ) ? '' : 'none' ) );
            });
         }
      });
   }
});

The plugin is ready, but it won’t hide/unhide elements on our web page ( the editor only adds HTML) We should insert next js code to our web page

$(function() {
   $(document).on('click', 'div.clickable.spoiler-header', function (e) {
      var $this = $(this);
      var $panel = $this.parent('.panel');
      var $panel_body = $panel.children('.panel-body');
      var $display = $panel_body.css('display');
      if ($display == 'block') {
         $panel_body.slideUp();
      } else if($display == 'none') {
         $panel_body.slideDown();
      }
   });
});

The only thing left is to copy and register our new plugin in our project.

If you are using Symfony2 bundle egeloen/ckeditor-bundle than you need to place a folder with your plugin inside AppBundle/Resources/public/js and app/config.yml as well.


ivory_ck_editor:
    default_config: default
    configs:
        default:
            extraPlugins: "spoiler"
            contentsCss: 'bundles/app/css/bootstrap.min.css'
    plugins:
        spoiler:
           path:     "/bundles/app/js/bootstrap-spoiler/"
           filename: "plugin.js"

Full version of this plugin could be found here:

https://github.com/smart-gamma/ck_editor-spoiler-bootstrap-plugin

seo: {"title":"","description":"","shortlink":"","canonical":"","robots":"index, follow","keywords":""}

Written by admin on Thursday July 21, 2016
Permalink

« Speech about SOLID architecture patterns in Symfony - Our team guys will make 2 speeches on upcoming Symfony2 Camp 2016 »