2012-09-21 119 views
14

如何动态更改CKEditor工具栏(不使用预定义的工具栏)?动态更改CKEditor工具栏

CKEditor Developer's Guide只告诉你如何在初始化期间设置工具栏。

我使用的是CKEditor 3.6.4。

+2

我猜你总是可以重新初始化整个编辑.. – mb21

回答

9

mb21的建议,我设法重新初始化整个编辑器来加载一个新的工具栏:

CKEDITOR.instances.editor.destroy(); 
CKEDITOR.replace('editor', configWithNewToolbar); 
3

您可以重新载入或更改的工具栏,而无需重新加载编辑器,使用此代码:

CKEDITOR.editor.prototype.loadToolbar = function(tbName) { 
    // If the 'themeSpace' event doesn't exist, load the toolbar plugin 
    if (!this._.events.themeSpace) { 
     CKEDITOR.plugins.registered.toolbar.init(this); 
    // causes themeSpace event to be listened to. 
    } 
    // If a different toolbar was specified use it, otherwise just reload 
    if (tbName) this.config.toolbar = tbName; 

    // themeSpace event returns a object with the toolbar HTML in it 
    var obj = this.fire('themeSpace', { space: 'top', html: '' }); 

    // Replace the toolbar HTML 
    var tbEleId = "cke_"+this.config.toolbarLocation+"_"+this.name; 
    var tbEle = document.getElementById(tbEleId); 
    tbEle.innerHTML = obj.html; 
    } // end of loadToolbar 

将editor.prototype添加到任何编辑器实例的方法中。您的编辑器对象可能是CKEDITOR.instances.editor1

loadToolbar的参数是要加载的工具栏的名称,如果为null,则重新加载当前工具栏。当前工具栏的名称位于CKEDITOR.instances.editor1.config.toolbar中。如果您指定工具栏'foo',那么必须有一个CKEDITOR.instances.editor1.config.toolbar_foo数组来定义工具栏的内容。

您可以从当前的数组变量的工具栏数组中添加或删除东西,然后使其重新加载:edObj.loadToolbar(null);


(元问题不影响上面的方法:我不明白为什么对“themeSpace”事件监听器消失后,原本编辑加载主题(工具栏插件的init()方法完成的。 event.on(“themeSpace”...),但编辑器初始化后听不见,我没有看到它在哪里做了removeListener(),所以调用... toolbar.init(this)是需要的restablish这些事件侦听器这样的工具栏的代码会重新生成新的工具栏。)

+1

关于你的最后的评论,我认为这样的监听器将自动删除该代码可以使用这样的fireOnce。 – AlfonsoML

1

只是一个快速的一个。

您可能需要加入这一行,如果你的loadToolbar功能[R工具栏包含的文字颜色和/或按钮的backgroundColor:

//Need to call init for colorbutton so that we can re-draw the color buttons 
CKEDITOR.plugins.registered.colorbutton.init(this); 
6
var editor = CKEDITOR.instances['text_id']; 
if (editor) { editor.destroy(true); } 

CKEDITOR.config.toolbar_Basic = [['Bold','Italic','Underline', 
'-','JustifyLeft','JustifyCenter','JustifyRight','-','Undo','Redo']]; 
CKEDITOR.config.toolbar = 'Basic'; 
CKEDITOR.config.width=400; 
CKEDITOR.config.height=300; 
CKEDITOR.replace('text_id', CKEDITOR.config); 
1

至少对我来说这有一点复杂....

,并回答了我想我会分享工作中的问题码。

我有一个用户定义的文本片段 - 在我需要加载的ckeditor说法中称为模板。 我还根据窗口宽度动态更改工具栏,并动态调整窗口大小调整大小。每个浏览器大小都有自己的自定义工具栏(XS,SM,MD)。我希望所有具有CKEDITOR的元素都有一个.ckeditor类,并且他们有一个ID分配。 此外,我有一个关于模糊ajax保存处理程序设置,所以失去焦点时,控制会自动保存(通过ajax_post函数),如果需要。

我使用setupCKEdit调用过程。这要归功于hpique的灵感,即去除旧对象并创建新实例。在resize事件中,我会稍微延迟一次(resizeTimeout = 200毫秒),所以在更改窗口大小时不会频繁触发。

// ********* ck editor section starts ************** 

var resizeTimeout; 
var ckeditorXSToolbar = Array(
    { name: 'clipboard', groups: [ 'clipboard', 'undo' ], items: [ 'Cut', 'Copy', 'Paste','-', 'Undo', 'Redo' ] }, 
    { name: 'document', groups: [ 'mode' ], items: [ 'Source'] }, 
    { name: 'tools', items: [ 'Maximize'] }, 
    { name: 'styles', items: [ 'Format', 'Font', 'FontSize'] ,class:'hidden-xs'}, 
    { name: 'basicstyles', groups: [ 'basicstyles'], items: [ 'TextColor','Bold', 'Italic'] } 

); 

var ckeditorSMToolbar = [ 
    { name: 'styles', items: [ 'Styles', 'Format', 'Font', 'FontSize'] ,class:'hidden-xs'}, 
    { name: 'clipboard', groups: [ 'clipboard', 'undo' ], items: [ 'Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo' ] }, 
    { name: 'editing', groups: [ 'find', 'selection' ], items: [ 'Find', 'Replace', '-', 'SelectAll' ] }, 
    { name: 'document', groups: [ 'mode', 'document', 'doctools' ], items: [ 'Source', '-', 'Save', 'NewPage', 'Preview', 'Print'] }, 

    { name: 'forms', items: [ 'Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField' ] }, 
    { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ], items: [ 'TextColor','Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat' ] }, 
    { name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ], items: [ 'NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote', 'CreateDiv', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock', '-', 'BidiLtr', 'BidiRtl', 'Language' ] }, 
    { name: 'tools', items: [ 'Maximize', 'ShowBlocks' ] } 
]; 
var ckeditorMDToolbar = [ 
    { name: 'styles', items: [ 'Styles', 'Format', 'Font', 'FontSize'] ,class:'hidden-xs'}, 
    { name: 'clipboard', groups: [ 'clipboard', 'undo' ], items: [ 'Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo' ] }, 
    { name: 'editing', groups: [ 'find', 'selection', 'spellchecker' ], items: [ 'Find', 'Replace', '-', 'SelectAll', '-', 'Scayt' ] }, 
    { name: 'document', groups: [ 'mode', 'document', 'doctools' ], items: [ 'Source', '-', 'Save', 'NewPage', 'Preview', 'Print'] }, 

    { name: 'forms', items: [ 'Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField' ] }, 
    { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ], items: [ 'TextColor','Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat' ] }, 
    { name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ], items: [ 'NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote', 'CreateDiv', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock', '-', 'BidiLtr', 'BidiRtl', 'Language' ] }, 
    { name: 'links', items: [ 'Link', 'Unlink', 'Anchor' ] }, 
    { name: 'insert', items: [ 'Image', 'Flash', 'Table', 'HorizontalRule', 'Smiley', 'SpecialChar', 'PageBreak', 'Iframe' ] }, 

    { name: 'tools', items: [ 'Maximize', 'ShowBlocks' ] }, 
    { name: 'others', items: [ '-' ] }, 
    { name: 'about', items: [ 'About' ] } 
]; 

function setupCKEdit(selector){ 
    if (typeof(o.snippets) == 'object'){ 
     var template = { 
      imagesPath:url_img , 
      templates: o.snippets 
     }; 
     CKEDITOR.addTemplates('myTemplate', template); 
    } 
    resizeCKEdit(); 

    $('.ckeditor',selector).not('.hasCKEDITOR').each(function(index,element){ 
     $(this).addClass('hasCKEDITOR'); 
     var ckConfig = { 
      templates_replaceContent:false, 
      scayt_slang:'en_GB', 
      scayt_autoStartup:scayt_autoStartup, 
      toolbarCanCollapse:true, 
      extraPlugins:'templates,colorbutton', 
      toolbar:getCKtoolbar(), 
      toolbarStartupExpanded:getCKToolbarStartup() 
     }; 
     // inject the snippets after the toolbar[].name = 'document' 
     if (typeof(o.snippets) == 'object'){ 
      ckConfig.templates = 'myTemplate'; 
      for(var i = 0 ; i < ckConfig.toolbar.length ; i++){ 
       if (ckConfig.toolbar[i].name == 'document'){ 
        // iterate throught each document element to make sure template is not already there. 
        var hasTemplate = false; 
        for (var j = 0 ; j < ckConfig.toolbar[i].items.length; j++){ 
         if (ckConfig.toolbar[i].items[j] == 'Templates'){ 
          hasTemplate = true; 
         } 
        } 
        if (hasTemplate == false){ 
         ckConfig.toolbar[i].items.push('-'); // add to documents group. 
         ckConfig.toolbar[i].items.push('Templates'); 
        } 

       } 
      }   
     } 
     $(this).ckeditor(ckConfig); 
     var editor = CKEDITOR.instances[this.id]; 
     if(typeof(editor) == 'object'){ 
      editor.on('blur',function(event){ 
       if (event.editor.checkDirty()){ 
        var ta = $('#'+event.editor.name); // ta = textarea 
        if ((typeof(ta) == 'object') 
         && (typeof(ta[0]) == 'object') 
         && ($(ta[0]).hasClass('noajax') == false) 
         && ($(ta[0]).data('id')) 
         && (ta[0].name)) { 
         var data = { 
          field_name:ta[0].name, 
          field_value:event.editor.getData(), 
          id:$(ta[0]).data('id') 
          }; 
         data[ta[0].name]=event.editor.getData(); 
         ajax_post(url_ajax + 'update_field', data); 
         event.editor.resetDirty(); 
        } 
       } 
      }); 
     } 
    }); 
} 
function getCKtoolbar(){ 
    // returns the CK editor toolbar array based on window width 
    var dw = $(document).width(); 
    if (dw < 768){ 
     return ckeditorXSToolbar; 
    } else if(dw < 991){ 
     return ckeditorSMToolbar; 
    } 
    else { 
     return ckeditorMDToolbar; 
    } 
} 

function getCKToolbarStartup(){ 
    // returns the toolbarStartupExpanded parameter, based on window width 
    var dw = $(document).width(); 
    if (dw < 768){ 
     return false; 
    } else if(dw < 991){ 
     return true; 
    } 
    else { 
     return true; 
    } 
    return true; 
} 
function resizeCKEdit(){ 
    // when there is a document resize, update the toolbar buttons. 
    if ($('body').data('resize_enabled') == undefined){ 
     $('body').data('resize_enabled',true); 
     $(window).resize(function(event){ 
      // only do the reize 100msec after the resizing finishes. 
      window.clearTimeout(resizeTimeout); 
      resizeTimeout = window.setTimeout(function(){ 

      // iterate through all CKEDITOR instances, and update their toolbars. 
       var ckConfig = { 
        templates_replaceContent:false, 
        scayt_slang:'en_GB', 
        scayt_autoStartup:scayt_autoStartup, 
        toolbarCanCollapse:true, 
        extraPlugins:'templates,colorbutton', 
        toolbar:getCKtoolbar(), 
        toolbarStartupExpanded:getCKToolbarStartup() 
       }; 
       if (CKEDITOR.editor.length){ 
        // need to get all instances before deleting them, 
        var instances = Array(); 
        var i = 0; 
        for (var instance in CKEDITOR.instances) { 
         instances[i] = instance; 
         i++; 
        } 
        for (i = 0 ; i < instances.length ; i ++){ 
         CKEDITOR.instances[instances[i]].destroy(); 
         $('#'+instances[i]).removeClass('hasCKEDITOR'); 
         setupCKEdit($('#'+instances[i]).parent()); 
        } 
       } 
      },200); 

     }); 
    } 
} 
// ********* ck editor section ends ************** 
3

根据[CKEditor的文档] [1],他们已经放弃了“主题”,因此“loadToolbar()”上述方法的概念已被修改的位与最新版本的工作CKEditor的。

这为我工作(CKEditor的4.4.4):

CKEDITOR.editor.prototype.setToolbar = function(tbName) { 
 
\t \t if (!this._.events.themeSpace) { 
 
\t \t CKEDITOR.plugins.registered.toolbar.init(this); 
 
\t \t // causes themeSpace event to be listened to. 
 
\t \t } 
 
\t \t // If a different toolbar was specified use it, otherwise just reload 
 
\t \t if (tbName){ 
 
\t \t \t this.config.toolbar = tbName; 
 
\t \t } 
 
\t \t //According to CKEditor documentation 
 
\t \t var obj = this.fire('uiSpace', { space: 'top', html: '' }).html; 
 
\t \t console.log("Received from themespace:"); 
 
\t \t console.log(obj); 
 
\t \t // Replace the toolbar HTML 
 
\t \t var tbEleId = this.id +"_" + this.config.toolbarLocation; 
 
\t \t console.log("Editor element id: " + tbEleId); 
 
\t \t var tbEle = document.getElementById(tbEleId); 
 
\t \t //tbEle.innerHTML = obj.html; 
 
\t \t $(tbEle).html(obj); 
 
     }
[1]: http://docs.ckeditor.com/#!/guide/dev_api_changes

0

如果你想有一个简单的方法来交换在不同领域的工具栏,你需要做的就是添加工具栏添加到配置中,然后在实例化编辑器时选择你想要的。

在config.js:

CKEDITOR.editorConfig = function(config) 
{ 
// default toolbar 
config.toolbar = [ 
    { name: 'source',  items: [ 'ShowBlocks', 'Source' ] }, 
    { name: 'clipboard', items: [ 'Undo', 'Redo', '-', 'Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord' ] }, 
    { name: 'editing',  items: [ 'Find', 'Replace', 'SelectAll', 'Scayt' ] }, 

    { name: 'p2',   items: [ 'Blockquote', 'Outdent', 'Indent', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock' ] }, 
    { name: 'links',  items: [ 'Link', 'Unlink', 'Anchor' ] }, 
    { name: 'paragraph', items: [ 'NumberedList', 'BulletedList' ] }, 
    { name: 'insert',  items: [ 'CreatePlaceholder', 'CreateDiv', 'Image', 'Table', 'HorizontalRule', 'SpecialChar', 'Iframe' ] }, 

    //{ name: 'styles',   items: [ 'Styles', 'Format' ] }, 
    { name: 'basicstyles', items: [ 'Bold', 'Italic', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat' ] }, 
    { name: 'styles',  items: [ 'Format' ] }, 
    { name: 'morestyles', items: [ 'Font', 'FontSize' ] }, 
    { name: 'colors',  items: [ 'BGColor', 'TextColor' ] } 
]; 

// here is one custom toolbar 
config.toolbar_mycustom1 = [ 
    { name: 'source',  items: [ 'ShowBlocks', 'Source' ] }, 
    { name: 'clipboard', items: [ 'Undo', 'Redo', '-', 'Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord' ] }, 
    { name: 'editing',  items: [ 'Find', 'Replace', 'SelectAll', 'Scayt' ] } 
]; 

// here is another custom toolbar 
config.toolbar_mycustom2 = [ 
    { name: 'styles',  items: [ 'Format' ] }, 
    { name: 'morestyles', items: [ 'Font', 'FontSize' ] }, 
    { name: 'colors',  items: [ 'BGColor', 'TextColor' ] } 
]; 

// ...other config vars here 

在你的页面,你实例化一个编辑器实例这样做是这样的:

<script> 
    CKEDITOR.replace('MyObject', {toolbar: 'mycustom2'}); 
</script> 
1

或者:

$(document).ready(function() { 
     CKEDITOR.config.customConfig = 'configSimple'; 
    }); 

    //the configSimple.js file is the same folder with config.js 
0

我假设你想要通过插件文件添加按钮。这是如何。将你的按钮添加到用户界面。

editor.ui.addButton('ButtonName', { 
    label: lang.lockediting.locked, 
    icon: this.path + 'icons/locked.png', 
    command: 'lockediting'}); 

然后,您可以将ButtonName推到工具栏。

//Here it is pushed as a new group 
editor.config.toolbar.push(['ButtonName']); 

如果您检查console.log(editor.config.toolbar);你会看到工具栏是一个带有工具栏组的数组[Array [10],Array [2],Array [5]]。 [数组[10]表示第一组中有10个按钮。你可以将你的按钮推入任何这些数组中。

0

您可以根据需要动态创建工具栏。我发现最好的方法是听取关于实例创建的CKE事件。

CKEDITOR.on('instanceCreated', function(event) { 
    var editor = event.editor; 
    editor.config.toolbar = [ 
     { name: 'basicstyles', groups: [ 'basicstyles'], items: [ 'Bold', 'Italic','Subscript', 'Superscript' ] }, 
    ]; // could be from synchronous!!! XHR as well 
}); 

CKEDITOR.on('instanceReady', function(event) { 
    var editor = event.editor; 
    editor.config.toolbar = [ 
     { name: 'basicstyles', groups: [ 'basicstyles'], items: [ 'Bold', 'Italic','Subscript', 'Superscript' ] }, 
    ]; 
});