ReactQuill onChange is being called a lot of times on Function based Component - react-quill

I'm using React Quill on my function-based component, but I'm having problems when I load content to it, I mean the onChange is called for several times in a row (100 times +) for no reason, this only happens when I pass value to it and load the value from data I parse and add to the editor.
import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.snow.css';
import './Editor.local.css';
const Editor = ({ method, ...props }: any): any => {
return (
<pre style={{ width: '100%' }}>
<label className="llabel">{props.label}</label>
<ReactQuill
value={props.value}
onChange={(value: any) => method(value, props.index)}
modules={Editor.modules}
formats={Editor.formats}
bounds={'#root'}
placeholder={props.placeholder}
/>
</pre>
);
};
Editor.modules = {
toolbar: [
[{ header: [1, 2, 3, 4, 5, 6, false] }],
['bold', 'italic', 'underline'],
[{ list: 'ordered' }, { list: 'bullet' }],
['link'],
['clean']
],
clipboard: {
matchVisual: false,
},
};
Editor.formats = [
'bold',
'italic',
'underline',
'blockquote',
'list',
'bullet',
'link',
'image',
'header',
'strike',
'size',
'color',
'font',
'align',
'clean',
'direction',
'rtl'
];
export default Editor;
As per the load, just simply I add it to the item and show multi by items with description.

Related

Default size and alignment for images (also inserted via html)

I'd like to know how do I make my <img> which I append using editor.data.set() to be in a specific size and alignment? Can I define a global size for such appended images? I want it also to work with a normal image adding feature.
I cannot set the default style options for images - side / alignRight / alignBlockRight in my case (I don't know what's the difference between them, but nevermind).
Even if a specific alignment option is active / highlighted, the image is not aligned to the right.
image: {
styles: {
options: [
'alignLeft', 'alignRight',
'alignCenter', 'alignBlockLeft', 'alignBlockRight',
'block',
{
name: 'inline',
isDefault: false,
},
{
name: 'side',
isDefault: true,
},
],
},
I tried many ways but nothing works.
My full config:
ClassicEditor
.create(editorElement, {
plugins: [
Autoformat,
Base64UploadAdapter,
BlockQuote,
Bold,
Essentials,
Heading,
Image,
ImageBlockEditing,
ImageCaption,
ImageInlineEditing,
ImageResize,
ImageStyle,
ImageToolbar,
ImageUpload,
Italic,
Link,
List,
MediaEmbed,
Paragraph,
PasteFromOffice,
SourceEditing,
Table,
TableToolbar,
TextTransformation,
Underline,
WordCount,
GeneralHtmlSupport,
],
toolbar: [
'heading',
'|',
'bold',
'italic',
'underline',
'link',
'bulletedList',
'numberedList',
'|',
'outdent',
'indent',
'|',
'imageUpload',
'blockQuote',
'insertTable',
'mediaEmbed',
'undo',
'redo',
'sourceEditing',
],
// #ts-expect-error
htmlSupport: {
allow: [
{
name: 'img',
classes: true,
attributes: true,
}
],
},
language: 'en',
image: {
styles: {
styles: {
options: [
{
name: 'alignRight',
isDefault: true,
},
],
},
toolbar: [
'imageTextAlternative',
'imageStyle:alignRight',
],
},
table: {
contentToolbar: [
'tableColumn',
'tableRow',
'mergeTableCells'
]
}
})
.then(ckeditor => {
editor = ckeditor;
// editor.execute('imageStyle', { value: 'alignRight' });
})
.catch(error => {
console.error(error);
});

How to implement Quill Emojis in vue2editor?

I tried to add Quill Emojis to editor but I am getting console error as
Uncaught ReferenceError: Quill is not defined
I am using Laravel 5.6 and vue js and definately new to vue and its components so I may sound silly to you but for the past 3 days I am searching on the google for the solution and even contacted author of vue2editor on github here is the link
This is what I have tried so far:
vue2editor.vue
<template>
<div id="app">
<vue-editor v-model="content"></vue-editor>
</div>
</template>
<script>
import { VueEditor, Quill } from 'vue2-editor';
import Emoji from 'quill-emoji/dist/quill-emoji';
Quill.register('modules/quill-emoji', Emoji);
export default {
name: 'vue2editor',
components: { VueEditor },
data() {
return {
content: "<h1>Some initial content</h1>",
editorSettings: {
modules: {
toolbar: {
container: [
[{'size': ['small', false, 'large']}],
['bold', 'italic', 'underline', 'strike'],
['blockquote', 'code-block'],
[{ 'header': 1 }, { 'header': 2 }],
[{ 'list': 'ordered' }, { 'list': 'bullet' }],
[{ 'script': 'sub' }, { 'script': 'super' }],
[{ 'indent': '-1' }, { 'indent': '+1' }],
[{ 'direction': 'rtl' }],
[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
[{ 'color': [] }, { 'background': [] }],
[{ 'font': [] }],
[{ 'align': [] }],
['clean'],
['link', 'image', 'video'],
['emoji'],
],
handlers: {
'emoji': function () {}
},
},
toolbar_emoji: true,
short_name_emoji: true,
textarea_emoji:true,
},
},
text: null,
};
},
};
</script>
I even tried the method mentioned by one of the user on github for Quill-Emoji, here is the link.
I came here with lots of hopes; if anyone here is to help me out, at least tell me what I am missing will be more than a help for me.
Quill.register({
'formats/emoji': Emoji.EmojiBlot,
'modules/short_name_emoji': Emoji.ShortNameEmoji,
'modules/toolbar_emoji': Emoji.ToolbarEmoji,
'modules/textarea_emoji': Emoji.TextAreaEmoji}, true);
you need register the model, add the up code to you code.
Edit:
//1) Add plugin to laravel mix
const mix = require('laravel-mix')
mix.webpackConfig(webpack => {
return {
plugins: [
new webpack.ProvidePlugin({
"window.Quill": "quill/dist/quill.js",
Quill: "quill/dist/quill.js"
})
]
};
});
//2 example vue file
<template>
<div class="mt-1">
<vue-editor
ref="editor"
v-model="content"
:editor-toolbar="customToolbar"
:editorOptions="editorSettings"
/>
</div>
</template>
<script>
import { VueEditor, Quill } from "vue2-editor";
import Emoji from "quill-emoji/dist/quill-emoji";
Quill.register("modules/emoji", Emoji);
export default {
components: {
VueEditor,
},
props: {
bubble: Object,
contentCol: {
type: String,
},
},
data() {
return {
edit: false,
content: "<b>Content is here</b>",
customToolbar: [["bold", "italic", "underline"], ["link"], ["emoji"]],
editorSettings: {
modules: {
"emoji-toolbar": true,
"emoji-textarea": true,
"emoji-shortname": true,
},
},
};
},
beforeDestroy() {},
};
</script>
<style src="quill-emoji/dist/quill-emoji.css"/>

Get a field placed in the header of a grid column. Extjs 6

I'm working on a grid with a remote filter. So, i set a field in a grid column header.
My question is,
How can i get the field value without field-id ??
See the example below
Thank You
You might be able to bind the value config of your textfield (the textfield in your items of the column header) to an attribute in a view model.
Something like :
var vm = Ext.create('Ext.app.ViewModel', {
data: [{
test : ''
}],
alias: 'viewmodel.myviewmodel',
stores: {
simpsonsStore: Ext.create('Ext.data.Store', {
fields:['name', 'email', 'phone'],
data:[
{'name': 'Lisa', "email":"lisa#simpsons.com", "phone":"555-111-1224"},
{'name': 'Bart', "email":"bart#simpsons.com", "phone":"555-222-1234"},
{'name': 'Homer', "email":"homer#simpsons.com", "phone":"555-222-1244"},
{'name': 'Marge', "email":"marge#simpsons.com", "phone":"555-222-1254"}
]
})
}
});
var grid = Ext.create('Ext.panel.Panel', {
height: 400,
width: 400,
renderTo: Ext.getBody(),
viewModel: vm,
layout: 'hbox',
items:[{
xtype: 'button',
bind: {
text: '{test}'
}
},{
xtype: 'grid',
flex: 1,
bind: '{simpsonsStore}',
columns: [{
text: 'Name',
dataIndex: 'name',
items: [{
xtype: 'textfield',
bind: {
value: '{test}'
}
}]
}, {
text: 'Email',
dataIndex: 'email',
flex: 1
}, {
text: 'Phone',
dataIndex: 'phone'
}]
}]
});
PS : here is the fiddle ;) https://fiddle.sencha.com/#fiddle/15j6 you can type in your header filed, the button text will updated automatically :)

Handsontable checkbox's not working

Real simple, I've been trying to get the checkbox type to render on my list, but all I get is the value "no." Here's my settings object. Am I doing something wrong? The list renders perfectly and works properly in terms of conditional coloring, etc., just no checkboxes. HELP! and thank you.
settings = {
data: bulkListData
,dataSchema: {name: {first: null, last: null}, email: null,status: null,action: null}
,colHeaders: ['First Name', 'Last Name', 'Email','Status','Action']
,columns: [
{data: 'name.first'},
{data: 'name.last'},
{data: 'email'},
{data: 'status'},
{data: 'action'
,type: 'checkbox'
,checkedTemplate: 'yes'
,uncheckedTemplate: 'no'
}
]
,colWidths:[200,200,300,120,120]
,startRows: 5
,startCols: 5
,minRows: 5
,minCols: 5
,maxRows: 10
,maxCols: 5
,minSpareRows: 5
,autoWrapRow:true
,contextMenu: true}
I put your sample code in a fiddle and it works for me.
The only thing I needed was to fill in the bulkListData accordingly, otherwise everything is exactly like yours. Perhaps you are making the mistake exactly there - are your action properties in this array in the form of yes/no string?
I have a renderer that changes the color of a column. When this renderer is used the check boxes change to 'yes'/'no'.
When the renderer is not used the checkboxes show.
$(document).ready(function () { function getCompData() {
return [
{Comp: "Annually", year: 2006, Retirement: 'yes'},
{Comp: "Monthly", year: 2008, Retirement: 'yes'},
{Comp: "Quarterly", year: 2011, Retirement: 'no'},
{Comp: "Semi-Annually", year: 2004, Retirement: 'yes'},
{Comp: "Semi-Monthly", year: 2011, Retirement: 'no'}
];}function cellColorRenderer(instance, td, row, col, prop, value, cellProperties) {
Handsontable.TextCell.renderer.apply(this, arguments);
if (col === 1) {
td.style.textAlign = 'right';
td.style.backgroundColor = "#ccffcc";
}
}var example2 = document.getElementById('example2'); var hot2 = new Handsontable(example2,{ data: getCompData(),
startRows: 7,
startCols: 4,
colHeaders: ["Comp", "Year", "401K"],
colWidths: [120, 50, 60],
columnSorting: true,
columns: [
{
data: "Comp"
},
{
data: "year",
type: 'numeric'
},
{
data: "Retirement",
type: "checkbox",
checkedTemplate: 'yes',
uncheckedTemplate: 'no'
}
], cells:
function (row, col, prop) {
var cellProperties = {};
cellProperties.renderer = cellColorRenderer;
return cellProperties;
}, }); });
Here is the code in jsfiddle
http://jsfiddle.net/w42cp1y8/1/
Just use CheckboxRenderer instead TextRenderer:
$element.handsontable( {
cells: function( row, col, prop ) {
return {
renderer: function( instance, td, row, col, prop, value, cellProperties ) {
Handsontable.renderers.CheckboxRenderer.apply( this, arguments );
td.style.backgroundColor = value ? 'red' : 'white';
td.style.textAlign = 'center';
},
type: 'checkbox'
};
}
} );
jExcel is an alternative to handsontable. The example below is using a checkbox column type:
data = [
['Brazil', 'Classe A', 'Cheese', 1, '2017-01-12'],
['Canada', 'Classe B', 'Apples', 1, '2017-01-12'],
['USA', 'Classe A', 'Carrots', 1, '2017-01-12'],
['UK', 'Classe C', 'Oranges', 0, '2017-01-12'],
];
$('#my').jexcel({
data:data,
colHeaders: [ 'Country', 'Description', 'Type', 'Stock', 'Next purchase' ],
colWidths: [ 300, 80, 100, 60, 120 ],
columns: [
{ type: 'text' },
{ type: 'text' },
{ type: 'dropdown', source:[ {'id':'1', 'name':'Fruits'}, {'id':'2', 'name':'Legumes'}, {'id':'3', 'name':'General Food'} ] },
{ type: 'checkbox' },
{ type: 'calendar' },
]
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/jexcel/1.2.2/css/jquery.jexcel.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jexcel/1.2.2/js/jquery.jexcel.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jexcel/1.2.2/js/jquery.jcalendar.min.js"></script>
<div id="my"></div>

Change CKEditor toolbar dynamically

How do you change the CKEditor toolbar dynamically (without using a pre-defined toolbar)?
The CKEditor Developer's Guide only tells you how to set the toolbar during initialization.
I'm using CKEditor 3.6.4.
Following mb21's suggestion I managed to load a new toolbar by reinitialising the whole editor:
CKEDITOR.instances.editor.destroy();
CKEDITOR.replace('editor', configWithNewToolbar);
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);
You can reload or change the toolbar, without reloading the editor, with this code:
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
Adding the function the the editor.prototype makes it a method of any editor instance. Your editor object is probably CKEDITOR.instances.editor1
The argument to loadToolbar is the name of the toolbar to load, or if null, the current toolbar is reloaded. The name of the current toolbar is in CKEDITOR.instances.editor1.config.toolbar. If you specify toolbar 'foo' then there must be a CKEDITOR.instances.editor1.config.toolbar_foo array that defines the contents of the toolbar.
You can add or remove things from the current toolbar array of arrays variable and then cause it to be reloaded with: edObj.loadToolbar(null);
(Meta issue not affecting the method above: I don't understand why the listeners for the 'themeSpace' event go away after the editor originally loads the theme. (The toolbar plugin init() method does an event.on("themeSpace"...) but the listens go away after the editor is intialized. I didn't see where it did a removeListener(). So the call ...toolbar.init(this) was needed to restablish those event listeners so the toolbar code would rebuild the new toolbar.)
According to [CKEditor documentation][1] they have given up the concept of 'theme' and thus the 'loadToolbar()' method mentioned above have to be modified a bit to work with the newest version of CKEditor.
This worked for me (CKEditor 4.4.4):
CKEDITOR.editor.prototype.setToolbar = function(tbName) {
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;
}
//According to CKEditor documentation
var obj = this.fire( 'uiSpace', { space: 'top', html: '' } ).html;
console.log("Received from themespace:");
console.log(obj);
// Replace the toolbar HTML
var tbEleId = this.id +"_" + this.config.toolbarLocation;
console.log("Editor element id: " + tbEleId);
var tbEle = document.getElementById(tbEleId);
//tbEle.innerHTML = obj.html;
$(tbEle).html(obj);
}
[1]: http://docs.ckeditor.com/#!/guide/dev_api_changes
Just a quick one.
You may need to add this line to the loadToolbar function if your toolbar contains the textcolor and/or backgroundcolor buttons:
//Need to call init for colorbutton so that we can re-draw the color buttons
CKEDITOR.plugins.registered.colorbutton.init(this);
for me at least this got a little complicated....
and to answer the question i thought i would share the working code.
i have a user-defined snippets of text -- known as templates in ckeditor parlance i needed to load in.
i also dynamically change the toolbar depending on the window width, and dynamically resize on window resize. each browser size gets its own custom toolbar. (XS,SM,MD) . i expect all elements with a CKEDITOR have a class of .ckeditor and they have an ID assigned.
Additionally i have an on blur ajax save handler set up, so on loss of focus the control is automatically saved (via the ajax_post function) if required.
I call the procedure using setupCKEdit. thanks to hpique for the inspiration of removing the old object and creating a new instance. on the resize event i do this with a slight delay (resizeTimeout= 200msec), so it doesn't fire so often whilst changing the window size.
// ********* 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 **************
Or:
$(document).ready(function() {
CKEDITOR.config.customConfig = 'configSimple';
});
//the configSimple.js file is the same folder with config.js
If you want a simple way to swap toolbars in different areas, all you need to do is add the toolbars to the config, then select the one you want when you instantiate the editor.
In 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
In your page where you instantiate a editor instance do so this way:
<script>
CKEDITOR.replace('MyObject', {toolbar: 'mycustom2'});
</script>
I am assuming you want to add button via plugin file. Here is how. Add your button to ui.
editor.ui.addButton('ButtonName', {
label: lang.lockediting.locked,
icon: this.path + 'icons/locked.png',
command: 'lockediting'});
Then you can push ButtonName to toolbar.
//Here it is pushed as a new group
editor.config.toolbar.push(['ButtonName']);
If you check console.log(editor.config.toolbar); you will see toolbar ise an object with toolbar groups as arrays [Array[10], Array[2], Array[5]]. [Array[10] means there are 10 button in first group. You can push your button into any of those arrays.
You can create toolbar dynamically as you like. I found that the best approach is to listen to CKE events regarding instance creation.
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' ] },
];
});

Resources