Reputation: 51
I have a jQuery UI Dialog that has a CKEditor instance on it. I can open the dialog and interact fine with the editor. But if I open another jQuery UI dialog from the original dialog the text in the editor disappears when the second dialog opens and the editor can't be used until you reload the entire page.
This works fine if the CKEditor instance is not in a dialog. I can open up the child dialog, use it, close it, and still interact with editor.
Any ideas what is going on and how to make it work?
Sample program below or http://jsfiddle.net/3EyM4/1/
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/ckeditor/4.3.2/ckeditor.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/ckeditor/4.3.2/adapters/jquery.js"></script>
</head>
<body>
<script>
$(document).ready(
function()
{
$('textarea').ckeditor( { toolbar: [] } );
$( "#childDialog" ).dialog(
{
autoOpen: false
} );
$( "#parentDialog" ).dialog(
{
autoOpen: false
} );
});
</script>
<div>
Main page
<button onclick="$('#parentDialog').dialog( 'open' );">Open Parent</button>
</div>
<div id="parentDialog" title="Parent Dialog">
<button onclick="$('#childDialog').dialog( 'open' );">Open Child</button>
<textarea name="editorTextArea"></textarea>
</div>
<div id="childDialog" title="Child Dialog">
Child
</div>
</body>
</html>
Upvotes: 4
Views: 4411
Reputation: 97
To get around the Problems when having a CKEDITOR in a Jquery ui-dialog I did the following:
Problem 1: Dropdowns like font-size etc. arent visible in ckeditor.
Solution: config.baseFloatZIndex=9999999;
Problem 2: Input Fileds in CKEDITOR Dialog arent "active".
Solution: Close ui-dialog when ckeditor dialog opens and vice-versa
Problem 3: Ckeditor dialog input fields arent "active" when ckeditor switches to fullscreen mode
Solution: Close jquery ui-dialog when ckeditor is going to fullscreen, reopen when leaving fullscreen mode
My CKEDITOR jquery adapter now looks like this, works fine for me:
/*
Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md or http://ckeditor.com/license
*/
(function(a) {
if ("undefined" == typeof a) throw Error("jQuery should be loaded before CKEditor jQuery adapter.");
if ("undefined" == typeof CKEDITOR) throw Error("CKEditor should be loaded before CKEditor jQuery adapter.");
console.error("CKEDITOR jQuery Team-pro adapter v0.4a");
CKEDITOR.config.jqueryOverrideVal = "undefined" == typeof CKEDITOR.config.jqueryOverrideVal ? !0 : CKEDITOR.config.jqueryOverrideVal;
a.extend(a.fn, {
ckeditorGet: function() {
var a = this.eq(0).data("ckeditorInstance");
if (!a) throw "CKEditor is not initialized yet, use ckeditor() with a callback.";
return a
},
ckeditor: function(g, d) {
if (!CKEDITOR.env.isCompatible) throw Error("The environment is incompatible.");
if (!a.isFunction(g)) {
var m = d;
d = g;
g = m
}
var k = [];
d = d || {};
this.each(function() {
var b = a(this),
c = b.data("ckeditorInstance"),
f = b.data("_ckeditorInstanceLock"),
h = this,
l = new a.Deferred;
k.push(l.promise());
if (c && !f) g && g.apply(c, [this]), l.resolve();
else if (f) c.once("instanceReady", function() {
setTimeout(function() {
c.element ? (c.element.$ == h && g && g.apply(c, [h]), l.resolve()) : setTimeout(arguments.callee, 100)
}, 0)
},
null, null, 9999);
else {
if (d.autoUpdateElement || "undefined" == typeof d.autoUpdateElement && CKEDITOR.config.autoUpdateElement) d.autoUpdateElementJquery = !0;
d.autoUpdateElement = !1;
b.data("_ckeditorInstanceLock", !0);
c = a(this).is("textarea") ? CKEDITOR.replace(h, d) : CKEDITOR.inline(h, d);
b.data("ckeditorInstance", c);
c.on("instanceReady", function(d) {
var e = d.editor;
e.config.baseFloatZIndex=9999999;
setTimeout(function() {
if (e.element) {
d.removeListener();
e.on("dataReady", function() {
b.trigger("dataReady.ckeditor", [e])
});
e.on("setData", function(a) {
b.trigger("setData.ckeditor", [e, a.data])
});
e.on("getData", function(a) {
b.trigger("getData.ckeditor", [e, a.data])
}, 999);
e.on("destroy", function() {
b.trigger("destroy.ckeditor", [e])
});
e.on("save", function() {
a(h.form).submit();
return !1
}, null, null, 20);
if (e.config.autoUpdateElementJquery && b.is("textarea") && a(h.form).length) {
var c = function() {
b.ckeditor(function() {
e.updateElement()
})
};
a(h.form).submit(c);
a(h.form).bind("form-pre-serialize", c);
b.bind("destroy.ckeditor", function() {
a(h.form).unbind("submit", c);
a(h.form).unbind("form-pre-serialize",
c)
})
}
e.on("destroy", function() {
b.removeData("ckeditorInstance")
});
/*
e.on("maximize", function (e) {
// console.log('---------------------------- MAXIMIZE ----------------------------');
// console.debug(e.data);
switch(parseInt(e.data)){
case(1)://Gehe in Fullscreen, SCHLIESSE Jquery ui Dialoge
console.log('CKEDITOR [maximize:true] jQuery adapter: schliesse ui-dialog');
$('.ui-dialog-content').dialog('close');
break;
case(2)://Gehe in Fullscreen, OFFNE Jquery ui Dialoge
console.log('CKEDITOR [maximize:false] jQuery adapter: öffne ui-dialog');
$('.ui-dialog-content').dialog('open');
break;
}
});
*/
b.removeData("_ckeditorInstanceLock");
b.trigger("instanceReady.ckeditor", [e]);
g && g.apply(e, [h]);
l.resolve()
} else setTimeout(arguments.callee, 100)
}, 0)
}, null, null, 9999)
}
});
var f = new a.Deferred;
this.promise = f.promise();
a.when.apply(this, k).then(function() {
f.resolve();
CKEDITOR.on("dialogDefinition", function (e) {
var dialogName = e.data.name;
var dialog = e.data.definition.dialog;
dialog.on('show', function () {
console.log('CKEDITOR [dialogdefinition:true] jQuery adapter: schliesse ui-dialog');
$('.ui-dialog-content').dialog('close');
});
dialog.on('hide', function () {
console.log('CKEDITOR [dialogdefinition:false] jQuery adapter: öffne ui-dialog');
$('.ui-dialog-content').dialog('open');
});
});
});
this.editor = this.eq(0).data("ckeditorInstance");
return this
}
});
CKEDITOR.config.jqueryOverrideVal && (a.fn.val = CKEDITOR.tools.override(a.fn.val, function(g) {
return function(d) {
if (arguments.length) {
var m =
this,
k = [],
f = this.each(function() {
var b = a(this),
c = b.data("ckeditorInstance");
if (b.is("textarea") && c) {
var f = new a.Deferred;
c.setData(d, function() {
f.resolve()
});
k.push(f.promise());
return !0
}
return g.call(b, d)
});
if (k.length) {
var b = new a.Deferred;
a.when.apply(this, k).done(function() {
b.resolveWith(m)
});
return b.promise()
}
return f
}
var f = a(this).eq(0),
c = f.data("ckeditorInstance");
return f.is("textarea") && c ? c.getData() : g.call(f)
}
}))
})(window.jQuery);
Also found this solution: https://forum.jquery.com/topic/can-t-edit-fields-of-ckeditor-in-jquery-ui-modal-dialog
Upvotes: 0
Reputation: 111
This will work fine
Check CKEditor intances than destroy it when dialog is closed. Enjoy your code
function DestryoCKEditorInstances(textarea_name)
{
if (CKEDITOR.instances[textarea_name])
{
CKEDITOR.instances[textarea_name].destroy();
}
}
$( "#add-task" ).dialog({
modal: true,
minHeight: 600,
minWidth: 600,
position: [0,28],
create: function (event) { $(event.target).parent().css('position', 'fixed');},
open: CKEDITOR.replace('textarea_name',{language: 'tr',height: 150,width: 550, allowedContent: true}),
close: function (){
DestryoCKEditorInstances('textarea_name');
form[ 0 ].reset();
},
buttons: {
"Add Task": function() {
Add();
form[ 0 ].reset();
$( this ).dialog( "close" );
},
"Keep Going To Add Task": function() {
Add();
form[ 0 ].reset();
},
Cancel: function() {
form[ 0 ].reset();
$( this ).dialog( "close" );
}
}
});
Upvotes: 2
Reputation: 1459
You need to instantiate the CKEDITOR on the open event of the dialog
open: CKEDITOR.replace('editor1', {
height: 145,
width: 500,
allowedContent: true,
}),
Then is will allow text. Something to do with the Iframe that CKEDITOR uses
Upvotes: 3
Reputation: 3214
I had a similar problem loading text into ckeditor while it was inside a jquery ui dialog. I had 2 instances of ckeditor and an ajax post to get the data so my workaround was:
(...)
success: function(data, textStatus, jqXHR) {
for (name in CKEDITOR.instances) {
CKEDITOR.instances[name].destroy()
}
$('#newForm').dialog('open');
$("#dialog").focus();
$('#txtDescription').ckeditor({ toolbar: 'Basic' });
$('#txtDescriptionFr').ckeditor({ toolbar: 'Basic' });
CKEDITOR.instances['txtDescription'].setData(data.Description.NameEn);
CKEDITOR.instances['txtDescriptionFr'].setData(data.Description.NameFr);
}
Upvotes: 0
Reputation: 51
I found a workaround at least. If I save the contents of the editor and destroy the instance before opening the dialog, and then recreate the editor instance after opening the dialog, it all works fine.
var editor = $('textarea').ckeditorGet();
editor.updateElement();
editor.destroy();
$('#childDialog').dialog( 'open' );
$('textarea').ckeditor( { toolbar: [] } );
Upvotes: 1