13
votes

I'm trying to create a Bootstrap modal which contains an instance of CKEditor, but there are a lot of problems...

So basically the fields are left unenabled, they don't look like, but I can't interact with them. Does anybody have a solution to this strange behavior?

9
I'm having a similar problem - the toolbar buttons work but the text fields within them are uneditable! Did you ever find a fix for this? I've seen some z-index hacks but none seem to work.WheretheresaWill

9 Answers

27
votes

FWIW, I couldn't get Peter's solution to work, but the following worked for me, and still keeps the hack in a separate file so you don't have to edit any Bootstrap source files:

// bootstrap-ckeditor-modal-fix.js
// hack to fix ckeditor/bootstrap compatiability bug when ckeditor appears in a bootstrap modal dialog
//
// Include this AFTER both bootstrap and ckeditor are loaded.

$.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 
    && !$(e.target.parentNode).hasClass('cke_dialog_ui_input_select') 
    && !$(e.target.parentNode).hasClass('cke_dialog_ui_input_text')) {
      modal_this.$element.focus()
    }
  })
};
13
votes

I just removed the tabindex attribute from the modal container, that seems to fix this issue for me.

This was suggested by fat here: https://github.com/twbs/bootstrap/issues/6996

5
votes

If all the above solutions will not work for you, Please try this:

   $('#myModal').on('shown.bs.modal', function() {
        $(document).off('focusin.modal');
    });

It worked for me instantly. Here is the source: tobiv's answer - github

3
votes

Instead of messing with the Bootstrap source, I re-attached the focus event handler.

I looked in the Bootstrap Modal (unminified) code to find where the event handler is being defined, under Modal.enforceFocus():

var that = this
$(document).on('focusin.modal', function (e) {
  if (that.$element[0] !== e.target && !that.$element.has(e.target).length) {
    that.$element.focus()
  }
})

I then added a method to CKEditor that ammended this function. You can put this wherever; maybe in a file just for CKEditor overrides.

CKEDITOR.bootstrapModalFix = function (modal, $) {
  modal.on('shown', function () {
    var that = $(this).data('modal');
    $(document)
      .off('focusin.modal')
      .on('focusin.modal', function (e) {
        // Add this line
        if( e.target.className && e.target.className.indexOf('cke_') == 0 ) return;

        // Original
        if (that.$element[0] !== e.target && !that.$element.has(e.target).length) {
          that.$element.focus()
        }
      });
  });
};

So now, if I know I am going to load a CKEditor in a Bootstrap modal, I call this method, assuming jQuery is $:

CKEDITOR.bootstrapModalFix( $('#myModal'), $ )
1
votes

Hey I was having these problems. I found this ticket https://github.com/twitter/bootstrap/issues/6996 which seems to have fixed the issue of the inputs being unselectable for me. I extended the change in this ticket to:

if (that.$element[0] !== e.target && !that.$element.has(e.target).length && !$(e.target.parentNode).hasClass('cke_dialog_ui_input_select') && !$(e.target.parentNode).hasClass('cke_dialog_ui_input_text')){

This allows the selects to be usuable as well as the inputs, although repeating the selector is a bit janky it does fix the bugs. Hope this helps you.

1
votes

The z-index of the bootstrap modal is higher than that of ckeditor panels. So an alternative solution I found was to increase the z-index for ckeditor. Add the following line to ckeditor config.js

// app/assets/javascripts/ckeditor/config.js
config.baseFloatZIndex = 1E5;
1
votes

I'm using CKEditor in the React-Boostrap Modal. And I faced the focus issue in the Wiris Mathtype editor. I tried this below two methods that solved my problem.

Paste this below script when the Modal component loads

document.getElementsByClassName('modal')[0].removeAttribute('tabindex')

or

Add this attribute to the Modal Component

enforceFocus={false}
0
votes

Working example is here: http://jsfiddle.net/pvkovalev/4PACy/

        $.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()
                }
            })
        };
0
votes

Bootstrap changed focusin.modal to shown.bs.modal

 $.fn.modal.Constructor.prototype.enforceFocus = function() {
  modal_this = this
  $(document).on('shown.bs.modal', function (e) {
    if (modal_this.$element[0] !== e.target && !modal_this.$element.has(e.target).length 
    && !$(e.target.parentNode).hasClass('cke_dialog_ui_input_select') 
    && !$(e.target.parentNode).hasClass('cke_dialog_ui_input_text')) {
      modal_this.$element.focus()
    }
  })
};

This is working for me.