3

I use Bootbox.js (http://bootboxjs.com/) to pop up forms in my application. Bootbox has an API for specifying callbacks on any custom buttons you may choose to add to your dialog. For example, here's an options object that gets passed into Bootbox:

var dialogOptions = {
    message: bodyMessage,
    className: uniqueClass,
    closeButton: false,
    onEscape: false,
    title: i18n.t("common.loginHeader"),
    buttons: {
      login: {
        label: i18n.t("common.signIn"),
        className: "btn btn-success ",
        callback: function () {
          var user = $("#username").val();
          var password = $("#password").val();
          var toEncode = user + ":" + password;
          fcr.api.authorization(window.btoa(toEncode), successCallback, errorCallback);
          return false;
        }
      }
    }
  };

As you can guess, it's an authentication dialog. The "return false" in the callback prevents the dialog from closing (the authentication method will find and close it if successful). Other than that, it just gathers some form values and sends them along.

Thing is, since the button is not a "Submit" DOM element, it doesn't listen for the "Enter" key. To be honest, this is usually a blessing. But in this one particular case (username/password form), I constantly intuitively expect it to submit with the "Enter" key. If I try to add a Submit button to the form, the consistency of the visual "vocabulary" is lost. The button needs to be part of the dialog, not part of the form.

I could add a listener to the password field that listens for the enter key (code 13):

$('#password').keypress(function(e) {
  if(e.which == 13) {
    // do the submit?
  }
});

But it seems kind of hack-ish. And I would have to abstract the callback into an action method of some sort so that either activity could call it. Not necessarily a bad thing, but I won't need that function anywhere else so it seems to be an abstraction I could avoid given an alternative. Is this the only way to get'r done, or does anybody know of something more elegant?

Greg Pettit
  • 10,749
  • 5
  • 53
  • 72

2 Answers2

4

I don't know that I'd call it elegant, but one possibility would be to add your keypress listener to a higher parent, and then trigger the login button's click event:

Add a class to the login button:

login: {
    className: "btn btn-success login-btn",
}

Add the listener to the modal itself (or, in this case, the form you injected):

$('.' + uniqueClass + ' form').on('keypress', function(e) {
    if(e.which == 13) {
        $('.login-btn').trigger('click');
    }
});

With the requisite jsFiddle: https://jsfiddle.net/aLeqec2L/

Tieson T.
  • 20,774
  • 6
  • 77
  • 92
  • 1
    This is a generally correct answer and I appreciate the time you took. In the end, the form is actually in the DOM (I store them elsewhere and fly them into the dialog) and the dialog is created on the fly. So if I just bind to the #password field (per the question) or to the form (per your example but without the modal's unique class) as the listener, either work. I ended up binding to the form, listening for keyup specifically on the password field. I'mma throw that into an answer but keep this one accepted. – Greg Pettit Oct 30 '15 at 14:36
1

Tieson's response is general-purpose and correct. In the end, I modified it a bit to suit my specific purposes. The general-purpose answer is more suited to future users looking for an answer, but for posterity here's my code:

$('#loginForm').on('keyup', '#passwordInputField', function(e) {
  if (e.which === 13) {
    $('.credentialSubmitButton').trigger('click');
  }
});

I have a single loginForm and passwordInputField on the page.

I updated the Bootbox.js dialog to add a class to my button; the updated dialog now contains buttons.login.className with a value of 'btn-success credentialSubmitButton'. I'm using this extra class as a unique selector which is a bit risky but there's no real choice since Bootbox.js does not allow specifying an ID for the buttons as far as I know.

There's a lot of tighter coupling and unique identifiers than I would prefer. I would rather have that tight coupling occurring inside the Bootbox definition (tight coupling is OK when properly encapsulated) hence my quest for a more "elegant" solution. But this works. It does its job.

Greg Pettit
  • 10,749
  • 5
  • 53
  • 72