Custom CKEditor plugin button not showing - ckeditor

Feel like I should have been able to track this one down already. I need to create a custom plugin for CKEditor (I'm using 4.3.1). To get started I used the guide found here (http://docs.ckeditor.com/#!/guide/plugin_sdk_sample_1). I downloaded the code and put it in my ckeditor\plugins folder. So, now I have ckeditor\plugins\abbr. I'm not sure what I'm doing, but the button is not showing in the toolbar. The code is below. My questions are, where should I define the "abbr" extra plugin? Do I do it in my _Edit.cshtml page where I'm defining stylesheetparser? Or put it in config.js? Given the setup below shouldn't the button show up next to the source button? Do I need to include it in config.js or does the plugin code take care of that?
Been doing a little playing around and it does show up if I use the full toolbar, but not when I customize it.
config.js
CKEDITOR.editorConfig = function (config) {
config.toolbar = 'MyToolbar';
config.forcePasteAsPlainText = true;
//config.extraPlugins = 'abbr';
config.ignoreEmptyParagraph = 'true'
config.toolbar_MyToolbar =
[
{ name: 'document', items: ['Preview', 'Print'] },
{ name: 'clipboard', items: ['Cut', 'Copy', 'PasteText', '-', 'Undo', 'Redo'] },
{ name: 'editing', items: ['Find', 'Replace', '-', 'SelectAll', '-', 'SpellChecker', 'Scayt'] },
{ name: 'basicstyles', items : [ 'Bold','Italic','Subscript','Superscript','-','RemoveFormat' ] },
'/',
{ name: 'insert', items: ['Table', 'SpecialChar'] },
{ name: 'styles', items : [ 'Styles'] }
, { name: 'source', items: ['Source', '-', 'abbr'] }
];
};
_Edit.cshtml
#Html.TextAreaFor(e => e.Narrative, 10, 10, null)
<script type="text/javascript">
CKEDITOR.replace('Narrative', {
extraPlugins: 'stylesheetparser,abbr',
// Stylesheet for the contents.
contentsCss: '#Href("~/content/"+#Model.CssFile)',
stylesheetParser_skipSelectors: '',
disableNativeSpellChecker: false,
// Do not load the default Styles configuration.
stylesSet: [],
height: '600px',
width: '100%'
});
</script>
plugin.js
CKEDITOR.plugins.add( 'abbr', {
// Register the icons.
icons: 'abbr',
// The plugin initialization logic goes inside this method.
init: function( editor ) {
// Define an editor command that opens our dialog.
editor.addCommand( 'abbr', new CKEDITOR.dialogCommand( 'abbrDialog' ) );
// Create a toolbar button that executes the above command.
editor.ui.addButton( 'Abbr', {
// The text part of the button (if available) and tooptip.
label: 'Insert Abbreviation',
// The command to execute on click.
command: 'abbr',
// The button placement in the toolbar (toolbar group name).
toolbar: 'source'
});
// Register our dialog file. this.path is the plugin folder path.
CKEDITOR.dialog.add( 'abbrDialog', this.path + 'dialogs/abbr.js' );
}
});

Related

ckeditor - Add title tag to link using Decorators

How can I add an input where a user can add the specific title tag to a link in the ckeditor5?
So for example my config file looks like this...
const config = {
toolbar: {
items: [
'bold',
'italic',
'link',
'|',
'bulletedList',
'numberedList',
'|',
'heading',
'|',
'undo',
'redo'
]
},
link: {
addTargetToExternalLinks: true,
decorators: {
openInNewTab: {
mode: 'manual',
label: 'Open in a new tab',
defaultValue: true,
attributes: {
target: '_blank',
rel: 'noopener noreferrer'
}
}, title: {
mode: 'manual',
label: 'Set a title',
defaultValue: ''
}
}
}
}
But I want to add a decorator that is like...
addTitleTag: {
mode: 'manual',
label: 'Add a title tag',
defaultValue: '', // Here the user have an input to add a title text
attributes: {
title: 'value'
}
}
But instead of a checkbox, it's text input. Is this possible?
Unfortunately, this can't be achieved using decorators and is not supported by any means by the original plugin you have to modify the plugin in order to do so. I had the same need and modified the plugin.

CKEDITOR adding a simple button should not be this difficult

CKEDITOR.plugins.add('Copyall', {
init: function(editor) {
editor.addCommand('copy_all', {
exec : function(editor){
alert('Yay!');
}
});
editor.ui.addButton('Copyall', {
label: 'Copy All',
command: 'copy_all',
toolbar: 'basicstyles',
icon: 'https://avatars1.githubusercontent.com/u/5500999?v=2&s=16'
});
}
});
CKEDITOR.config.toolbar = [
{name: 'basicstyles', items : ['Copyall', 'Font', 'FontSize', 'Bold', 'Italic', 'Strike']},
];
I have a simple menu for inline CKEDITOR elements. I merely need a button to do some js work.
https://jsfiddle.net/elb_/as1km50L/
Gine an id to your editable area:
<div id="editor1" contenteditable="true">some text</div>
Then, use your id to add the command and the button without a plugin:
CKEDITOR.instances.editor1.addCommand('copy_all', {
exec : function(editor) {
alert('Yay!');
}
});
CKEDITOR.instances.editor1.ui.addButton('Copyall', {
label: 'Copy All',
command: 'copy_all',
toolbar: 'basicstyles',
icon: 'https://avatars1.githubusercontent.com/u/5500999?v=2&s=16'
});
CKEDITOR.config.toolbar = [
{name: 'basicstyles', items : ['Copyall', 'Font', 'FontSize', 'Bold', 'Italic', 'Strike']},
];
See this: https://jsfiddle.net/as1km50L/1/
CKEDITOR.inlineAll();
for (var instanceName in CKEDITOR.instances) {
CKEDITOR.instances[instanceName].addCommand('copy_all', {
exec: function(edt) {
alert('Yay!');
}
});
CKEDITOR.instances[instanceName].ui.addButton('Copyall', {
label: 'Copy All',
command: 'copy_all',
toolbar: 'basicstyles',
icon: 'https://avatars1.githubusercontent.com/u/5500999?v=2&s=16'
});
}
CKEDITOR.config.toolbar = [
{name: 'basicstyles', items : ['Copyall', 'Font', 'FontSize', 'Bold', 'Italic', 'Strike']},
];
See that CKEDITOR.inlineAll() method above? Turns out that CKEDITOR instances are not available to customize unless that beauty is there. It's also interesting to note that without the inlineAll(), the CKEDITOR.instances will show as populated, but for some reason cannot be iterated.
Anyway, problem solved.

Spell Check not working in CKEditor

Spell Check is not working in my CKEditor. I tried disableNativeSpellChecker = false but in vain. Here is my config.js. My CKEditor version is 4.5.6 Any idea ?
CKEDITOR.editorConfig = function( config ) {
// Define changes to default configuration here.
// For complete reference see:
// http://docs.ckeditor.com/#!/api/CKEDITOR.config
config.disableNativeSpellChecker = true;
// The toolbar groups arrangement, optimized for two toolbar rows.
config.toolbarGroups = [
{ name: 'clipboard', groups: [ 'clipboard', 'undo' ] },
{ name: 'editing', groups: [ 'find', 'selection'] },
{ name: 'links' },
{ name: 'insert' },
{ name: 'forms' },
{ name: 'tools' },
{ name: 'document', groups: [ 'mode', 'document', 'doctools' ] },
{ name: 'others' },
{ name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },
{ name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ] },
{ name: 'styles' },
{ name: 'colors' },
{ name: 'about' }
];
// Use line below for line break in toolbar
// '/',
// Html encode ouput
config.htmlEncodeOutput = true;
config.removePlugins = 'elementspath,maximize,scayt';
// Remove some buttons provided by the standard plugins, which are
// not needed in the Standard(s) toolbar.
config.removeButtons = 'Strike,Subscript,Superscript,Source,About,Styles,Blockquote,Link,Unlink,Anchor,Image,Table,HorizontalRule,SpecialChar';
// Set the most common block elements.
config.format_tags = 'p;h1;h2;h3;pre';
// Simplify the dialog windows.
config.removeDialogTabs = 'image:advanced;link:advanced';
};
Integrated the Browser Spell check by adding the following code to config.js
config.disableNativeSpellChecker = false;
config.removePlugins = 'liststyle,tabletools,scayt,menubutton,contextmenu';
Hold down the SHIFT key then click the right mouse button on the text.
At this point the usual context menu with options will be displayed.
On Linux you can use either the SHIFT or the CONTROL keys.
On Mac you can use either the SHIFT or the COMMAND keys.
Here are screenshots WITH and WITHOUT modifier key.

Trying to get CKEDITOR Simple Plugin (Part 1) Example to Work

I added the files provided in the zip download for the Simple Plugin (Part 1) example to a web site with a working CKEDITOR setup. I made no changes to any of the files. A plugin called abbr is supposed to be defined by this code. After reloading the page containing CKEDITOR, I did not see the icon for the plugin appear after I added the plugin to extraPlugins. I then added a reference to the plugin in the insert toolbar but that also did not work.
I can get the plugin dialog to appear by binding to a keystroke, so at least that much works:
config.keystrokes = [
[ CKEDITOR.CTRL + CKEDITOR.SHIFT + 32 /*space*/, 'abbr' ]
];
Here is my ckeditor.js, after removing the Play Framework view markup (hopefully I did not miss any):
<script>
function createEditor() {
var editor = CKEDITOR.instances.BLAH;
if (editor) {
try { editor.destroy(true) ; } catch ( e ) { }
}
editor = CKEDITOR.replace("BLAH", {
height: $(window).height() / 2 - 30,
"extraPlugins": "imagebrowser,abbr,codemirror",
on: {
instanceReady: function(evt) {
var maximized = $.cookie("maximized");
var me = maximized=="true";
if (me)
editor.execCommand('maximize');
},
save: function(evt) {
var scaytEnabled = CKEDITOR.plugins.scayt.state[evt.editor.name];
$.cookie("scayt_enabled", scaytEnabled.toString(), { path: '/' });
var maximized = evt.editor.commands.maximize.state==1;
$.cookie("maximized", maximized.toString(), { path: '/' });
}
}
});
}
</script>
Here is the JavaScript that launches CKEDITOR. abbr is the last plugin mentioned in insert toolbar:
CKEDITOR.editorConfig = function(config) {
config.allowedContent = true;
config.tabSpaces = 2;
config.format_tags = 'p;h1;h2;h3;h4;h5;h6;pre;address;div';
config.toolbarCanCollapse = true;
config.toolbar = [
{ name: 'tools', items : [ 'Maximize', 'ShowBlocks','-','About' ] },
{ name: 'document', items : [ 'Source','-','Save','NewPage','DocProps',/*'Preview',*/'Print','-','Templates' ] },
{ name: 'clipboard', items : [ 'Cut','Copy','Paste','PasteText','PasteFromWord','-','Undo','Redo' ] },
//{ name: 'forms', items : [ 'Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField' ] },
{ name: 'insert', items : [ 'Image',/*'Flash',*/'Table','HorizontalRule','Smiley','SpecialChar','PageBreak','Iframe', 'abbr' ] },
'/',
{ name: 'basicstyles', items : [ 'Bold','Italic','Underline','Strike','Subscript','Superscript','-','RemoveFormat' ] },
{ name: 'colors', items : [ 'TextColor','BGColor' ] },
{ name: 'styles', items : [ 'Styles','Format','Font','FontSize' ] },
'/',
{ name: 'paragraph', items : [ 'NumberedList','BulletedList','-','Outdent','Indent','-','Blockquote','CreateDiv','-','JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'/*,'-','BidiLtr','BidiRtl'*/ ] },
{ name: 'links', items : [ 'Link','Unlink','Anchor' ] },
{ name: 'editing', items : [ 'Find','Replace','-','SelectAll','-','SpellChecker','Scayt' ] }
];
};
I noticed that the instructions had a difference from the code; this code was shown in the instructions:
editor.ui.addButton( 'Abbr', {
label: 'Insert Abbreviation',
command: 'abbrDialog',
toolbar: 'insert'
});
But the code in the download has a different value for command: abbr. Neither value worked. I tried adding abbrDialog to the insert section of config.toolbar but that did not work either. Perhaps there is still another problem.
There's a small bug in this tutorial - in the code you can download the command is named abbr when in the code samples it is abbrDialog.
But name of the button is all the time the same - Abbr (it's case sensitive!). So basically, your config.toolbar setting is incorrect, because you used lower cased name.

Sencha Touch Swap Panels

I just started using sencha touch recently and so far I've got this built:
app.js:
Ext.regApplication({
name: 'app',
launch: function() {
this.launched = true;
this.mainLaunch();
},
mainLaunch: function() {
if (!device || !this.launched) {return;}
this.views.viewport = new this.views.Viewport();
}
});
Viewport.js:
app = Ext.extend(Ext.TabPanel, {
fullscreen: true,
sortable: false,
tabBar: {
dock: 'bottom',
layout: {pack: 'center'}
},
cardSwitchAnimation: {
type: 'slide',
cover: true
},
initComponent: function() {
Ext.apply(app.views, {
searchListTab: new app.views.SearchListTab(),
searchTab: new app.views.SearchTab(),
mapTab: new app.views.MapTab(),
infoTab: new app.views.InfoTab()
});
Ext.apply(this, {
items: [
app.views.searchTab,
app.views.mapTab,
app.views.infoTab
]
});
app.views.Viewport.superclass.initComponent.apply(this, arguments);
}
});
SearchTab.js
app.views.SearchTab = Ext.extend(Ext.Panel, {
title: 'Search',
iconCls: 'search',
dockedItems: [{
xtype: 'toolbar',
title: 'Search'
}],
items: [
{
xtype: 'button',
ui: 'round',
text: 'Hledej',
listeners: {
tap: function() {
Ext.dispatch({
controller: app.controllers.main,
action: 'search',
animation: {type:'slide', direction:'right'}
});
}
}
}
],
initComponent: function() {
app.views.SearchTab.superclass.initComponent.apply(this, arguments);
}
});
SearchListTab.js
app.views.SearchListTab = Ext.extend(Ext.Panel, {
title: 'Search',
iconCls: 'search',
dockedItems: [{
xtype: 'toolbar',
title: 'Search Results'
}],
items: [{
xtype: 'list',
store: app.stores.results,
itemTpl: '{titul}',
grouped: false
//onItemDisclosure: function (record) {
//Ext.dispatch({
// controller: app.controllers.contacts,
// action: 'show',
// id: record.getId()
//});
//}
}],
initComponent: function() {
app.stores.results.load();
app.views.SearchListTab.superclass.initComponent.apply(this, arguments);
}
});
and search.js
app.controllers.main = new Ext.Controller({
search: function(options) {
app.views.searchTab.setActiveItem(
app.views.searchListTab, options.animation
);
}
});
and some other stuff which is not important now. So basically I've got a main viewport which is a tabpanel, then few panels which are its items and one panel which is nowhere from the beginning. Now I want to achieve, that when I click the button in searchTab I want the searchTab panel to swap with searchListTab panel. The problem is, when I use app.views.viewport.setActiveItem(...); it works fine, but it adds a new tab to the tab panel. I just want the current tab panel to slide to another panel, but when I use the code I posted here - app.views.searchTab.setActiveItem(...); it doesn't do anything.
What am I doing wrong? Thanks.
I think you will have to introduce another layer of nesting to achieve this.
I think you want to nest your SearchTab in another Ext.Panel with a card layout and add your SearchListTab to this panel when needed and then you can use the setActiveItem() method to slide across. This will keep your TabPanel visible while moving between sub-views within a tab.
I've drawn a wee diagram to try and explain it better! The black box is the new Panel I think you should add which will replace the SearchTab as the item directly added to the TabPanel.
Hope this helps and is clear!

Resources