José Carlos
José Carlos

Reputation: 1015

Use of classes for alignment ckeditor

I am using ckeditor and it is really great. The only one problem I have is that I am trying to use classes instead of style when aligning objects. More specifically, I want to use a class alignleft for align left images instead of using style="float:left". For this purpose I modified the plugin ckeditor/plugins/image/dialogs/image.js

In id:'cmbAlign' I changed the setup and the commid method so that it should add the class "alignleft" or "alignright" depending the situation but strangelly It does not work when I try to change the class (using removeClass or addClass, setAttribute('class') does not work too). The code is:

id:'cmbAlign',
    type:'select',
    widths:['35%','65%'],
    style:'width:90px',
    label:b.lang.common.align,
    'default':'',
    items:[[b.lang.common.notSet,'none'],[b.lang.common.alignLeft,'left'],[b.lang.common.alignRight,'right']],
    onChange:function(){
        l(this.getDialog());
        o.call(this,'advanced:txtdlgGenStyle');
    },
    setup:function(C,D){
        if(C==d){
            var E=(D.getAttribute('class')+'').match(/align([a-z]+)?/);
            if(E&&E[1])E = E[1];else E='';
            this.setValue(E);
        }
    },
    commit:function(C,D,E){        
        var F = (this.getValue()+'');
        if(C==d||C==f){
            var G=(D.getAttribute('class')+'').match(/align([a-z]+)?/);
            if(G&&G[1]){
                if(F!=G[1]){
                    D.removeClass('align'+G[1]);
                    if(F!=='')D.setAttribute('rel',F); D.addClass('align'+F);
                }
            } else {
                if(F!=='')D.setAttribute('rel',F); D.addClass('align'+F);
            }

        }
}

Please note that I have added D.setAttribute('rel',F) and it works perfect.

Does anybody have any idea or solution for it??

Upvotes: 2

Views: 3469

Answers (2)

codewaggle
codewaggle

Reputation: 4943

Here is a little more info:

The unpacked version of that code is in:

ckeditor/_source/plugins/image/dialogs/image.js ( line 994 )

Instead of guessing what all those letters stand for, you can see the actual objects, variables and functions that are involved.

The information I posted about listening for the dialog events was based on looking at that code and seeing what it does.

You need to stop the dialog from adding the inline float style or it will override the style that you apply to your class. The float isn't being added as a class, so using addClass or removeClass will have no effect on it. That means you need to approach the problem in a different way.

Here are a few possibilities that came to my mind, I expect that other people can suggest additional approaches:

1) You can modify the code in the image plugin ( but it could be overwritten if the editor is updated ).

2) Make a copy of the image plugin and modify the code to make a custom plugin, then replace the image button with one that calls your plugin.

3) Work from outside the dialog code by listening for the dialog event, then stop the inline float style from being added and add your class instead.

Hope this helps,
Joe


What version of CKEditor are you using? I'm using 3.6.1.

I searched for "cmbAlign" in the ckeditor/plugins/image/dialogs/image.js file. I modified this bit on line 11:

id:'cmbAlign',type:'select',widths:['35%','65%'],style:'width:90px'.....

I changed "width:90px" to "width:290px" and the dialog box got a lot wider. So a change to that file has an effect in my install.

Is it possible that you are working with the unpacked file found in the _source directory?:
ckeditor/_source/plugins/image/dialogs/image.js

Just mentioning it because those files aren't loaded unless you are loading one of the ckeditor_basic files instead of the ckeditor.js file.


A Possible Approach:

You could make a custom plugin that replaces the image plugin. There's a tutorial section with easy instructions for creating a plugin here:

http://docs.cksource.com/CKEditor_3.x/Tutorials

You can use that as an overview of how plugins work, but you'll really just be making a few changes to the default image plugin.

Just copy the image plugin folder from the ckeditor/_source/plugins directory and put it in the ckeditor/plugins directory. You'll need to rename the plugin and disable the default image plugin. Then you can make the changes that you outlined in your post to the image.js file.

To disable the default image plugin add this to your config settings:

config.removePlugins = 'image';

Another Possible Approach:

Add an event listener to the page, you can set up a script to do the following:

Watch for the "dialogShow" event and check if the dialog that opened is the image dialog.
If it is, listen for the change event of the Alignment selector.
When the Alignment selector is changed, check if "align left" was selected.
If so, stop the command from propagating and insert your class name in the "Stylesheet Classes" field of the Advanced tab.

You can set the priority of your event listener for the selector change to "1", so it goes before the default code is run. The docs for the "on" method show the available parameters:

http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.event.html#on


You can look at the following post for sample code and further info about setting this up (jQuery is used):

ckeditor add event handler to dialog element

In that post, the second section of the answer (near the top) begins with:

Start Quote
If you would like to listen for a change to a select element from another location, you can create a listener that keys on the "dialogShow" event. Here's an example:

// Watch for the "dialogShow" event to be fired in the editor,

End Quote


Additionally, you'll want to wrap the listener for the "dialogShow" event inside a listener for the "instanceReady" event, here is some sample code for that (jQuery is used):

// After both the document and editor instance are ready, 
// Start listening for the image dialog

// Wait for the document ready event
$(document).ready(function(){

  // Wait for the instanceReady event to fire for this (editor1) instance
  CKEDITOR.instances.editor1.on( 'instanceReady', 
    function( instanceReadyEventObj )
    {
      var currentEditorInstance = instanceReadyEventObj.editor;

      ...Put Code To Listen For The "dialogShow" Event Here...
    }
  );
});

Let me know if you have any questions about what I've written.

Be Well, Joe

Upvotes: 5

atma
atma

Reputation: 875

If you changes core files be careful when upgrading CKEditor. The easiest (but not the most convenient for the editor) solution is:

CKEditor image dialog

Upvotes: 2

Related Questions