views:

4925

answers:

7

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.

+1  A: 

if you know the button element selector :

$('#dialogBox').dialog('open');
$('#okButton').focus();

Should do the trick for you. This will focus the ok button, and enter will 'click' it, as you would expect. This is the same technique used in native UI dialogs.

sandesh247
This would work if a form wasn't involved.
CMB
+2  A: 

I don't know about simpler, but ordinarily you would track which button has the current focus. If the focus is changed to a different control, then the "button focus" would remain on the button that had focus last. Ordinarily, the "button focus" would start on your default button. Tabbing to a different button would change the "button focus". You'd have to decide if navigating to a different form element would reset the "button focus" to the default button again. You'll also probably need some visual indicator other than the browser default to indicate the focused button as it loses the real focus in the window.

Once you have the button focus logic down and implemented, then I would probably add a key handler to the dialog itself and have it invoke the action associated with the currently "focused" button.

EDIT: I'm making the assumption that you want to be able hit enter anytime you are filling out form elements and have the "current" button action take precedence. If you only want this behavior when the button is actually focused, my answer is too complicated.

tvanfosson
+16  A: 

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

$('#DialogTag').keyup(function(e) {
    if (e.keyCode == 13) {
     //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.

Lunchy
How to do this if dialog is created on-the-fly as in $('<div title="my title">Message</div>').dialog()... ?
Milan Babuškov
Nevermind, I found it: add "open" to dialog (like like close, modal, bgiframe, etc.) and hook the keyup handler there.
Milan Babuškov
This works well in conjunction with the close callback option on the dialog; your various buttons and this method can all close the dialog, and then the close callback can check to see if it should act upon the dialog's information.
TALlama
For Webkit (Safari/Chrome), this only works if I do "keydown" instead of "keyup". Not sure if this is a recent change or if it matters that my page also has a real form on it. Still, thanks for the tip!
Nicholas Piasecki
+1  A: 

A crude but effective way to make this work more generically:

$.fn.dlg = function(options) {
    return this.each(function() {
             $(this).dialog(options);
             $(this).keyup(function(e){
                  if (e.keyCode == 13) {                
                       $('.ui-dialog').find('button:first').trigger('click');
                  }
             });
    });
}

Then when you create a new dialog you can do this:

$('#a-dialog').mydlg({...options...})

And use it like a normal jquery dialog thereafter:

$('#a-dialog').dialog('close')

There are ways to improve that to make it work in more special cases. With the above code it will automatically pick the first button in the dialog as the button to trigger when enter is hit. Also it assumes that there is only one active dialog at any given time which may not be the case. But you get the idea.

Note: As mentioned above, the button that is pressed on enter is dependent on your setup. So, in some cases you would want to use the :first selector in .find method and in others you may want to use the :last selector.

Karim
I think there should be a .first() in there as in $('.ui-dialog').find('button').first().trigger('click');Otherwise you'll trigger the click of all the buttons of the dialog if there are more than one.
JustinStolle
You're right. Thanks.
Karim
+1  A: 
$('#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.

Mario Awad
A: 

Used Karim's method above. Works great, but then there's autocomplete. So, when a user picks a value from autocomplete (FF) they then hit enter. Guess what. Was looking for a way to flag if they are in autocomplete, but not really finding anything. Anyone have any ideas?

dudeman
A: 

done and done

  $('#login input').keyup(function(e) {
if (e.keyCode == 13) {
  $('#login form').submit();
}

}

kevin