I have encountered a minor yet annoying bug in ctools modal.

When the modal window is visible browser keyboard shortcuts only work if an input element inside the modal window is in focus.

The reason is that keypress/keydown events gets targeted at the body element when no other element is in focus, but the modal event handler filters out any event that doesn't have a target inside the modal content div.

I have attached a patch as an attempt to solve this. In the patch i have tried to check if the target is body or the modal content div itself, and allow those events.

If the target is neither body, modal content div or inside the modal content div, the focus is moved to the modal content div. (using jquery's .focus() which seems to work better).

I'm hoping some of you, who are more experienced with ctools modal and the javascript event system will take a look at this, see if it's useful, or if more work is needed.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

prinds’s picture

Status: Needs work » Needs review

maybe a change of status will create some response..

Status: Needs review » Needs work

The last submitted patch, modal.js-allow-keyboard-shortcuts.patch, failed testing.

prinds’s picture

ha.. wonderful, an automated response.. looks like i need to learn a thing or two about patches..

prinds’s picture

Status: Needs work » Needs review
FileSize
773 bytes

trying again..

jerrylow’s picture

Seems like the new updates to Chrome made this a none issue but even with the new Safari the issue still persists. I've updated the patch in terms of the lines where it applies.

joelpittet’s picture

Priority: Minor » Normal
Status: Needs review » Needs work

Thanks for pointing me at this patch and fixing it so I can use cmd+f to find things in modal windows (panels add content specifically)!

  1. +++ b/js/modal.js
    @@ -421,12 +421,14 @@
    +      if( $(target).is('#modalContent,body') || $(target).filter('*:visible').parents('#modalContent').size()){
    

    $.size() is deprecated as of jquery 1.8 so might as well change that to length() here maybe?
    @see http://api.jquery.com/size/

    And there is some minor but odd coding standards spacing before and after the opening if parenthesis and need a space between #modalContent,body

  2. +++ b/js/modal.js
    @@ -421,12 +421,14 @@
    -      return false;
    ...
    +      event.preventDefault();
    

    I think these lines helped fix the problem thanks:)

jerrylow’s picture

@joelpittet - Good catches. There're more .size and a few more deprecated functions in there. I'll do some testing with some of the functions with 1.5 and 1.7+ and do another update/issue.

joelpittet’s picture

Status: Needs work » Reviewed & tested by the community
FileSize
602 bytes
2.12 KB

Yeah those other size() calls should be another issue separate from this, just thought in context this should be fixed so thanks for that. It could be a follow-up issue to this one.

Thanks @jerrylow, attached is some very minor whitespace and coding standards changes to #7

japerry’s picture

Status: Reviewed & tested by the community » Fixed

Thanks Joel, looks good. Committed.

  • japerry committed cbebf96 on 7.x-1.x authored by joelpittet
    Issue #1823834 by prinds, jerrylow, joelpittet: Modal windows disable...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

jlafu’s picture

Hi, I'm re-opening this issue after finding an error when updating my site to ctools 7.x-1.6 (debugging that error led to this issue).

I have:

  1. A content type with an Image field and Media browser as its widget.
  2. This field is translatable with Entity translation, and its translation is syncronized.
  3. (The "Image" file type is also translatable with Entity translation, with translatable fields alt and title)

When I add/edit a translation of this content type, and from within that translation I add a translation of the Image field, I can't type anymore in the input fields of this content type.
Ok, I'm trying to explain it step by step:

  1. Edit a node of this content type
  2. Add/edit a translation
  3. Edit an image (modal window)
  4. Add a translation of the image (from the image modal window, this opens a new modal window for the translation)
  5. Close the image translation window (which takes you back to the modal editing of the node)
  6. Now, I can't type anymore in the input fields of this content type (such as the title).
  7. If I save the node ore close the edit window and reopen it, everything goes back to normal

I've realized that this is solved by doing this:

diff --git a/sites/all/modules/ctools/js/modal.js b/sites/all/modules/ctools/js/modal.js
index 37908cf..b309521 100644
--- a/sites/all/modules/ctools/js/modal.js
+++ b/sites/all/modules/ctools/js/modal.js
@@ -428,7 +428,7 @@
         return true;
       }
       else {
-        $('#modalContent').focus();
+        if ( $('#modalContent')) $('#modalContent').get(0).focus();
       }
 
       event.preventDefault();

Which is going back to the previous version of that line, as in ctools 7.x-1.5. Since I don't understand that change, I'm posting here my problem and how I've solved it in my project to ask you experts if you think this is an issue and how it should be treated. If it is, I'd be glad to solve it.

The core/modules versions I'm using are:

Drupal 7.34
ctools 7.x-1.6
File entity 7.x-2.0-beta1
Media7.x-2.0-alpha4
Entity Translation 7.x-1.0-beta4

Thank you very much for your help.

joelpittet’s picture

Status: Closed (fixed) » Needs review
FileSize
293 bytes

@jlafu that may be a good catch:

if ( $('#modalContent')) $('#modalContent').get(0).focus();

Should really be:

if ($('#modalContent').length) {
  $('#modalContent').focus();
}

For coding standards and all.

Here's a patch, try this out and let me know.

We may need to open a new issue for this as this one is closed. (up to the maintainers)

jlafu’s picture

Thanks a lot @joelpittet

I have tried your patch, but it does not work for my case. The only thing that works for me is (better coded now):

diff --git a/js/modal.js b/js/modal.js
index 37908cf..16940bd 100644
--- a/js/modal.js
+++ b/js/modal.js
@@ -427,8 +427,8 @@
         // of #modalContent.
         return true;
       }
-      else {
-        $('#modalContent').focus();
+      else if ($('#modalContent')) {
+        $('#modalContent').get(0).focus();
       }
 
       event.preventDefault();

(I don't post it as a patch since I don't understand how I am altering the original code).

The funny thing is that I have tested that any of the two changes in your patch (the check on $('#modalContent').length and the use of $('#modalContent').focus() instead of $('#modalContent').get(0).focus() ) break my configuration.

I am assuming that it is caused by the ctools modal opening another ctools modal and then coming back directly to the edit node page sequence. But I have no Idea of what is getting lost in the path...

Thank you very much for your help and tell me if I can provide some more information about this.

joelpittet’s picture

So that sounds like it may be a bigger problem then... get(0) is getting the DOM element of the first instance of that, and calling it's focus() method.

The problems with that, it assumes there is more than one, but there can only be one ID in valid HTML. #modalContent

The jQuery.focus and DOM focus method should trigger the same. Except for invisible elements which jQuery makes notes to in their docs. @see http://api.jquery.com/focus/

I have some help on how to contribute to core: http://pittet.ca/drupal/sprint/patch
But more useful is having a look at How to create a patch with Git: https://www.drupal.org/node/707484

I am assuming that it is caused by the ctools modal opening another ctools modal and then coming back directly to the edit node page sequence. But I have no Idea of what is getting lost in the path...

I think you are right here. Which may be why the .get(0) is working for you because it's setting focus on the first one it finds in the DOM. Where as the other one sets focus on all of the IDs it finds(even though there should only be one ... highlander).

The assumption that there is only one ctools modal on the page made by the #ID causes this craziness.
Maybe we can document this line as well and revert as a way forward?

jlafu’s picture

Hi, if documenting and reverting sounds ok to you, I think it can be the way to go, since we are'nt breaking anything or unrolling funcionality, we are just undoing some coding standards to avoid a bigger problem.
I think that if we document it and open a related issue with all the information of the "big problem" we are good.

Do you agree?

joelpittet’s picture

I agree, think that may be the best approach, undoing that part of the code change does not effect this issue with the keyboard shortcuts disabled.

Chris Matthews’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll

The 4 year old patch in #13 to modal.js does not apply to the latest ctools 7.x-1.x-dev and if still applicable needs to be re-rolled.

Checking patch js/modal.js...
error: while searching for:
        // of #modalContent.
        return true;
      }
      else {
        $('#modalContent').focus();
      }

error: patch failed: js/modal.js:427
error: js/modal.js: patch does not apply