Submit jQuery UI dialog on <Enter>

I have a jQuery UI dialog box with a form. I would like to simulate a click on one of the dialog's buttons so you don't have to use the mouse or tab over to it. In other words, I want it to act like a regular GUI dialog box where simulates hitting the "OK" button.

I assume this might be a simple option with the dialog, but I can't find it in the jQuery UI documentation. I could bind each form input with keyup() but didn't know if there was a simpler/cleaner way. Thanks.


Solution 1:

I don't know if there's an option in the jQuery UI widget, but you could simply bind the keypress event to the div that contains your dialog...

$('#DialogTag').keypress(function(e) {
    if (e.keyCode == $.ui.keyCode.ENTER) {
          //Close dialog and/or submit here...
    }
});

This'll run no matter what element has the focus in your dialog, which may or may not be a good thing depending on what you want.

If you want to make this the default functionality, you can add this piece of code:

// jqueryui defaults
$.extend($.ui.dialog.prototype.options, { 
    create: function() {
        var $this = $(this);

        // focus first button and bind enter to it
        $this.parent().find('.ui-dialog-buttonpane button:first').focus();
        $this.keypress(function(e) {
            if( e.keyCode == $.ui.keyCode.ENTER ) {
                $this.parent().find('.ui-dialog-buttonpane button:first').click();
                return false;
            }
        });
    } 
});

Here's a more detailed view of what it would look like:

$( "#dialog-form" ).dialog({
  buttons: { … },
  open: function() {
    $("#dialog-form").keypress(function(e) {
      if (e.keyCode == $.ui.keyCode.ENTER) {
        $(this).parent().find("button:eq(0)").trigger("click");
      }
    });
  };
});

Solution 2:

I have summed up the answers above & added important stuff

$(document).delegate('.ui-dialog', 'keyup', function(e) {
        var target = e.target;
        var tagName = target.tagName.toLowerCase();

        tagName = (tagName === 'input' && target.type === 'button') 
          ? 'button' 
          : tagName;

        isClickableTag = tagName !== 'textarea' && 
          tagName !== 'select' && 
          tagName !== 'button';

        if (e.which === $.ui.keyCode.ENTER && isClickableTag) {
            $(this).find('.ui-dialog-buttonset button').eq(0).trigger('click');

            return false;
        }
    });

Advantages:

  1. Disallow enter key on non compatible elements like textarea , select , button or inputs with type button , imagine user clicking enter on textarea and get the form submitted instead of getting new line!
  2. The binding is done once , avoid using the dialog 'open' callback to bind enter key to avoid binding the same function again and again each time the dialog is 'open'ed
  3. Avoid changing existing code as some answers above suggest
  4. Use 'delegate' instead of the deprecated 'live' & avoid using the new 'on' method to allow working with older versions of jquery
  5. Because we use delegate , that mean the code above can be written even before initializing dialog. you can also put it in head tag even without $(document).ready
  6. Also delegate will bind only one handler to document and will not bind handler to each dialog as in some code above , for more efficiency
  7. Works even with dynamically generated dialogs like $('<div><input type="text"/></div>').dialog({buttons: .});
  8. Worked with ie 7/8/9!
  9. Avoid using the slow selector :first
  10. Avoid using hacks like in answers here to make a hidden submit button

Disadvantages:

  1. Run the first button as the default one , you can choose another button with eq() or call a function inside the if statement
  2. All of dialogs will have same behavior you can filter it by making your selector more specific ie '#dialog' instead of '.ui-dialog'

I know the question is old but I have had the same need, so, I shared the solution I've used.

Solution 3:

$('#dialogBox').dialog('open');
$('.ui-dialog-buttonpane > button:last').focus();

It works beautifully with the latest version of JQuery UI (1.8.1). You may also use :first instead of :last depending on which button you want to set as the default.

This solution, compared to the selected one above, has the advantage of showing which button is the default one for the user. The user can also TAB between buttons and pressing ENTER will click the button currently under focus.

Cheers.