CKEditor 4.7 - Justify Group Menu Button - javascript

i'm trying to create a dropdown menu in CKEditor to group some normal button tool just because i need to compress the toolsbar. For this i'm trying to create, for example, a justify group button menu, for this i have compile this plugin :
CKEDITOR.plugins.add('justifygroup', {
requires: ['justify'],
init: function (editor) {
var items = {
justifyleft: {
label: editor.lang.justify.left,
group: 'justify_group',
command: 'justifyleft',
// icon: CKEDITOR.getUrl(this.path + 'icons/icon.png'),
order: 1
},
justifycenter: {
label: editor.lang.justify.center,
group: 'justify_group',
command: 'justifycenter',
order: 2
},
justifyright: {
label: editor.lang.justify.right,
group: 'justify_group',
command: 'justifyright',
order: 3
},
justifyblock: {
label: editor.lang.justify.block,
group: 'justify_group',
command: 'justifyblock',
order: 4
}
};
editor.addMenuGroup('justify_group');
editor.addMenuItems(items);
editor.ui.add('JustifyGroup', CKEDITOR.UI_MENUBUTTON, {
label: 'Justify Group',
icon: 'JustifyLeft',
// Disable in source mode.
modes: {
wysiwyg: 1
},
onMenu: function () {
var activeItems = {};
// Make all items active.
for (var prop in items)
activeItems[prop] = CKEDITOR.TRISTATE_OFF;
return activeItems;
}
});
}
});
here it is a demo of this plugin : https://codepen.io/seltix/pen/dWxWbO
CKEDITOR.replace('textarea', {
extraPlugins: 'justifygroup',
toolbar:[{name: 'test', items: ['JustifyGroup']}]
});
the problems :
1 - if i dont call one of the align buttons on the toolbar ('JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock') the
button menu does not show any button
2 - i'm unable to control some
sort of visual mark to show what alignment is in use (like on the
toolbar buttons)
UPDATE : I found the solution for this problem on the "onMenu" function replacing activeItems[prop] = CKEDITOR.TRISTATE_OFF; with activeItems[prop] = editor.getCommand(items[prop].command).state;
3 - i dont know why but the first option is always
with "focus", how can I set the focus to match a specific item?
thanks all!

1 - The problem that is causing buttons not to display is ACF. Buttons that you're grouping in your dropdown requires certain tags/attrs to be available. In the simplest case it requires text-align to be applicable on p.
It looks that there's a bug in CKEditor that buttons added using editor.addMenuItems are not registering properly new ACF rules, while they do if added directly to the toolbar.
3 - I couldn't find a proper function for that, IMHO it should be doable in onMenu function, however it does not provide enough references to do that. Sounds like a feature request.
Generally you should look at language plugin, as it has many things you are looking for so it's a nice source of inspiration.
For future reference, please create separate StackOverflow question for each case. Though these issues were releated, they are a different cases.

Related

CKEditor insert html duplicates

Here's my code
CKEDITOR.rbcPluginTools.addCustomPlugins('custom_author_signature', [
{
name: "author_signature",
title: "Подпись автора",
tooltip: "Добавить подпись автора",
icon: 'author_signature',
hidpi: true,
toolbar: "media,9",
exec: function (plugin, editor) {
selection = editor.getSelection();
if(selection.getSelectedText()) {
editor.insertHtml(`<div class="back_container author_signature">${editor.getSelection().document.getBody().getHtml()}</div>`);
}
}
}
]);
'back_container' is for background-color. Looks like it duplicates divs for some weird reason, cause after 2 executions it makes 3 back colors instead of two.
Expected behavior:
select text -> press plugin button -> 1 background container
select text inside this background container -> press plugin button -> 2 background containers (not 3!)

Custom plugin with DOM manipulation CKEditor 4.x

I am developing one custom plugin for the CKEditor 4.7 which do a simple think take in case user select some stuff it will put it in a div with specific class, else it will put a div with same class just with text like 'Add content here'
I try to use some functions according to CKEditor docs but have something really wrong.
here is the code for the plugin folder name=> customdiv, file=> plugin.js
CKEDITOR.plugins.add('customdiv', {
icons: 'smile',
init: function (editor) {
editor.addCommand( 'customdiv',{
exec : function( editor ){
var selection = editor.getSelection();
if(selection.length>0){
selection='<div class="desktop">'+selection+'</div>';
}else{
selection='<div class="desktop">Add your text here </div>';
}
return {
selection
};
}
});
editor.ui.addButton( 'Customdiv',
{
label : 'Custom div',
command : 'customdiv',
toolbar: 'customdiv',
icon : this.path + 'smile.png'
});
if (editor.contextMenu) {
editor.addMenuGroup('divGroup');
editor.addMenuItem('customdiv', {
label: 'Customdiv',
icon: this.path + 'icons/smile.png',
command: 'customdiv',
group: 'divGroup'
});
editor.contextMenu.addListener(function (element) {
if (element.getAscendant('customdiv', true)) {
}
});
}
}
});
According to some docs it have to return the result good.
Also this is how I call them in my config.js file
CKEDITOR.editorConfig = function (config) {
config.extraPlugins = 'templates,customdiv';
config.allowedContent = true;
config.toolbar = 'Custom';
config.toolbar_Custom = [
{ name: 'divGroup', items: [ 'Customdiv' ] },
{name: 'document', items: ['Source', '-', 'Save', 'Preview', '-', 'Newplugin']},
/* MOre plugins options here */
];
};
Note: the official forum was close and moved here :(
UPDATE
I have change the function like this
exec : function( editor ){
var selection = editor.getSelection();
if(selection.length>0){
selection='<div class="desktop">'+selection+'</div>';
CKEDITOR.instances.editor1.insertHtml( selection );
}else{
selection='<div class="desktop">Add your text here </div>';
CKEDITOR.instances.editor1.insertHtml( selection );
}
}
This makes it work for the else part, but still can't get the selected one.
UPDATE 2
After change of the if I can get data if is selected, but when I do insert selected between <div> I face a problem.
var selection = editor.getSelection();
give like result an object, and I funded out a more complex function and I get collected data like this
var selection = editor.getSelection().getNative();
alert(selection);
from this in alert I see the proper selection and not just object,but when I insert it like
CKEDITOR.instances.editor1.insertHtml('<div class="desktop">' + selection + '</div>');
it just put all selected in one line and not adding the div, new div for else case working with this syntax.
UPDATE 3
The problem now is this function
CKEDITOR.instances.editor1.insertHtml('<div>' + selection + '<div>');
it delete all existing HTML tags even if I add just selection without <div> I am not sure if this is because of the way I insert data or way I collect data, just in alert when I collect data I see correct space like in the editor.
user select some stuff it will put it in a div with specific class
If you want to check if selection is not empty, please instead of selection.length>0 try using !selection().getRanges()[0].collapsed.
If you need something more advanced you could also try using
!!CKEDITOR.instances.editor1.getSelection().getSelectedText() to see if any text was selected and !!CKEDITOR.instances.editor1.getSelection().getSelectedElement() to see if any element like e.g. image, tabl,e widget or anchor was selected.
EDIT:
If you need selected HTML please use CKEDITOR.instances.editor1.getSelectedHtml().getHtml();
Please also have a look at CKEditor documentation:
https://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getSelectedHtml
https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_dom_documentFragment.html#method-getHtml
https://docs.ckeditor.com/#!/api/CKEDITOR.dom.selection-method-getSelectedText
https://docs.ckeditor.com/#!/api/CKEDITOR.dom.selection-method-getSelectedElement

Predefined buttons in CKEditor Mathjax plugin

CKEditor's Mathjax plugin contains several elements in the dialog: one textarea (id: equation) and one div (id: preview).
https://github.com/ckeditor/ckeditor-dev/blob/master/plugins/mathjax/dialogs/mathjax.js
When some mathjax code is entered in the textarea, the formula is written in the div. I am trying to add several predefined buttons that add usual formulae mathjax text to the textarea, so users only have to populate these formulae.
Adding a button into the elements works nice, but I can only access to change the div element. Accessing the textarea does not work, it seems that is not available in any scope at all.
id: 'info',
elements: [
{
id: 'testButton',
type: 'button',
button: 'aaaa',
onClick: function() {
// Changing the ID value does work
preview.setValue('Test');
// but changing the textarea does not.
// equation.setValue('Test');
// document.getElementById('equation').setValue('Test');
}
},
{
id: 'equation',
type: 'textarea',
label: lang.dialogInput,
onLoad: function() {
var that = this;
if ( !( CKEDITOR.env.ie && CKEDITOR.env.version == 8 ) ) {
this.getInputElement().on( 'keyup', function() {
// Add \( and \) for preview.
preview.setValue( '\\(' + that.getInputElement().getValue() + '\\)' );
} );
}
},
Sorry if this is a simple question, but how can I access to equation textarea?
After much reading, it seems that this is a way, not sure it's the best way though.
onClick: function() {
this._.dialog.setValueOf("info","equation","TEST");
}

CKEditor Remove (selected) from label on click

I have created a simple plugin to move some of the formatting buttons to a dropdown button. The dropdown button has both an icon and a label. The plugin works as intended except that when clicked on the label shows both the intended text as well as adding "(selected)" to the end.
Here is the button default view (the formatting button):
And here is how it looks when clicked on:
Here is the code for the plugin:
CKEDITOR.plugins.add( 'sf_formatting', {
init: function( editor ) {
var format = {};
editor.addMenuGroup( 'format_group' );
format.indent = {
label: 'Increase Indent',
group: 'format_group',
command: 'indent',
order: 6
};
format.outdent = {
label: 'Decrease Indent',
group: 'format_group',
command: 'outdent',
order: 7
};
editor.addMenuItems( format );
editor.ui.add( 'Formatting', CKEDITOR.UI_MENUBUTTON, {
label: 'Formatting',
// Disable in source mode.
modes: {
wysiwyg: 1
},
icon: 'dropdown',
onMenu: function() {
var active = {};
// Make all items active.
for ( var p in format )
active[ p ] = CKEDITOR.TRISTATE_OFF;
return active;
}
} );
}
});
I have a second issue
The outdent (decrease indent) only appears when the text has been indented. In the main menu it is always there but greyed out. How can I force the outdent button to always be visible in the dropdown box but not accessible.
Here is a screenshot of the dropdown when the text has been indented:
I'd be really grateful for any help.
I managed to create a hack to make this work as no one seems to know the answer.
In the language file, the relevant entry is "%s (Selected)". %s is replaced by the menu title in the plugin code.
I just removed the "(Selected") and now it works fine FOR MY USE.
It may break other things I am unaware of, but it works for me

How to add a customize buttons in dojox grid?

I've developed web applications with Dojo for more than one year, and I've used dojox grid a lot, but there is no way to add customize buttons on DataGrid or EnhancedGrid, as I know that ExtJS, or EasyUI, jQuery jqgrid are capable doing this.
So I want to ask if there is any way that can add buttons or other HTML DOM in the dojox.DataGrid?
at least, you can add dojo.form.Button's to it. simly add an element to the structure-property of your DataGrid like that (sorry, due to no-time i just copy pasted it from an actual project of mine...):
{
name: ' ',
field: 'idx',
type: dojox.grid.cells._Widget,
editable: false,
formatter: function (idx) {
return new dijit.form.Button({
_destroyOnRemove: true,
label: 'Bearbeiten',
onClick: function () {
dojo.byId('clickedItemIdx').value = idx + '';
if (reports.entries[idx].type == 'Rufbereitschaft') {
dojo.byId('addOrEditEntry_OCD_btn').click();
} else {
dojo.byId('addOrEditEntry_ASS_btn').click();
}
}
});
}
},
note that my data contains an idx-field which i commit to the onclick-function in order to know which element was clicked. This is the only way i got this to work.
As you may know, you can add multiple of those structure-elements referring to the same field.

Categories