CKEditor error creating dialog - javascript

I have the following test script:
var field = {id: "html1"};
var editor = CKEDITOR.replace(field.id);
var dialogObj = new CKEDITOR.dialog(editor, 'smiley');
I get the following error: Uncaught TypeError: Cannot read property 'dir' of undefined
at CKEDITOR.dialog (ckeditor.js:573)
at testCKE.html:24
I am using the full version 4.6.2 (12 Jan 2017)
dir seems to be an element of editor.lang
I experimented with setting config.language and config.defaultLanguage
I tried it with and without jquery, no difference
The editor opens fine and appears to work.
What am i doing wrong?
UPDATE: found an answer, see below. Still interested if there is a better way.

I got the dialog to work using code based on the samples/old/dialog files, cutdown version:
var field = {id: "html1"};
CKEDITOR.on( 'instanceCreated', function( ev ){
var editor = ev.editor;
// Listen for the "pluginsLoaded" event, so we are sure that the
// "dialog" plugin has been loaded and we are able to do our
// customizations.
editor.on( 'pluginsLoaded', function() {
// If our custom dialog has not been registered, do that now.
if ( !CKEDITOR.dialog.exists( 'myDialog' ) ) {
CKEDITOR.dialog.add( 'myDialog', function(){
return {title: 'My Dialog',
minWidth: 400,
minHeight: 200,
contents:[
{
id: 'tabA',
label: 'TabA',
title: 'TabA',
elements: [
{
id: 'button1',
type: 'button',
label: 'Button Field'
}
]
}
]
};
} );
}
// Register the command used to open the dialog.
editor.addCommand( 'myDialogCmd', new CKEDITOR.dialogCommand( 'myDialog' ) );
// Add the a custom toolbar buttons, which fires the above
// command..
editor.ui.add( 'MyButton', CKEDITOR.UI_BUTTON, {
label: 'My Dialog',
command: 'myDialogCmd'
});
});
});
var editor = CKEDITOR.replace(field.id);

Related

CKEditor's dialog textarea is not editable

So I'm making my own plugin to the ckeditor, since I need a special case. Anyway, I can't make textarea element editable. This is my whole code to my own dialog (for the plugin):
CKEDITOR.dialog.add('myDialog', function(editor) {
return {
title: 'My Plugin',
minWidth: 750,
minHeight: 500,
onShow: function(evt) {
var selection = editor.getSelection();
var widget = editor.widgets.selected[0];
var element = !!widget && !!widget.parts ? widget.parts['my'] : false;
var command = this.getName();
if(command == 'myDialog') {
var code = selection.getSelectedElement();
if(code && !!element) {
this.setupContent(code);
widget.data.myinput = element.getHtml();
}
}
},
contents: [{
id: 'info',
label: 'Info',
accessKey: 'I',
elements: [{
id: 'myinput',
type: 'textarea',
required: true,
label: 'Content',
rows: 42,
setup: function(widget) {
this.setValue(widget.data.myinput);
},
commit: function(widget) {
widget.setData('myinput', this.getValue());
}
}]
}],
};
});
Problem is only within contents.myinput. It type is textarea but when I open the dialog its not editable. When I change type to the text and remove rows, then text input shows up, working great and so on. Only textarea is problem. This is how it looks like after opening the dialog:
Version of my CKEditor is 4.5. I already made 3 plugins before, but never had to use textarea so all other plugins works except this one. I would append jsFiddle, if there was any site offering "ckeditor plugin tester" so I just post my code.
Problem is that I init ckeditor in the bootstrap's dialog. So the solution for my problem is to apply the following lines of code after initialization:
$.fn.modal.Constructor.prototype.enforceFocus = function() {
var $modalElement = this.$element;
$(document).on('focusin.modal', function(e) {
var $parent = $(e.target.parentNode);
if($modalElement[0] !== e.target
&& !$modalElement.has(e.target).length
&& !$parent.hasClass('cke_dialog_ui_input_select')
&& !$parent.hasClass('cke_dialog_ui_input_text')
&& !$parent.hasClass('cke_dialog_ui_input_textarea')) {
$modalElement.focus();
}
})
};
I had this code before the problem, but I was missing !$parent.hasClass('cke_dialog_ui_input_textarea') which I forget to add, so this was my fault :)

CKEditor discards widget data after switching to source mode

I am developing a simple widget using the following code. Can anyone please explain to me why the attribute and text iv set turn to undefined after switching to "source mode"?
<pre>
/*
/dialogs/b2eupobject.js
*/
CKEDITOR.dialog.add( 'b2eupobject', function( editor ) {
return {
title: 'Edit Simple Box',
minWidth: 200,
minHeight: 100,
contents: [
{
id: 'info',
elements: [
{
id: 'objectId',
type: 'select',
label: 'ObjectName',
items: [ ['select', '-1' ],
['first name', '1' ],
['last name', '2' ],
],
setup: function( widget ) {
this.setValue( widget.data.title );
//this.setValue(widget.data.desc);
},
commit: function( widget ) {
widget.setData( 'title', this.getValue() );
var input = this.getInputElement().$;
widget.setData('desc',input.options[ input.selectedIndex ].text);
}
},
]
}
],
onShow: function() {
// The code that will be executed when a dialog window is loaded. This function will be defined above the onOk function
var selection = editor.getSelection(); //get to the element that is selected by the user (either highlighted or just having the caret inside)
var element = selection.getStartElement(); // get the element in which the selection starts
if ( element )
element = element.getAscendant( 'em', true ); // get the abbr element
console.log(this);
},
onOk: function() {
// The code that will be executed when a dialog window is loaded. This function will be defined above the onOk function
var selection = editor.getSelection(); //get to the element that is selected by the user (either highlighted or just having the caret inside)
var element = selection.getStartElement(); // get the element in which the selection starts
// if ( element )
console.log (element);
console.log(this);
}
};
} );
</pre>
<pre>
/*
plugin.js
*/
CKEDITOR.plugins.add( 'b2eupobject', {
requires: 'widget', //reference the generic Widget plugin that provides the Widget API
icons: 'b2eupobject',
init: function( editor ) {
CKEDITOR.dialog.add( 'b2eupobject', this.path + 'dialogs/b2eupobject.js' );
editor.widgets.add( 'b2eupobject', {
button: 'Insert user object',
template:'<em class="b2eUp">test </em>',
toolbar:'widgets',
parts: {elm: 'em.b2eUp'}, //this is a CSS selector of the element within the template above that you want to target
allowedContent: 'em ( b2eUp) [title]',
requiredContent : 'em(b2eUp) [title]',
dialog: 'b2eupobject',
init: function (widget) {
console.log("widget init : "+widget);
// widget.parts.elm.setAttribute('title',this.data.title);
// widget.parts.elm.setHtml(this.data.desc);
},
data: function (widget) {
this.parts.elm.setAttribute('title',this.data.title);
this.parts.elm.setHtml(this.data.desc);
},
upcast: function( element ) {
alert(element.name == 'em' && element.hasClass( 'b2eUp' ));
return element.name == 'em' && element.hasClass( 'b2eUp' );
},
} );
var pluginDirectory = this.path;
editor.addContentsCss( pluginDirectory + 'style/style.css' );
if ( editor.contextMenu ) {// check if contextmenu plugin exsists
editor.addMenuGroup( 'b2eupgrouGroup' ); // register a new menu group called abbrGroup.
editor.addMenuItem( 'b2eupItem', { //register a new menu item that will belong to the newly created group.
label: 'Edit user object',
icon: this.path + 'icons/b2eupobject.png',
command: 'b2eupobject',
group: 'b2eupgrouGroup'
});
editor.contextMenu.addListener( function( element ) { // add an event listener function that will be called whenever the context menu is fired.
if ( element.getAscendant( 'em', true ) ) {
// check if element is of type abbr
return { simpleboxitem: CKEDITOR.TRISTATE_OFF };
}
});
};
},
enter code here
} );
</pre>
I'm using CKEditor version 4.5 and I have both the widget and dialog plugins installed.
******* addition ******
when i return from source mode in the editor i can see that the upcast function is invoked.
writing to log, i can see that it returns true and that the element object :
FF console:
attributes: Object { class="b2eUp", title="1", data-cke-widget-data="%7B%7D", more...}
children:[Object { value="first name", _={...}, parent={...}, more...}]

Add Custom Button in User JavaScript for MediaWiki

I want to create a button like the one that inserts your signature. How to do this?
After doing some research I figured out that I can insert custom buttons with the User:MYUSERNAME/common.js page.
I saw several examples. But the wiki references and informations are often splittet across multiple pages and out dated. So I try here if I am lucky and find someone who tried similar things.
Who can help me with this:
var customizeToolbar = function() {
$('#wpTextbox1').wikiEditor('addToToolbar', {
section: 'advanced',
group: 'format',
tools: {
"comment": {
label: 'Comment',
type: 'button',
icon: '//upload.wikimedia.org/wikipedia/commons/3/37/Btn_toolbar_commentaire.png',
action: {
type: 'encapsulate',
options: {
pre: "<!-- ",
post: " -->"
}
}
}
}
});
};
When I do it like this, nothing happens because customizeTooblar most likely gets never called. When I remove it, it says that wikiEditor is not defined.
I already enabled $wgAllowUserJs = true; in LocalSettings.php.
I saw this question: Creating custom edit buttons for MediaWiki Is this still the way we should do this kind of things? This is possibly not a dublicate question because I am already asking about my particular issue here.
The problem was that the initiation code was missing.
This code should directly add a smiley label to your advanced toolbar:
var customizeToolbar = function() {
/* Your code goes here */
$( '#wpTextbox1' ).wikiEditor( 'addToToolbar', {
'section': 'advanced',
'group': 'insert',
'tools': {
'SimpleComment': {
label: 'Comment',
type: 'button',
icon: '//upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Gnome-face-smile.svg/22px-Gnome-face-smile.svg.png',
action: {
type: 'encapsulate',
options: {
pre: "preText",
post: "postText"
}
}
}
}
} );
};
/* Check if view is in edit mode and that the required modules are available. Then, customize the toolbar … */
if ( $.inArray( mw.config.get( 'wgAction' ), [ 'edit', 'submit' ] ) !== -1 ) {
mw.loader.using( 'user.options', function () {
// This can be the string "0" if the user disabled the preference ([[phab:T54542#555387]])
if ( mw.user.options.get( 'usebetatoolbar' ) == 1 ) {
$.when(
mw.loader.using( 'ext.wikiEditor.toolbar' ), $.ready
).then( customizeToolbar );
}
} );
}
// Add the customizations to LiquidThreads' edit toolbar, if available
mw.hook( 'ext.lqt.textareaCreated' ).add( customizeToolbar );
Can be added to wiki/User:YOUR_USRNAME/common.js
In LocalSettings.php this option must be enabled $wgAllowUserJs = true;

Is there a possibility to add a HTML element dynamically inside a dialog of a plugin in CK-EDITOR?

I am creating a widget in ck-editor where when user clicks a toolbar button,a dialog is opened.In a dialog there is text field and one search button,rest area in a dialog is for search results to be shown.
Is it possible that user enters some text in a text field , hit search button and by using some API I display some 50 search results(scrollable) in a dialog of a plugin below the text field and search button?
Right now I am using this code (just a dummy to check if I can add elements dynamically)-
CKEDITOR.dialog.add('simplebox', function(editor){
return {
title: 'Reference',
minWidth: 600,
minHeight: 400,
onShow: function() {
alert(CKEDITOR.dialog.getCurrent().definition.getContents("new_reference").elements);
},
contents: [
{
id: 'new_reference',
label:'New Reference',
elements: [
{
id: 'type',
type: 'select',
label: 'Type',
items: [
[ editor.lang.common.notSet, '' ],
[ 'Book' ],
[ 'Journal' ],
[ 'URL' ],
[ 'PHD Thesis']
]
},
{
type: 'text',
id: 'reference',
label: 'Reference',
validate: CKEDITOR.dialog.validate.notEmpty( "Search field cannot be empty." )
},
{
type: 'button',
align:'horizontal',
id: 'referencebutton',
label:'Search',
title: 'My title',
onClick: function() {
var linkContent = { type : 'html', id : 'test', html : '<div>just a test</div>' };
// this = CKEDITOR.ui.dialog.button
var dialog = CKEDITOR.dialog.getCurrent();
//alert(dialog.getContentElement('new_reference','reference').getValue());
var definition = dialog.definition;
//alert(definition.title);
definition.getContents("new_reference").add(linkContent);
// CKEDITOR.dialog.addUIElement('list',function(){
// definition.getContents("new_reference").add(linkContent);
// });
alert(CKEDITOR.dialog.getCurrent().definition.getContents("new_reference").elements);
}
}
]
},
{
id: 'old_reference',
label:'Old Reference',
elements: [
{
id:'author',
type:'text',
label:'Author'
}
]
}
]
};
});
Inside onShow method I am printing the no. of UI elements inside a content of a dialog.It shows 3 objects. After click of a button,it shows 4 objects since one has been added via code but it does show in the UI?
Any clues on this?
Thanks
Your approach is OK but by calling
definition.getContents("new_reference").add(linkContent);
you're modifying CKEDITOR.dialog.definition, which is used only the first time the dialog is opened – to build it. Then, once built, if you close the dialog and open it again, the editor uses the same DOM to display it. What I mean is that CKEDITOR.dialog.definition is a blueprint, which is used once and has no further impact on the dialog.
To interact with live dialog, use the following
CKEDITOR.ui.dialog.uiElement-method-getDialog,
CKEDITOR.dialog-method-getContentElement (returns CKEDITOR.ui.dialog.uiElement),
CKEDITOR.dialog-method-getValueOf,
CKEDITOR.dialog-method-setValueOf
like
onClick: function() {
var dialog = this.getDialog();
// get the element
console.log( dialog.getContentElement( 'tabName', 'fieldId' ) );
// get the value
dialog.getValueOf( 'tabName', 'fieldId' ) );
// set the value
dialog.setValueOf( 'tabName', 'fieldId', 'value' ) );
}
One way to get around this problem is to use the onShow function and insert an html object in the dialog tab.
onShow : function() {
var element = document.createElement("div");
element.setAttribute('id', "someId");
document.getElementsByName("new_reference")[0].appendChild(element);
}
Then in the onClick function, just access the element and set the content you want, like this:
onClick : function() {
document.getElementById("someId").innerHTML='<div id="example-'+count+'">Hello World</div>';
}
By doing this, you should be able to get data to show in your dialog. Hope it helps.

ckeditor error while creating file upload button

I am using below code to create a ckeditor plugin to upload images. While i am trying to create a ckeditor dialog, I am getting below errors. Below piece of code i took from the below link.
http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.dialog.definition.button.html
In chrome :
Uncaught TypeError: Cannot read property '_' of undefined
In firefox :
b.getContentElement(...) is undefined
Any help will be greateful.
{
type : 'file',
id : 'upload',
label : 'Select file from your computer',
size : 38
},
{
type : 'fileButton',
id : 'fileId',
label : 'Upload file',
'for' : [ 'tab1', 'upload' ],
filebrowser : {
onSelect : function( fileUrl, data ) {
alert( 'Successfully uploaded: ' + fileUrl );
}
}
},
I think that what you have there, is not "code" as it. Is just the object definition you must do to initialize a button in a dialog, as the docs you pasted say:
This class is not really part of the API. It just illustrates the
properties that developers can use to define and create buttons.
Once the dialog is opened, the created element becomes a
CKEDITOR.ui.dialog.button object and can be accessed with
CKEDITOR.dialog#getContentElement. For a complete example of dialog
definition, please check CKEDITOR.dialog.add.
Then, if we check that: http://docs.ckeditor.com/#!/api/CKEDITOR.dialog.definition
We will find this code:
CKEDITOR.dialog.add( 'testOnly', function( editor ) {
return {
title: 'Test Dialog',
resizable: CKEDITOR.DIALOG_RESIZE_BOTH,
minWidth: 500,
minHeight: 400,
contents: [
{
id: 'tab1',
label: 'First Tab',
title: 'First Tab Title',
accessKey: 'Q',
elements: [
{
type: 'text',
label: 'Test Text 1',
id: 'testText1',
'default': 'hello world!'
}
]
}
]
};
} );
Then it seems you need to call the method CKEDITOR.dialog.add with the object you prepared. (anyway, I din´t checked all the data and the formats you have in your object) this example should work.
Anyway, you should check this part of the same documentation and be sure on which one is the dialog/plugin you need.
Hope it may help to you.

Categories