6

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?

Community
  • 1
  • 1
chemitaxis
  • 13,889
  • 17
  • 74
  • 125
  • What isn't working? I could edit the Modal title and the body no problem. – Rob Quincey Sep 03 '14 at 13:09
  • Mmmm i can't do it using chrome and windows 8.1 – chemitaxis Sep 03 '14 at 13:21
  • 1
    Hmm,you're right, in my version of Chrome it doesn't work, but it did work fine on Firefox (22 on WinXP, yes you heard right, XP). I do get this error in the Chrome console `The editor instance "myModalLabel" is already attached to the provided element. ` – Rob Quincey Sep 04 '14 at 08:01
  • There is a common problem. In modal there is a problem with z axis css – Kshitiz Sep 18 '14 at 07:28

3 Answers3

4

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);
}
George G
  • 7,443
  • 12
  • 45
  • 59
3

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/

Irvin Dominin
  • 30,819
  • 9
  • 77
  • 111
  • why the instance have to be destroyed? In my example it works without it, performance is also important I think – George G Sep 11 '14 at 11:56
  • @GeorgeGarchagudashvili this will allow the code to work with newly created/added element too and with broken instances – Irvin Dominin Sep 11 '14 at 12:02
  • Ok, I prefer not destroy the element, regards. – chemitaxis Sep 18 '14 at 07:48
  • @chemitaxis Doh, I missed the bounty :-( – Irvin Dominin Oct 17 '14 at 08:39
  • 2
    C'mon think a bit, you could easily modify `ckCreate` function in my case, I've had the version for destroying instances but removed because it was working without it, anyway I've updated my answer, nothing magic here, I made it easier for anyone to understand how it works :p, @IrvinDominin you did not miss anything – George G Oct 17 '14 at 08:54
  • Also my solution still would stay performant than this one, because it work on each instance individually not looping over and over – George G Oct 17 '14 at 08:56
  • Ok, I will test again, and I will tell you something... Just wait five minutes, regards! – chemitaxis Oct 17 '14 at 10:39
  • Hi! @GeorgeGarchagudashvili I don't knwo why it's not working... I'm thinking a bit... ;) – chemitaxis Oct 17 '14 at 10:43
  • nice if you achieved what works for you, but the case depends, so if you show why you stucked again I'd be able to help farther, anyway doing it yourself would be better ;) – George G Oct 17 '14 at 11:33
1

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);

    }

}
chemitaxis
  • 13,889
  • 17
  • 74
  • 125