Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#10099 adds keyboard handling to close confirm_modal on ESC #10455

Merged

Conversation

dpenny52
Copy link
Contributor

Closes #10099 by adding keyDown handling to document.body while the ConfirmModal is open, looking for ESC keyDown events (keyCode === 27) and calling the onCancel() method of the ConfirmModal when they are detected.

@elasticmachine
Copy link
Contributor

Can one of the admins verify this patch?

@dpenny52
Copy link
Contributor Author

dpenny52 commented Feb 19, 2017

confirmButtonText: 'bye',
onConfirm: confirmCallback,
onCancel: cancelCallback,
onClose: closeCallback,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can remove the onClose lines in your tests, as well as the showClose setting. They aren't actually used in these tests anyway.


const e = angular.element.Event('keydown'); // eslint-disable-line new-cap
e.keyCode = 27;
while(e.keyCode === 27) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need to worry about the random value here. Just set the keyCode to a value other than 27. Probably good to avoid 9 (tab) and 13 (enter) too. You could play it safe and just pick a letter, so any value between 48 and 90 is fine.

}
};

angular.element(document.body).bind('keydown', onKeyDown);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use .on here instead of .bind

@@ -1 +1 @@
<div class="kuiModalOverlay"></div>
<div class="kuiModalOverlay" ng-keydown="onKeyDown($event)"></div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you're listening for the keypress event on document.body, you don't need this keydown directive here.

@dpenny52
Copy link
Contributor Author

Thanks for the comments, I will make these changes later on tonight or tomorrow.

@w33ble
Copy link
Contributor

w33ble commented Feb 27, 2017

@dpenny52 you got it. Sorry it took me a while to review this, my local environment was being really goofy.

I also opened dpenny52#1 for you to check out. It's a small change to some of the test code that was already there, but it affects the couple tests you wrote as well.

@dpenny52
Copy link
Contributor Author

Updated with your PR + comments @w33ble


angular.element(document.body).on('keydown', (event) => {
if(event.keyCode === 27) {
scope.onCancel();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be onClose, not onCancel (I know you have concerns @w33ble about the differences between them, and I am starting to see your side of things, since this is a subtle difference, and it caused confusion here).

onClose will be onCancel unless a caller specifically sent a separate function - onClose maps to the X, while onCancel maps to one of the buttons.

Copy link
Contributor

@w33ble w33ble Feb 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But if there is no X, then onCancel is the interaction we want.

And this is why I've been advocating for a new dialog type for when you want the X/close button. They're different things ;)

But this isn't really a concern for @dpenny52 to worry about. I think this PR should be handled with the intention of working with the "confirm" modal, and we can break out the "close" functionality and make a new modal later. To my knowledge, we don't use the yes/no/close interaction anywhere right now, so it's safe to pretend it doesn't exist yet.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related: #10104 (comment) - your comment which advocates removing the Close option (and thus onClose) from the existing confirm modal.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough. Actually the whole reason for the onClose functionality may be going away, so we could rip that out (though I'd prefer to wait till after #10585 gets checked in just to be sure).

My modified feedback, in that case, is that I still think this logic should either go in confirm_modal, or be passed in as a function. No need for the modal overlay to have scope knowledge, and this could easily break if we change the name of the function inside confirm_modal.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you both agree on that point I'd be happy to move that code down to the dialog level.

Copy link
Contributor

@w33ble w33ble Mar 1, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think I'm on board with that part. I think that, while you're right @dpenny52 about the ESC being a universal modal interaction, we probably want to handle it differently in each case (as outlined in the whole onClose/onCancel conversation here). For now, let's move it into the confirm modal, and we can worry about pushing that logic back up when we add other modal types.

@@ -5,16 +5,23 @@ import modalOverlayTemplate from './modal_overlay.html';
* Appends the modal to the dom on instantiation, and removes it when destroy is called.
*/
export class ModalOverlay {
constructor(modalElement) {
constructor(modalElement, scope) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this functionality belongs in confirm_modal.js, and I think we should only bind ESC key functionality if showClose is true in confirm_modal.

My concern is, we don't always show the X in the modal, and if we don't show the X then I think we should force the user to be explicit about their choice. Esc usually means, do nothing or dont make a choice right now which is what I see being mapped to the X icon functionality on a dialog. onCancel and onConfirm can be any functions, and the button text can also be anything, so it might not be a "noop" type of function.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should only bind ESC key functionality if showClose is true in confirm_modal

I disagree. Keyboard navigation is key, and ESC means "no" on a confirmation dialog. If we're going to replace native functionality, we need to provide the same interactions in our replacement.

if we don't show the X then I think we should force the user to be explicit about their choice

We are. They can't do anything else until they deal with the confirm dialog. "no" is a valid response, and ESC allows the user to respond that way with from the keyboard, just like they could always do before.

The functionality we're trying to replicate here is that of window.confirm, and adding ESC handling gets us there.

Copy link
Contributor Author

@dpenny52 dpenny52 Feb 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also agree that ESC traditionally maps to "Cancel" in basically any dialog that I can think of. It would be very confusing/annoying to me as a user if I was used to navigating using a keyboard, then opened a dialog with "showClose=false" and suddenly my normal means of navigation doesn't work anymore.

@stacey-gammon The reason I put this in the ModalOverlay rather than the ConfirmDialog itself was so that the functionality could be re-used for other dialog types when they are created. I figured that ESC->Cancel is universal enough that it would be re-used for any other dialog. If that's not desired then it is easy enough to move that code to the dialog itself.

@dpenny52
Copy link
Contributor Author

dpenny52 commented Mar 1, 2017

Updated with keyboard handling in confirm_modal.js

Copy link
Contributor

@stacey-gammon stacey-gammon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm Thanks @dpenny52!

Copy link
Contributor

@w33ble w33ble left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @dpenny52 for the submission!

@w33ble w33ble merged commit cbe26ea into elastic:master Mar 1, 2017
w33ble pushed a commit that referenced this pull request Mar 1, 2017
* #10099 adds keyboard handling to close confirm_modal on ESC

* remove resetSpyCounts, use beforeEach

* #10099 change from .bind to .on and remove unnecessary onKeyDown call

* #10099 move ESC handling to confirm_modal.js
w33ble pushed a commit that referenced this pull request Mar 1, 2017
* #10099 adds keyboard handling to close confirm_modal on ESC

* remove resetSpyCounts, use beforeEach

* #10099 change from .bind to .on and remove unnecessary onKeyDown call

* #10099 move ESC handling to confirm_modal.js
@w33ble
Copy link
Contributor

w33ble commented Mar 1, 2017

5.x: 3264487
5.3: 6641bc1

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

Successfully merging this pull request may close these issues.

5 participants