How to change CKEditor styles dynamically via script? - ckeditor

I a project I work on we need to restrict users with predefined styles that can be changed by the user.
In my jsFiddle the function setStyle() works. You can try out by uncommentting the setStyle([]). It seems to me that I can use the config.stylesSet = assignment only once.
The function to change the style does not work after a button click nor after setTimeout.
Is there any way to set styles via a script in CKE4 more than once?
CKEDITOR.stylesSet.add( 'my_styles', [
// Block-level styles
{ name: 'Blue Title', element: 'h2', styles: { 'color': 'Blue' } },
{ name: 'Red Title' , element: 'h3', styles: { 'color': 'Red' } },
// Inline styles
{ name: 'CSS Style', element: 'span', attributes: { 'class': 'my_style' } },
{ name: 'Marker: Yellow', element: 'span', styles: { 'background-color': 'Yellow' } }
] );
CKEDITOR.stylesSet.add( 'my_styles2', [
// Block-level styles
{ name: 'Default Title', element: 'h2', styles: { 'color': 'Red' } },
// Inline styles
{ name: 'CSS Style', element: 'span', attributes: { 'class': 'my_style' } },
] );
var ckeditor = CKEDITOR.inline('editor1', {
removePlugins: 'exportpdf,sourcearea',
fillEmptyBlocks : false,
});
// setStyle([])
setTimeout(() => {
console. log("resetting styles")
setStyle([])
}, 5000);
function setStyle(style){
// ckeditor.config.stylesSet = style
CKEDITOR.config.stylesSet = style
// console.log(ckeditor)
console.log(style)
}

Related

Integrating GrapesJS with CKEditor 5 keyboard problem

I am trying to replace the GrapesJS RTE with CKEditor 5. I can get the CK editor to display, but the content of the editor is always locked. No matter what key is pressed no input is entered. I can style text in the box, just not type with the keyboard. Below is the code that I use.
I don't know if this is a problem with CKEditor or GrapesJS.
//The variable called "editor" is the grapesJS instance.
editor.setCustomRte({
enable: async function(el, rte) {
el.contentEditable = true;
// If already exists just focus
if (rte) {
//
var rteToolbar = editor.RichTextEditor.getToolbarEl();
[].forEach.call(rteToolbar.children, function(child) {
child.style.display = 'none';
});
rte = await rte;
rte.ui.view.toolbar.element.style.display = 'flex';
this.focus(el, rte);
return rte;
}
var rteToolbar = editor.RichTextEditor.getToolbarEl();
[].forEach.call(rteToolbar.children, function(child) {
child.style.display = 'none';
});
// Init CkEditors
rte = await InlineEditor
.create(el, {
language: 'en-au',
isReadOnly: false,
heading: {
options: [
{ model: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' },
{ model: 'heading1', view: 'h1', title: 'Heading 1', class: 'ck-heading_heading1' },
{ model: 'heading2', view: 'h2', title: 'Heading 2', class: 'ck-heading_heading2' },
{ model: 'heading3', view: 'h3', title: 'Heading 3', class: 'ck-heading_heading3' },
{ model: 'heading4', view: 'h4', title: 'Heading 4', class: 'ck-heading_heading4' },
{ model: 'heading5', view: 'h5', title: 'Heading 5', class: 'ck-heading_heading5' }
]
}
}
).catch(console.error);
if (rte) {
editor.RichTextEditor.getToolbarEl().appendChild(rte.ui.view.toolbar.element);
this.focus(el, rte);
} else {
console.error('Editor async was not initialized');
}
return rte;
},
disable: function(el, rte) {
el.contentEditable = false;
},
focus: function (el, rte) {
el.contentEditable = true;
rte && rte.editing.view.focus();
rte && rte.disableReadOnlyMode( el.id );
},
});
I tried ensuring CKEditor readOnly was off, and it was not in restricted editing mode.

CKEditor 4 - How to add H2, H3, etc to toolbar

Looking at these docs: https://ckeditor.com/docs/ckeditor4/latest/features/styles.html
So adding a style set should go something like this, but I can't get the H2 or H3 items to appear in my toolbar:
CKEDITOR.stylesSet.add( 'my_styles', [
// Block-level styles
{ name: 'Blue Title', element: 'h2', styles: { 'color': 'Blue' } },
{ name: 'Red Title' , element: 'h3', styles: { 'color': 'Red' } },
// Inline styles
{ name: 'CSS Style', element: 'span', attributes: { 'class': 'my_style' } },
{ name: 'Marker: Yellow', element: 'span', styles: { 'background-color': 'Yellow' } }
] );
CKEDITOR.editorConfig = function( config ) {
config.extraPlugins = 'firstname,MediaEmbed,justify,image';
//config.forcePasteAsPlainText = true;
config.extraAllowedContent = 'iframe[*]';
config.toolbar = 'Normal';
config.toolbar_Normal = [
{ name: 'basicstyles', items: [ 'Bold', 'Italic','Underline','Strike' ] },
{ name: 'paragraph', items: [ 'NumberedList', 'BulletedList', 'JustifyLeft', 'JustifyCenter', 'JustifyRight' ] }
];
config.toolbar_Emails = [
{ name: 'basicstyles', items: [ 'Bold', 'Italic','Underline','Strike' ] },
{ name: 'paragraph', items: [ 'NumberedList', 'BulletedList', 'JustifyLeft', 'JustifyCenter', 'JustifyRight' ] }
];
config.removeDialogTabs = 'link:advanced;link:target';
config.stylesSet = 'my_styles';
};
As mentioned in the docs
Open the config.js file available in your ckeditor directory, and edit the config.format_tags entry in the following way to display the text formatting toolbar.
// Enable all default text formats:
config.format_tags = 'p;h1;h2;h3;h4;h5;h6;pre;address;div';
// Enable a limited set of text formats:
config.format_tags = 'p;h1;h2;pre;div';

Replace styles in CKEditor

I'm building out a simple site building tool using CKEditor. The tool has the ability to choose from and set palettes, which should be reflected in the styles drop down of CKEditor. However, it seems to me that styles cannot be overwritten in CKEditor. The code I have at the moment is:
CKEDITOR.stylesSet.add( 'styles', [
// Block-level styles
{ name: 'blah 1', element: 'h2', styles: { 'color': '#xxxxxx' } },
{ name: 'blah 2', element: 'h3', styles: { 'color': '#xxxxxx' } },
{ name: 'blah 3' , element: 'h4', styles: { 'color': '#xxxxxx' } },
{ name: 'blah 4' , element: 'h5', styles: { 'color': '#xxxxxx' } },
] );
CKEDITOR.config.stylesSet = 'styles';
Now, if I repeat this with new styles, I get:
ckeditor.js:232 Uncaught Error: [CKEDITOR.resourceManager.add] The resource name "styles" is already registered.
I've tried using CKEDITOR.replace, but this doesn't fix the issue. I guess, the obvious solution is to iterate the style name with each use; style1, style2, style3... but that's not very resource friendly. Does anyone have an actual solution for this?
Thanks,
Lee
have you tried renaming styles to default?
I use this and it works, mine loads an external style file. But same array structure.
CKEDITOR.config.stylesSet = 'default:http://' + window.location.host + '/folder/fckeditor.styles.js';
So, I figured out a solution by always destroying the panel, if it exists, before re-creating it. For instance:
if (CKEDITOR.instances['footer-' + i]) {
CKEDITOR.instances['footer-' + i].destroy(true);
}
var editor = CKEDITOR.inline('footer-' + i, {
stylesSet: [
// Block-level styles
{ name: 'Blue Title', element: 'h2', styles: { 'color': 'Blue' } },
{ name: 'Red Title' , element: 'h3', styles: { 'color': 'Red' } },
{ name: 'Brown Title' , element: 'h4', styles: { 'color': 'Red' } },
{ name: 'Purple Title' , element: 'h5', styles: { 'color': 'Red' } }
]
});
Now, this does throw up a warning each time, saying:
[CKEDITOR] For more information about this error go to http://docs.ckeditor.com/#!/guide/dev_errors-section-editor-incorrect-destroy
However, theres no clean way to do this otherwise with the CKEditor API, so since it works, I'm marking it as the answer.

Create style that can be applied to div in ckeditor?

My ckeditor WYSIWYG has the option to create divs. Im trying to create a style that can be put in the 'Style' dropdown:
Ive tried adding the following to my config.js but it seems to have no effect.
CKEDITOR.stylesSet.add( 'default',
[
// Inline styles
{ name : 'Titulo Explicacion Servicio', element : 'div', attributes : { 'class' : 'titulo_explicacion_servicio' } },
{ name : 'Texto Explicacion Servicio', element : 'div', attributes : { 'class' : 'texto_explicacion_servicio' } },
{ name : 'Texto Fondo Foto', element : 'div', attributes : { 'class' : 'intro_fondo_foto' } }
]);
I doubt it makes any difference but this is for a Drupal site.
I found what I needed to change in styles.js
CKEDITOR.stylesSet.add( 'default', [
{ name: 'Italic Title', element: 'h2', styles: { 'font-style': 'italic' } },
{ name: 'Subtitle', element: 'h3', styles: { 'color': '#aaa', 'font-style': 'italic' } },
{
name: 'Image caption', //THESE NEXT 4 LINES I CHANGED
element: 'div',
attributes: {
class: 'caption-mine'
}
},

Image form field Sencha Touch 2

I'm trying to create a Sencha Touch 2 form panel for a model in which one of the fields contains the URL to an image file. If I include a textfield, it'll display the text of the URL correctly, but what I really want is to display the image found at that URL, and I'm not sure how to do that. If I use xtype: image, I think I need a src config, and I'm not sure how to specify that the desired value is in one of the form fields. My view looks like this:
Ext.define("CatalogApp.view.ItemDetailView", {
extend: "Ext.form.Panel",
requires: "Ext.form.FieldSet",
alias: "widget.itemdetailview",
config:{
scrollable:'vertical'
},
initialize: function ()
{
this.callParent(arguments);
var backButton = {
xtype: "button",
ui: "back",
text: "Home",
handler: this.onBackButtonTap,
scope: this
};
var topToolbar = {
xtype: "toolbar",
docked: "top",
title: "Item Detail",
items: [
backButton
]
};
var mainLayout = {
xtype: "container",
layout: 'hbox',
items: [
{
xtype: 'textfield',
width: 200,
name: 'thumbUrl'
},
{
xtype: "fieldset",
flex: 1,
items : [
{
xtype: 'textfield',
name: 'itemNbr',
label: 'Item Nbr',
disabled: true
},
{
xtype: 'textfield',
name: 'itemDesc',
label: 'Item Desc',
disabled: true
}
]
}
]
};
this.add([
topToolbar,
mainLayout
]);
},
onBackButtonTap: function ()
{
console.log("backToHomeCommand");
this.fireEvent("backToHomeCommand", this);
}
});
How can I set up this view to display the image correctly?
You have to define new Sencha component: ImageField
Ext.define('Ext.ux.field.ImageField', {
extend: 'Ext.field.Field',
requires: [
'Ext.Img'
],
xtype: 'imagefield',
config: {
component: {
xtype: 'image'
}
},
updateValue: function(value, oldValue) {
var me = this,
component = me.getComponent();
component.setSrc(value);
},
proxyConfig: {
width: '100%',
height: '100%'
}
});
Than in form:
Ext.define("CatalogApp.view.ItemDetailView", {
extend: "Ext.form.Panel",
requires: "Ext.form.FieldSet",
alias: "widget.itemdetailview",
config:{
scrollable:'vertical'
},
initialize: function ()
{
this.callParent(arguments);
var backButton = {
xtype: "button",
ui: "back",
text: "Home",
handler: this.onBackButtonTap,
scope: this
};
var topToolbar = {
xtype: "toolbar",
docked: "top",
title: "Item Detail",
items: [
backButton
]
};
var mainLayout = {
xtype: "container",
layout: 'hbox',
items: [
{
xtype: 'imagefield', // only this change
width: 200,
height: 150,
name: 'thumbUrl'
},
{
xtype: "fieldset",
flex: 1,
items : [
{
xtype: 'textfield',
name: 'itemNbr',
label: 'Item Nbr',
disabled: true
},
{
xtype: 'textfield',
name: 'itemDesc',
label: 'Item Desc',
disabled: true
}
]
}
]
};
this.add([
topToolbar,
mainLayout
]);
},
onBackButtonTap: function ()
{
console.log("backToHomeCommand");
this.fireEvent("backToHomeCommand", this);
}
});
Cheers, Oleg

Resources