Skip to content
Permalink
Browse files

UX: Trigger primary action in modals using Enter

A modal's primary action (blue button in the default theme) can now be invoked
by hitting Enter on the keyboard. This applies to all modals that aren't strict
forms as long as the focus is not on a textarea element.
  • Loading branch information...
pmusaraj committed Oct 9, 2019
1 parent 10e509e commit a91ad81ed1e81ef0fd63e4d2c90b3e41daedb5d9
@@ -33,6 +33,10 @@ export default Ember.Component.extend({
if (e.which === 27 && this.dismissable) {
Ember.run.next(() => $(".modal-header a.close").click());
}

if (e.which === 13 && this.triggerClickOnEnter(e)) {
Ember.run.next(() => $(".modal-footer .btn-primary").click());
}
});

this.appEvents.on("modal:body-shown", this, "_modalBodyShown");
@@ -44,6 +48,18 @@ export default Ember.Component.extend({
this.appEvents.off("modal:body-shown", this, "_modalBodyShown");
},

triggerClickOnEnter(e) {
// skip when in a form or a textarea element
if (
$(e.target).parents("form").length > 0 ||
(document.activeElement && document.activeElement.nodeName === "TEXTAREA")
) {
return false;
}

return true;
},

mouseDown(e) {
if (!this.dismissable) {
return;
@@ -52,3 +52,38 @@ QUnit.test("modal", async function(assert) {
"ESC should not close the modal"
);
});

acceptance("Modal Keyboard Events", { loggedIn: true });

QUnit.test("modal-keyboard-events", async function(assert) {
await visit("/t/internationalization-localization/280");

await click(".toggle-admin-menu");
await click(".topic-admin-status-update button");
await keyEvent(".d-modal", "keydown", 13);

assert.ok(
find("#modal-alert:visible").length === 1,
"hitting Enter triggers modal action"
);
assert.ok(
find(".d-modal:visible").length === 1,
"hitting Enter does not dismiss modal due to alert error"
);

await keyEvent("#main-outlet", "keydown", 27);
assert.ok(
find(".d-modal:visible").length === 0,
"ESC should close the modal"
);

await click(".topic-body button.reply");

await click(".d-editor-button-bar .btn.link");

await keyEvent(".d-modal", "keydown", 13);
assert.ok(
find(".d-modal:visible").length === 0,
"modal should disappear on hitting Enter"
);
});

2 comments on commit a91ad81

@discoursereviewbot

This comment has been minimized.

Copy link

replied Oct 9, 2019

Robin Ward posted:

This commit is fine, but FYI is very close to the equivalent code that doesn't use jQuery.

Instead of $(e.target).parents("form") for example you could do e.target.closest('form').

These days I prefer not to use jQuery unless I absolutely have to.

@discoursereviewbot

This comment has been minimized.

Copy link

replied Oct 9, 2019

Penar Musaraj posted:

Thanks, I did not know closest could be used this way.

Please sign in to comment.
You can’t perform that action at this time.