Dialog windows for CKEditor by default appear in the middle of the page but if the page is an iframe with a big height the dialogs appear way down the page.
Is it possible to configure CKEditor to position the dialogs in a different quadrant of the page? For example top middle?
Yes, the link MDaubs gives will guide you to do what you want.
I've had to do this in the past and the following snippet will demonstrate a solution for your problem:
CKEDITOR.on('dialogDefinition', function(e) {
var dialogName = e.data.name;
var dialogDefinition = e.data.definition;
dialogDefinition.onShow = function() {
this.move(this.getPosition().x,0); // Top center
}
})
You can place this in the config file or the ready function for jQuery.
The solution by zaf works in that it helps to position the dialog, but I've found it to produce a bunch of side effects as to how the dialog functions (failing to display the URL of the image in the image dialog is one example).
It turned out that the original onShow() method that is being overridden returns a meaningful value that we should keep. This could be due to a plugin or something, but here's the code that ultimately worked for me:
CKEDITOR.on('dialogDefinition', function(e) {
var dialogName = e.data.name;
var dialogDefinition = e.data.definition;
var onShow = dialogDefinition.onShow;
dialogDefinition.onShow = function() {
var result = onShow.call(this);
this.move(this.getPosition().x, $(e.editor.container.$).position().top);
return result;
}
});
This may be way you're looking for:
Programatically set the position of CKEditor's dialogs
I just had the same issue as Yehonatan and found this question really fast via Google. But after using the answer provided by zaf I still didn't get a dialog to appear in the proper position when the editor is loaded within an iframe.
In stead of the position() method I used the offset() method to place a dialog right under the toolbar. Together with the response of jonespm I came to this code that seems to work very good, also with existing dialogs.
CKEDITOR.on('dialogDefinition', function(e) {
var dialogName = e.data.name;
var dialogDefinition = e.data.definition;
var onShow = dialogDefinition.onShow;
dialogDefinition.onShow = function() {
this.move(this.getPosition().x, jQuery(this.getParentEditor().container.$).offset().top);
if (typeof onShow !== 'undefined' && typeof onShow.call === 'function')
{
return onShow.call(this);
}
}
});
Hopefully this code can help others with the same issue as me.
Correct syntax is:
CKEDITOR.on('dialogDefinition', function(ev) {
var dialogName = ev.data.name;
var dialogDefinition = ev.data.definition;
var dialog = dialogDefinition.dialog;
if (dialogName == 'image2') {
dialogDefinition.onShow = CKEDITOR.tools.override(dialogDefinition.onShow, function(original) {
return function() {
original.call(this);
CKEDITOR.tools.setTimeout( function() {
/*do anything: this.move(this.getPosition().x, $(e.editor.container.$).position().top);*/
}, 0);
}
});
}
});
Related
It's not a question, but rather a solution (with a small dirty trick).
I needed to insert an image in CKEditor with "center" alignment by default. I could not find working example, so I spent lots of time and come up with the following answer.
In your editor's config.js
CKEDITOR.on( 'dialogDefinition', function( ev ) {
// Take the dialog name and its definition from the event data.
var dialogName = ev.data.name;
var dialogDefinition = ev.data.definition;
if ( dialogName == 'image2' ) {
ev.data.definition.dialog.on('show', function() {
//debugger;
var widget = ev.data.definition.dialog.widget;
// To prevent overwriting saved alignment
if (widget.data['src'].length == 0)
widget.data['align'] = 'center';
});
}
});
Enjoy!
I've used the above solution for a few years successfully - although now (CKEditor Version 4.14.0) it throws an error and no longer works. After a bunch of troubleshooting and assistance from admittedly old documentation from here:
https://nightly.ckeditor.com/20-05-20-06-04/standard/samples/old/dialog/dialog.html
... the following seems to work here:
In editor config.js file:
CKEDITOR.on('dialogDefinition', function(ev) {
let dialogName = ev.data.name;
let dialogDefinition = ev.data.definition;
console.log(ev);
if (dialogName == 'image2') {
dialogDefinition.onFocus = function() {
/**
* 'none' is no good for us - if is none - reset to 'center'
* if it's already 'left','center', or 'right' - leave alone.
*/
if (this.getContentElement('info', 'align')
.getValue() === 'none') {
this.getContentElement('info', 'align')
.setValue('center');
}
};
}
});
I am trying to embed into the editor an uploaded image. My filebrowserUploadUrl is /api/m/image and it seems to be working fine. After I clicked the Send it to the Server button, there is a script error as follows:
image.js?t=H4PG:19 Uncaught TypeError: Cannot read property 'setCustomData'
of undefined
at textInput.onChange (image.js?t=H4PG:19)
at textInput.n (ckeditor.js:10)
at textInput.CKEDITOR.event.CKEDITOR.event.fire (ckeditor.js:12)
at textInput.setValue (ckeditor.js:619)
at textInput.setValue (ckeditor.js:545)
at a.q (ckeditor.js:841)
at ckeditor.js:31
at Object.callFunction (ckeditor.js:31)
at image?CKEditor=editor&CKEditorFuncNum=1&langCode=en:1
The last line in the above is the call to filebrowserUploadUrl and the response from that is:
window.parent.CKEDITOR.tools.callFunction(1, '/images/bulletins.jpg', 'Uploaded successfully');
The Uploaded successfully message is shown in an alert. The Preview box under Image Info tab is not updated. But if I clicked OK to close the dialog, the image (bulletins.jpg) is embedded in the editor alright.
What could be causing the error and how do I fix it?
I found what was causing it. I wanted to set the default tab when the insert image dialog is launched to the Upload tab. I use the following code:
CKEDITOR.on("dialogDefinition", function(ev) {
var dialogName = ev.data.name;
var dialogDefinition = ev.data.definition;
if (dialogName === "image") {
dialogDefinition.onShow = function() {
this.selectPage("Upload");
}
}
});
When the above code is used, that error happens when a file is uploaded.
I was having same issue, and after using proposed solution from vikram, editor was generating error while pasting image link into the text. Better approach here, not to completely override default onShow method, but add more to it in the following way:
CKEDITOR.on('dialogDefinition', function (ev) {
var dialogName = ev.data.name;
var dialogDefinition = ev.data.definition;
if (dialogName == 'image') {
var oldOnShow = dialogDefinition.onShow;
var newOnShow = function () {
this.selectPage('Upload');
this.hidePage('Link');
// change tabs order
$('a[title=Upload].cke_dialog_tab').css('float', 'left');
};
dialogDefinition.onShow = function () {
oldOnShow.call(this, arguments);
newOnShow.call(this, arguments);
};
}
});
After debugging a lot I found a solution on this.
If you will see onChange method of txtUrl textBox in image.js
See line number 507 and 513
you will understand cause of this error.
at line 513 setCustomData is called.
original.setCustomData( 'isReady', 'false' );
CKEDITOR.on("dialogDefinition", function(ev) {
var dialogName = ev.data.name;
//current editor
var editor = ev.editor;
var dialogDefinition = ev.data.definition;
if (dialogName === "image") {
dialogDefinition.dialog.on('show', function(e){
var dialogBox = e.sender;
//This line is the answer of your question
//this line will get rid of the error setCustomData
dialogBox.originalElement = editor.getSelection().getStartElement();
this.selectPage("Upload");
});
}
});
When pasting data into a cell, the page scrolls to the top of the page or to the bottom of the targeted cell.
How can I remove any scrolling on paste? I would like for the page to not move at all.
You can apply fixes like below code:
$(document).ready(function () {
var position_Y_before = null;
$(".handsontable").handsontable({
//some code here for initializing the table and its functions
//Then I added this callback function
beforeKeyDown: function(e) {
position_Y_before = window.pageYOffset || 0;
};
});
//Here we prevent from scrolling to top of page after pasting to handsontable with cmd+v or ctrl+v
$(window).scroll(function(){
if(position_Y_before != null){
window.scrollTo(0, position_Y_before);
position_Y_before = null;
}
});
});
This works for me at least, hope it helps you as well!
I have this code:
function getArea (){
var area1 = document.getElementById('first');
var area2 = document.getElementById('adart');
if (area1.style.display.match("none") && area2.style.display.match("none"))
{
area1.style.display = 'block';
}
else
{
area1.style.display = 'none';
}
}
function getArea1 (){
var addArticle = document.getElementById('adart');
var area1 = document.getElementById('first');
if (addArticle.style.display.match("none") && area1.style.display.match("none"))
{
addArticle.style.display = 'block';
}
else
{
addArticle.style.display = 'none';
}
}
Now, in my html page:
I have two text areas and two buttons.
Each button "activates" a different text area.
All that my code does is to make the property 'display' in each text area to be "block" or "none", also, to make sure that if one text is already visible, the others will not.
The problem is that the first button "edit article" is not working until I click on the second button "add article". The second button works properly.
Any thoughts?
A while back I found some code that allows you to filter the contents of a SELECT by typing in a text element. It works well however, over time the performance degrades pretty badly. I'm not sure if it is the filter code or the way in which I am activating it.
The SELECT shows up in a modal dialog (bootstrap) so I have the following code:
$('#myModal').on('shown', function () {
$(".focusable").val("").focus();
var select = $('#myModal').find(".modal-body").find("select");
var text = $('#myModal').find(".modal-body").find("input[type='text']");
select.filterByText(text, true);
});
And here is the filter code:
jQuery.fn.filterByText = function (textbox, selectSingleMatch) {
return this.each(function () {
var select = this;
var options = [];
$(select).find('option').each(function () {
options.push({value:$(this).val(), text:$(this).text(), data:$(this).data("short-name")});
});
$(select).data('options', options);
$(textbox).bind('change keyup', function () {
var options = $(select).empty().data('options');
var search = $.trim($(this).val());
var regex = new RegExp(search, 'gi');
$.each(options, function (i) {
var option = options[i];
if (option.text.match(regex) !== null) {
var copyOption = $('<option>').text(option.text).val(option.value);
copyOption.data("short-name", option.data);
$(select).append(copyOption);
}
});
if (selectSingleMatch === true &&
$(select).children().length === 1) {
$(select).children().get(0).selected = true;
}
});
});
};
Can anyone shed some light on where my performance issue(s) might be and how to solve it?
reading through the comments I would suggest to add the following:
$(textbox).bind('change keyup', function(event) {
console.log(event);
// your code
});
Is the event triggered more than once on a single keyup after some times the dialog is shown?
$('#myModal').on('hidden', function () {
$('#myModal').find(".modal-body").find("input[type='text']").off("change keyup");
});