cz4586
cz4586

Reputation: 51

CKEditor not working after opening jQuery UI Dialog

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

Answers (5)

Gehtdich Nichtsan
Gehtdich Nichtsan

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

Goragio Haddeler
Goragio Haddeler

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

pat capozzi
pat capozzi

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

Paulj
Paulj

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

cz4586
cz4586

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

Related Questions