Problem/Motivation

When using CKeditor in a jQuery UI dialog with the modal option set as TRUE, it is not possible to CKeditor native dialogs. The text fields within the modal dialog are not clickable.

Proposed resolution

Extend the dialog by using the jQuery UI native widget factory feature. By the way, jQuery UI itself uses exactly the same example for demonstration purposes of extending _allowInteraction( event ) method, see https://api.jqueryui.com/dialog/#method-_allowInteraction:

Modal dialogs do not allow users to interact with elements behind the dialog. This can be problematic for elements that are not children of the dialog, but are absolutely positioned to appear as though they are. The _allowInteraction() method determines whether the user should be allowed to interact with a given target element; therefore, it can be used to whitelist elements that are not children of the dialog but you want users to be able to use.

Remaining tasks

Review a patch

User interface changes

None

API changes

None

Data model changes

None

CommentFileSizeAuthor
#71 3065095-71-1.0.x.patch7.19 KBSerkanB
#64 interdiff-56-64.txt704 bytesTaran2L
#64 3065095-64-9.5.x.patch7.63 KBTaran2L
#62 3065095-56-9.5.x.patch7.38 KBTaran2L
#60 3065095-56-9.5.x.patch0 bytesTaran2L
#56 3065095-56.patch7.34 KBTaran2L
#55 3065095-55.patch7.32 KBTaran2L
#54 3065095-54.patch0 bytesTaran2L
#53 3065095-53-D10.patch7.29 KBTaran2L
#52 3065095-52-D10.patch7.22 KBTaran2L
#40 3065095-40.ckeditor-table-prop.patch6.65 KBGrayle
#37 Table modal patch successfully applied.png45.31 KBseeduardo
#35 Screenshot 2021-10-21 162931.png95.1 KBGrayle
#33 3065095-31.patch11.05 KBsaso.sotlar
#14 3065095-14--FAIL.patch3.88 KBjohnwebdev
Screenshot 2019-07-01_10-13-23-064.png75.26 KBPascalMortier

Issue fork drupal-3065095

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

PascalMortier created an issue. See original summary.

idebr’s picture

This seems to match the 'official' behavior on https://ckeditor.com/ckeditor-4/demo/#article where some cells are disabled. However, Seven does not display the 'disabled' styling.

PascalMortier’s picture

It has nothing to do with disabled cells. If I use it in a normal form everything is working. As soon as I use the editor in a modal form, the input fields for cell properties are not working.

cilefen’s picture

Is there anything in the browser console?

PascalMortier’s picture

No I can't see any error.
Select lists are working, but text fields doesn't.

olmanslm’s picture

I also could reproduce this issue, There is no console log errors. Also when we click the table icon in the CKeditor the auto focus is also missing, it should focus the first input in the modal.

Also I noticed that the CKeditor modals works correctly outside the layout builder.

olmanslm’s picture

Hello,

I was able to reproduce the error and come with a solution. The Error es caused by how the CKeditor modal element is added to the page. In order to make the two modals work together, one solution could be to append the CKeditor modal and its overlay inside the #layout-builder-modal

I extend the module functionality with the following fix:

(function ($) {

  let zIndex = 601;

  $(window).on({
    'dialog:aftercreate': function dialogAftercreate(event, dialog, $element, settings) {
      $element.dialog('widget').css('zIndex', zIndex);
      $element.dialog('widget').next('.ui-widget-overlay').css('zIndex', zIndex - 1);
      if ($element.first() && $element.first().attr('id') === 'layout-builder-modal') {
        $('#layout-builder-modal').on('click', '.cke_button.cke_button__table', () => {
            setTimeout(() => {
              let _$el = $('#layout-builder-modal').parent();
              let _$firstInput = $('.cke_reset_all.cke_1 .cke_dialog_ui_input_text input').first();
              _$el.append($('.cke_reset_all.cke_1'));
              _$el.append($('.cke_dialog_background_cover'));
              if(_$firstInput && typeof _$firstInput !== 'undefined'){
                _$firstInput.focus();
              }
            }, 200);
          }
        );
      }
      zIndex += 2;
    }
  });

})(jQuery);

Also, we can and a Drupal behavior by adding the following:

      $(window).on({
        'dialog:aftercreate': function dialogAftercreate(event, dialog, $element, settings) {
          if ($element.first() && $element.first().attr('id') === 'layout-builder-modal') {
            $('#layout-builder-modal').on('click', '.cke_button.cke_button__table', () => {
              setTimeout(() => {
                let _$el = $('#layout-builder-modal').parent();
                let _$firstInput = $('.cke_reset_all.cke_1 .cke_dialog_ui_input_text input').first();
                _$el.append($('.cke_reset_all.cke_1'));
                _$el.append($('.cke_dialog_background_cover'));
                if (_$firstInput && typeof _$firstInput !== 'undefined') {
                  _$firstInput.focus();
                }
              }, 200);
            });
          }
        }
      });

Hope this fix and guide you to implement the proper fix.

PascalMortier’s picture

Hi olmanslm,

Thank you a lot for your feedback.
However I was not working with the layout builder, I stripped your code and placed it in a js file of my custom module.
Now everything is working, thank you !

I only used this part in my module :

            //fix for ck editor table function (not clickable properties)
            $('#my-div').on('click', '.cke_button.cke_button__table', () => {
                setTimeout(() => {
                    let _$el = $('#my-div').parent();
                    let _$firstInput = $('.cke_reset_all.cke_1 .cke_dialog_ui_input_text input').first();
                    _$el.append($('.cke_reset_all.cke_1'));
                    _$el.append($('.cke_dialog_background_cover'));
                    if (_$firstInput && typeof _$firstInput !== 'undefined') {
                        _$firstInput.focus();
                        }
                }, 200);
            });

In this example you have to replace '#my-div' with the div that is used as the parent modal.

olmanslm’s picture

Hello PascalMortier,

Glad that it helped, I also noticed some styling issue and this is a update to that code:

$(window).on({
        'dialog:aftercreate': function dialogAftercreate(event, dialog, $element, settings) {
          if ($element.first() && $element.first().attr('id') === 'layout-builder-modal') {
            $('#layout-builder-modal').on('click', '.cke_button.cke_button__table', function () {
              var _$el = $('#layout-builder-modal').parent();
              var _$firstInput = $('.cke_reset_all.cke_1 .cke_dialog_ui_input_text input').first();
              $('.cke_reset_all.cke_1').hide();
              setTimeout(function () {
                var cke = {
                  $el: $('.cke_reset_all.cke_1'),
                  $table: $('.cke_reset_all.cke_1>table'),
                  $bg: $('.cke_dialog_background_cover'),
                };
                cke.$table.removeAttr('style').css({
                  'z-index': '10010',
                  'position': 'absolute',
                  'top': 'calc(50%/2)',
                  'left': 'calc(50%/2)',
                });
                _$el.append(cke.$el).append(cke.$bg);
                if (_$firstInput && typeof _$firstInput !== 'undefined') {
                  _$firstInput.focus();
                }
                $('.cke_reset_all.cke_1').show();
              }, 200);
            });
          }
        }
      });
Wim Leers’s picture

Title: CKeditor table properties not clickable » CKEditor table properties not clickable due to interaction with jQuery UI dialogs
Issue tags: +undefined

We now can write tests that can reproduce even complex JS or element reachability problems like this one. So let's write a failing test!

johnwebdev’s picture

To reproduce without Layout Builder Modal module you could do something like:

<a href="/node/add/page" class="use-ajax" data-dialog-options='{"width": 500,"modal": true}' data-dialog-type="dialog">Link 1 without class</a>

One thing more; it is the jQuery UI dialog modal option that makes the table not clickable.

johnwebdev’s picture

Issue summary: View changes
johnwebdev’s picture

I intend to work on the failing test today :)

johnwebdev’s picture

Status: Active » Needs review
FileSize
3.88 KB

Failing test

Status: Needs review » Needs work

The last submitted patch, 14: 3065095-14--FAIL.patch, failed testing. View results

SoulReceiver’s picture

The fix provided in #9 works great for when you add a new table, but if you want to edit an existing table and get the table properties by right-clicking then this is still broken.

knaffles’s picture

I tried working with #9 but wasn't able to adapt it to work when there are multiple toolbar buttons that launch a modal.

I added the snippet below into a library in a custom module, with a dependency on core/jquery.ui.dialog. This took care of the issue for me, and also works for other buttons that launch a modal, such as the anchor button, which had the same issue. That said, I'm not sure where in core this would belong as a patch.

(function ($, Drupal) {

  orig_allowInteraction = $.ui.dialog.prototype._allowInteraction;
  $.ui.dialog.prototype._allowInteraction = function(event) {
     if ($(event.target).closest('.cke_dialog').length) {
        return true;
     }
     return orig_allowInteraction.apply(this, arguments);
  };

})(jQuery, Drupal);

This snippet comes from this comment on stack overflow: https://stackoverflow.com/a/28086465

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.9 was released on November 6 and is the final full bugfix release for the Drupal 8.7.x series. Drupal 8.7.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.8.0 on December 4, 2019. (Drupal 8.8.0-beta1 is available for testing.)

Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

pcorbett’s picture

#17 works well by implementing a custom module and library with the referenced JS.

Webbeh’s picture

Issue summary: View changes
Webbeh’s picture

One of my colleagues was able to mediate this issue using #17, thank you for sharing! They noted that:

...it doesn't fix the focusing issue (e.g., if you open the Link tool or Image tool, focus jumps to the first field of the block modal instead of the first field of the Link or Image modal).

I wanted to highlight a consideration of how to take this fix snippet JS and create a patch out of it as our next steps?

That said, I'm not sure where in core this would belong as a patch.

komlenic’s picture

I encountered another instance of this issue when using CKEditor Media Embed with Layout Builder Modal.

The solution in #17 resolves this problem for me.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

AaronChristian’s picture

Confirming that #17 works for me as well.

Make sure you don't forget to add the dependency for core/jquery.ui.dialog like mentioned above the original snippet.

Thanks!

Luke.Leber’s picture

Confirmed that #17 works as advertised on Drupal 8.9.9!

malmeida287’s picture

Confirming that #17 works for me as well.

Thanks @knaffes !

YesCT’s picture

Thanks so much for this issue, and the snippet in #17.

I wasn't sure what todo with it... so I'll share the diff I ended up with, in case it helps others see a bigger picture too.

Caution, this is not a diff that can be "applied" to anyone's specific code base, but should indicate one example of how to get the snippet into code.

diff --git a/web/themes/organization/org_theme/org_theme.info.yml b/web/themes/organization/org_theme/org_theme.info.yml
index 47968d8b..4abf18ea 100644
--- a/web/themes/organization/org_theme/org_theme.info.yml
+++ b/web/themes/organization/org_theme/org_theme.info.yml
@@ -7,6 +7,11 @@ base theme: iastate_base_theme
 libraries:
   - org_theme/global-styling
   - org_theme/global-js
+libraries-extend:
+  layout_builder/drupal.layout_builder:
+    - org_theme/layout_builder
 ckeditor_stylesheets:
   - css/style.css
 # Regions from the base theme must be re-defined
diff --git a/web/themes/organization/org_theme/org_theme.libraries.yml b/web/themes/organization/org_theme/org_theme.libraries.yml
index 0eace495..65d5d77d 100644
--- a/web/themes/organization/org_theme/org_theme.libraries.yml
+++ b/web/themes/organization/org_theme/org_theme.libraries.yml
@@ -20,3 +20,7 @@ global-js:
   dependencies:
     - core/jquery
     - core/drupal
+
+layout_builder:
+  js:
+    js/org-layout-builder.js: {}
diff --git a/web/themes/organization/org_theme/js/org-layout-builder.js b/web/themes/organization/org_theme/js/org-layout-builder.js
new file mode 100644
index 00000000..adf068c0
--- /dev/null
+++ b/web/themes/organization/org_theme/js/org-layout-builder.js
@@ -0,0 +1,21 @@
+/**
+ * @file
+ * jQuery for various fixes for layout_builder.
+ */
+
+/**
+ * Fix issue where anchor_link modal cannot grab focus when using layout_builder.
+ *
+ * @see https://www.drupal.org/project/drupal/issues/3065095#comment-13311079
+ */
+(function ($, Drupal) {
+
+  orig_allowInteraction = $.ui.dialog.prototype._allowInteraction;
+  $.ui.dialog.prototype._allowInteraction = function(event) {
+    if ($(event.target).closest('.cke_dialog').length) {
+      return true;
+    }
+    return orig_allowInteraction.apply(this, arguments);
+  };
+
+})(jQuery, Drupal);

---

also, I'm making this related to https://www.drupal.org/project/drupal/issues/3113649 since that issue is re-writing the js core uses. So depending on how that works out, the "fix" here might not be needed eventually.... maybe.

I made a comment on that issue too, so they are aware of this test case if they want to include this in their testing while working on re-writing core.

alexharries’s picture

Thank you, @YesCT - your diff was really helpful.

Edit: unfortunately, using the libraries-extend option doesn't work with Entity Reference with Layout, which we're using for Paragraphs.

Instead, we had to add the function either into an existing Js file in one of our existing custom modules, or as a new Js file in a new or existing module.

We went with the first option, which gave us this:

redactived8platform_dragdrop/js/redactived8platform-dragdrop-layout-builder-fix.js:

/**
 * @file
 * redactived8platform-dragdrop-layout-builder-fix.js
 *
 * jQuery for various fixes for layout_builder.
 */

/**
 * Fix issue: anchor_link modal cannot grab focus when using layout_builder.
 *
 * @see https://www.drupal.org/project/drupal/issues/3065095#comment-13311079
 */

(function ($, Drupal) {

  let orig_allowInteraction = $.ui.dialog.prototype._allowInteraction;
  $.ui.dialog.prototype._allowInteraction = function (event) {
    if ($(event.target).closest('.cke_dialog').length) {
      return true;
    }

    return orig_allowInteraction.apply(this, arguments);
  };

})(jQuery, Drupal);

redactived8platform_dragdrop/redactived8platform_dragdrop.libraries.yml

redactived8platform-dragdrop:
  version: 1.x
  js:
    js/redactived8platform-dragdrop-layout-builder-fix.js: {}
  dependencies:
    - core/jquery.ui.dialog

... just in case this detail helps the next person dealing with this shiny-new DrupalWTF... ¯\_(ツ)_/¯

Thanks - Al :)

ndf’s picture

Version: 8.9.x-dev » 9.2.x-dev

ndf’s picture

This merge request has:
- the existing automated test from johnwebdev comment #14
- the existing snippet from #17 that copies the interaction settings to the modal
- added code the snippet runs when the dialog opens. My goal was that a custom new library is not needed.

ndf’s picture

Status: Needs work » Needs review
Issue tags: -undefined +jQuery UI

Now many tests fail due to the "core/jquery.ui.dialog" dependency. Not sure how to proceed with this at the moment. Maybe move this issue to https://www.drupal.org/project/jquery_ui_dialog? And then let affected contrib modules set a dependency to that module?

The "core/jquery.ui.dialog" asset library is deprecated in drupal:9.2.0 and is removed from drupal:10.0.0. See https://www.drupal.org/node/3067969

Still putting this to needs review because I would like to know if this patch fixes the issue in various scenario's.

saso.sotlar’s picture

Uploaded (locked) version of a patch from latest MR (comment #31).

Patch applies successfully on 9.2.6.

Status: Needs review » Needs work

The last submitted patch, 33: 3065095-31.patch, failed testing. View results

Grayle’s picture

Latest patch causes a lot of console errors when just clicking anything in any layout builder modal.

error

Poindexterous’s picture

I'm getting the same errors as @grayle with patch #31 running drupal core 9.2.7, I also ran across a "permission denied" error when attempting to insert a media item into a field with the layout builder modal. Removing the patch in this issue restored access to insert the media image into the field. The error I received was

Path: /admin/content/media-widget/image?directory=401&name=&sort_by=created. Drupal\Core\Http\Exception\CacheableAccessDeniedHttpException: The opener ID parameter is required and must be a string. in Drupal\Core\Routing\AccessAwareRouter->checkAccess() (line 117 of /app/docroot/core/lib/Drupal/Core/Routing/AccessAwareRouter.php).

seeduardo’s picture

Just confirming successful application of the patch in #33 on Drupal 9.2.8. Table modal patch successfully applied

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.1.10 (June 4, 2021) and Drupal 9.2.10 (November 24, 2021) were the last bugfix releases of those minor version series. Drupal 9 bug reports should be targeted for the 9.3.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

chrisgross’s picture

This patch applies to Drupal 9.3.4, but does not appear to do anything. Both before and after applying the patch, I can change table row and column properties if I select the table and use the Table button in the editor. However, if I access this via the Table Properties right-click menu, those properties are not editable.

Edit: Okay, so it looks like this patch does fix the issue where modal dialogs cannot be focused at all. So is this unrelated to being not able to change the number of rows and columns after the table is created? I guess we couldn't do this in 7 either, so if that's the case then I can confirm that this patch works.

Grayle’s picture

Locked patch based on last MR status. All I did was revert the linter removing "arguments", that's what was causing all the console errors.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functi...

Also used plain diff instead of the email formatted diff the previous patch was based on. You can get the plain diff version using the download button on the MR's status page.

immaculatexavier’s picture

Status: Needs review » Needs work

#40 Custom Commands Failed. Changing the status to Need Work

Wim Leers’s picture

Huh, I wonder if #3274937: Get CKEditor 5 to work in (modal) dialogs would need to be applied to CKEditor 4 too 🤔

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Taran2L made their first commit to this issue’s fork.

Taran2L’s picture

Version: 9.4.x-dev » 9.5.x-dev
Status: Needs work » Needs review

Taran2L’s picture

Taran2L’s picture

Title: CKEditor table properties not clickable due to interaction with jQuery UI dialogs » CKEditor native dialogs not clickable inside of jQuery UI dialogs
Issue summary: View changes
vlad.dancer’s picture

Status: Needs review » Reviewed & tested by the community

Thanks @Taran@L. Tested MR863, works as expected.

Taran2L’s picture

@vlad.dancer, thanks for the RTBC, but the last MR does not pass the tests.

Discussed the matter with @nod_ in Slack, thus the new patch that mimics the CKE5 fix from #3274937: Get CKEditor 5 to work in (modal) dialogs and #3301631: Regression with CKEditor 35.0.1 and modal dialogs

Taran2L’s picture

FileSize
7.29 KB
Taran2L’s picture

FileSize
0 bytes
Taran2L’s picture

FileSize
7.32 KB
Taran2L’s picture

nod_’s picture

probably should be a 9.x patch since ckeditor will be removed in 10.x.

Taran2L’s picture

@nod_, it won't be removed in 10.0.x, CKE4 will be supported till the end of 2023 (afaik), so it will be (probably) removed in 10.1 or even in 10.2 (or even 10.3)

nod_’s picture

It'll live in contrib but the plan is to remove it from core in 10.0.0, see #3304326: Deprecate CKEditor 4 module in 9.5

Taran2L’s picture

nod_’s picture

(that's because if it makes it in D10, we can't remove it until D11 because of our support/BC rules. And because CKE4 will be out of support before the end of the D10 support it would implicitly means that we'll need to support CKE4 over the life of D10, which no one wants to do. Major version are the only time we can remove existing modules from core)

Taran2L’s picture

Version: 10.0.x-dev » 9.5.x-dev
FileSize
7.38 KB

Status: Needs review » Needs work

The last submitted patch, 62: 3065095-56-9.5.x.patch, failed testing. View results

Taran2L’s picture

Status: Needs work » Needs review
FileSize
7.63 KB
704 bytes

Status: Needs review » Needs work

The last submitted patch, 64: 3065095-64-9.5.x.patch, failed testing. View results

Taran2L’s picture

Status: Needs work » Needs review
quietone’s picture

Project: Drupal core » CKEditor 4 - WYSIWYG HTML editor
Version: 9.5.x-dev » 1.0.x-dev
Component: ckeditor.module » Code

CKEditor has been removed from core, CKEditor 4 is removed from Drupal Core in 10.0.0

carolpettirossi’s picture

I tested patch #56 and it worked for me on Drupal 9.4

Rajeshreeputra’s picture

patch #56 works with Drupal 9.4

ari.saves’s picture

The patch in #56 appears to have broken for 9.4.7; it still applies cleanly, but doesn't appear to work. I ended up using the one in #40 after upgrading.

SerkanB’s picture

I'm using Drupal 9.4.8, CKEditor 4 (contrib) 1.0.1 and bunch of paragraphs and layout-builder stuff, where the modal-overlay-stuff comes from.

I've taken the patch in #64 and changed it a bit until it applied and worked correctly for me.
I didn't touch the tests though. For me the changes seem to work fine.

I based the patch on the branch 1.0.x, but it works just fine for the released 1.0.1.

mark_fullmer’s picture

For sites using this patch to fix this issue with the jQuery UI dialog, an alternative to consider is switching to the very similar contributed module, https://drupal.org/project/layout_builder_iframe_modal.

I verified that this issue is not present when using that module.

TerraCoders’s picture

Patch in #71 looks to be working for Drupal 9.5.5 and CKE4 1.0.1 -- resolving this issue in Layout Builder when using CKE Anchor Link plugin.

alexortega_98’s picture

Status: Needs review » Reviewed & tested by the community

#71 works, tested in Drupal 9.5.8 and Drupal 10.0.8.

cbanman’s picture

#71 works with Drupal 10.2.3