Skip to content

Instantly share code, notes, and snippets.

@Reinmar
Last active June 1, 2022 13:47
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Reinmar/b9df3f30a05786511a42 to your computer and use it in GitHub Desktop.
Save Reinmar/b9df3f30a05786511a42 to your computer and use it in GitHub Desktop.

CKEditor inside jQuery UI dialogs

This tip is compatible with jQuery UI 1.10.2+ and was tested with jQuery UI 1.11.2 and 1.10.4.

The are known compatibility issues when running CKEditor inside jQuery UI dialogs with the modal option enabled, such as: broken drop-downs and disabled inputs inside CKEditor dialogs. You can use the code below to fix these issues.

The code overrides jQuery UI dialog widget's _allowInteraction method in order to allow the focus to leave the jQuery UI's dialog so it can stay in CKEditor's dialogs and drop-down panels. It also fixes errors thrown when using CKEditor's magicline on IEs.

Execute this code after including jQuery UI's script and before executing $( '#dialog' ).dialog() function.

Note: You need to uncomment the second method when using this fix with jQuery UI 1.10.*.

$.widget( 'ui.dialog', $.ui.dialog, {
	_allowInteraction: function( event ) {
		if ( this._super( event ) ) {
			return true;
		}

		// Address interaction issues with general iframes with the dialog.
		// Fixes errors thrown in IE when clicking CKEditor magicline's "Insert paragraph here" button.
		if ( event.target.ownerDocument != this.document[ 0 ] ) {
			return true;
		}

		// Address interaction issues with dialog window.
		if ( $( event.target ).closest( '.cke_dialog' ).length ) {
			return true;
		}

		// Address interaction issues with iframe based drop downs in IE.
		if ( $( event.target ).closest( '.cke' ).length ) {
			return true;
		}
	},

	// Uncomment this code when using jQuery UI 1.10.*.
	// Addresses http://dev.ckeditor.com/ticket/10269
	// _moveToTop: function ( event, silent ) {
	//	if ( !event || !this.options.modal ) {
	//		this._super( event, silent );
	//	}
	// }
} );

More:

CKEditor inside Bootstrap modals

This tip is compatible with Bootstrap 3.0.0+ and was tested with Bootstrap 3.3.0.

The are known compatibility issues when running CKEditor inside Bootstrap modals, such as: broken drop-downs and disabled inputs inside CKEditor dialogs. You can use the code below to fix these issues.

The code overrides a Bootstrap's method in order to allow the focus to leave the Bootstrap's modal so it can stay in CKEditor's dialogs or drop-down panels (in IEs). The only changed part of the original method is the code between "CKEditor compatibility fix start/end" comments.

Execute this code after including Boostrap's script and before executing $( '#modal' ).modal() function.

$.fn.modal.Constructor.prototype.enforceFocus = function() {
	$( document )
		.off( 'focusin.bs.modal' ) // guard against infinite focus loop
		.on( 'focusin.bs.modal', $.proxy( function( e ) {
			if (
				this.$element[ 0 ] !== e.target && !this.$element.has( e.target ).length
				// CKEditor compatibility fix start.
				&& !$( e.target ).closest( '.cke_dialog, .cke' ).length
				// CKEditor compatibility fix end.
			) {
				this.$element.trigger( 'focus' );
			}
		}, this ) );
};

More:

@archonic
Copy link

In bootstrap 4.3.1 I just needed to change enforceFocus to _enforceFocus. So here's the working snippet:

$.fn.modal.Constructor.prototype._enforceFocus = function() {
  $(document).off('focusin.bs.modal').on('focusin.bs.modal', $.proxy((function(e) {
    if (this.$element[0] !== e.target && !this.$element.has(e.target).length && !$(e.target).closest('.cke_dialog, .cke').length) {
      this.$element.trigger('focus');
    }
  }), this));
};

@masterguru
Copy link

Thanks archonic! It works well with bootstrap 4.2.1. too!

@mh-firouzjah
Copy link

I used ajax to load data in modal, and I don't know where exactly I have to put this peace of code?

@japo32
Copy link

japo32 commented Nov 20, 2019

I kept getting this error when I used @archonic solution https://gist.github.com/Reinmar/b9df3f30a05786511a42#gistcomment-2897528

TypeError: this.$element is undefined

So I just added a check for that.

    $.fn.modal.Constructor.prototype._enforceFocus = function() {
      $(document).off('focusin.bs.modal').on('focusin.bs.modal', $.proxy((function(e) {
        if (typeof this.$element !== 'undefined' &&
          this.$element[0] !== e.target &&
          !this.$element.has(e.target).length &&
          !$(e.target).closest('.cke_dialog, .cke').length) {
          this.$element.trigger('focus');
        }
      }), this));
    };

I'm on 4.3.1 as well.

@japo32
Copy link

japo32 commented Nov 20, 2019

@mahdokhi you can place it in any js code that executes after loading bootstrap.js. It's a prototype level change so it doesn't matter if the modal loads data using ajax.

@WolflanFreitas
Copy link

In bootstrap 4.3.1 I just needed to change enforceFocus to _enforceFocus. So here's the working snippet:

$.fn.modal.Constructor.prototype._enforceFocus = function() {
  $(document).off('focusin.bs.modal').on('focusin.bs.modal', $.proxy((function(e) {
    if (this.$element[0] !== e.target && !this.$element.has(e.target).length && !$(e.target).closest('.cke_dialog, .cke').length) {
      this.$element.trigger('focus');
    }
  }), this));
};

Perfect solution! Thanks @archonic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment