Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CKEditor inline in modal bootstrap window

I need to use CKEditor inline inside a modal bootstrap, but it's not working...

I have read this post: How to use CKEditor in a Bootstrap Modal?

But it's different to me, beacuse I'm using the inline, and I need just apply CKEditor to some fields (I have other ones using contenteditable property).

JS CODE:

CKEDITOR.disableAutoInline = true;
CKEDITOR.inline('myModalLabel');
CKEDITOR.inline('bodyModal');

$.fn.modal.Constructor.prototype.enforceFocus = function () {
    modal_this = this
    $(document).on('focusin.modal', function (e) {
        if (modal_this.$element[0] !== e.target && !modal_this.$element.has(e.target).length
        // add whatever conditions you need here:
        &&
        !$(e.target.parentNode).hasClass('cke_dialog_ui_input_select') && !$(e.target.parentNode).hasClass('cke_dialog_ui_input_text')) {
            modal_this.$element.focus()
        }
    })
};

HTML CODE

<button type="button" data-toggle="modal" data-target="#modalAddBrand">Launch modal</button>

<div class="modal fade" id="modalAddBrand" tabindex="-1" role="dialog" aria-labelledby="modalAddBrandLabel" aria-hidden="true">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                 <h4 class="modal-title" id="modalAddBrandLabel">add</h4>

            </div>
            <div class="modal-body">
                <form>
                    <textarea name="editor1" id="editor1" rows="10" cols="80">This is my textarea to be replaced with CKEditor.</textarea>
                </form>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                <button id="AddBrandButton" type="button" class="btn btn-primary">Save</button>
            </div>
        </div>
    </div>
</div>

JSFiddle:

JSFiddle Example

Can anybody help me please?

like image 332
chemitaxis Avatar asked Sep 03 '14 08:09

chemitaxis


3 Answers

The problem is that when you init CKEDITOR instance, that time target is hidden, so if you instantiate editor after target is shown it will wok:

So you simply put:

CKEDITOR.disableAutoInline = true;

$('#myModal').on('shown.bs.modal', function () {
   CKEDITOR.inline('myModalLabel');
   CKEDITOR.inline('bodyModal');
});

But after closing and reopening the modal you may get error:

Uncaught The editor instance "myModalLabel" is already attached to the provided element

Update:

For this we can have function:

function ckCreate(name)
{
    if(CKEDITOR.instances[name] === undefined) 
    {
        CKEDITOR.inline(name);
    }
}

only create instance if it does not exist;

Finally your code would be:

CKEDITOR.disableAutoInline = true;

$('#myModal').on('shown.bs.modal', function () {
   ckCreate('myModalLabel');
   ckCreate('bodyModal');
});

Final Fiddle: http://jsfiddle.net/0vLs3fku/4/

Update: in need of destroying instances

function ckCreate(name)
{
    if (CKEDITOR.instances[name]) 
    {
        CKEDITOR.instances[name].destroy();
    }

    CKEDITOR.inline(name);
}
like image 78
George Garchagudashvili Avatar answered Nov 12 '22 09:11

George Garchagudashvili


Seems to be a known bug affecting webkit/blink browsers. The reason why is that when an element is hidden the attribute contenteditable is removed and in this case the CKEDITOR instance must be destroyed and recreated the contenteditable attribute must be set to true.

For this reason you can set the attribute again when the dialog is showed using shown.bs.modal event.

You have to get all ex contenteditable elements children of the opened dialog.

Code:

$('#myModal').on('shown.bs.modal', function (e) {
    $(this).find("*[contenteditable='false']").each(function () {
        var name;
        for (name in CKEDITOR.instances) {
            var instance = CKEDITOR.instances[name];
            if (this && this == instance.element.$) {
                instance.destroy(true);
            }
        }
        $(this).attr('contenteditable', true);
        CKEDITOR.inline(this);
    })
});

Demo: http://jsfiddle.net/IrvinDominin/q5zxn3yf/

like image 29
Irvin Dominin Avatar answered Nov 12 '22 09:11

Irvin Dominin


Ok, after all, I did a mix of the two answers... and it's working now... What do you think?

$(document).ready(function(e) {
    CKEDITOR.disableAutoInline = true;
    CKEDITOR.inline('myModalLabel');
    CKEDITOR.inline('bodyModal');


    $('#myModal').on('shown.bs.modal', function () {
        ckCreate('myModalLabel');
        ckCreate('bodyModal');
    });
});

function ckCreate(name) {
    if (CKEDITOR.instances[name]) {

        var instance = CKEDITOR.instances[name];
        if (instance.element.$) {
            instance.destroy(true);
        }

        $('#' + name).attr('contenteditable', true);
        CKEDITOR.inline(name);

    }

}
like image 1
chemitaxis Avatar answered Nov 12 '22 10:11

chemitaxis