60

In a jquery modal dialog, is there a way to select a button as the default action (action to execute when the user presses enter)?

Example of jquery web site: jquery dialog modal message

In the example above the dialog closes when the user presses Esc. I would like the "Ok" button action to be called when the user presses Enter.

asked Mar 26, 2010 at 9:23
1

14 Answers 14

40

In your dialog's open function, you can focus the button:

$("#myDialog").dialog({
 open: function() {
 $(this).parents('.ui-dialog-buttonpane button:eq(0)').focus(); 
 }
});

Change the :eq(0) if it's at a different index, or find by name, etc.

answered Mar 26, 2010 at 14:50
7
  • 5
    I just wrote the code to using $(this).parent().find('button:nth-child(1)').focus(); which is similar. Thanks Commented Mar 26, 2010 at 15:16
  • 9
    Yeah, I did open: function() { $(this).parent().find('.ui-dialog-buttonpane button:eq(1)').focus(); }. Commented May 17, 2012 at 23:39
  • 4
    I don't think this method works on newer versions of jQuery UI. The dialog's DOM now appears to have div.ui-dialog-buttonpane as a sibling, not a parent of $(this). Check out madeuz's answer below. zesc's answer will include the dialog's title bar "x". Gabriel's answer is basically the same as madeuz's, except the traversal is a bit different. Commented Mar 7, 2013 at 19:56
  • 1
    Any of the answer that use an event handler for keycode 13 are better than this since this only works when you only have buttons. If you want to have focus set to a different control than the default button this wont work. Darrens answer to use a form with a submit action may also be a better answer. Commented Jan 21, 2015 at 15:50
  • 2
    I found it worked but setting the focus is not the same as making the button default. If there are other controls in the div then once they are selected the button will not have focus any more ? Surely a keydown event is required ? Commented Dec 2, 2015 at 12:20
36

I like this one (it is working for me), which leaves the focus where I wanted to be (a text box)

 $("#logonDialog").keydown(function (event) {
 if (event.keyCode == $.ui.keyCode.ENTER) {
 $(this).parent()
 .find("button:eq(0)").trigger("click");
 return false;
 }
 });

However, this is working just for one button (Ok button), if needed ':eq(n)' could be set to select other button.

Note: I added a new line returning false to prevent event bubbling when the enter key is handled, I hope it helps better than before.

Takit Isy
10.2k3 gold badges29 silver badges48 bronze badges
answered Jan 26, 2012 at 13:04
3
  • 6
    This is the way to go. Setting focus (as shown in other solutions) will mess up power users who use tab to go to other fields and still want to hit "enter" anywhere in the form. Commented Aug 21, 2013 at 8:56
  • 1
    It is preferable to use which instead of keyCode. Commented Jan 21, 2015 at 16:27
  • To get this to work, I had to change the action line to this: $(this).parent().find('button:nth-child(1)').click(); Looks like the closer element already took the zeroth position! Commented Sep 20, 2016 at 19:28
20

try this way:

$("#myDialog").dialog({
 open: function() {
 $(this).siblings('.ui-dialog-buttonpane').find('button:eq(1)').focus(); 
 }
});
answered Dec 12, 2011 at 18:28
3
  • 2
    This appears to match the DOM created by newer versions of jQuery UI (tested in 1.9.2) . Check out jsfiddle.net/KF3pp/1 for a pattern that does not involve :eq(x) Commented Mar 7, 2013 at 19:23
  • Also, I believe this will work in any version of jQuery UI: $(this).parents('.ui-dialog').find('.ui-dialog-buttonpane button:eq(0)') . Commented Mar 7, 2013 at 20:02
  • 4
    This also worked for me in jQuery UI 1.10. The accepted answer did not. Commented Dec 10, 2013 at 15:44
12

This other stackoverflow question should get you where you want:

$('#DialogTag').keyup(function(e) {
 if (e.keyCode == 13) {
 //Close dialog and/or submit here...
 }
});
answered Mar 26, 2010 at 12:53
1
  • I did not found the question before posting this question. It is definely almost the same question. Thanks for pointing it out. I tried to make this code work without to much success. I tried downloading the latest version of jqueryui and adding this code to the example (index.html), I did not manage to make it work. Commented Mar 26, 2010 at 15:19
10

Another option that gives you more control over all buttons in the dialog is to add them as an array of buttons. Then in the open event you can get the buttons by id and do whatever you want (including set the focus)

$('#myDialog').dialog({
 buttons: [ 
 {
 id: "btnCancel",
 text: "Cancel",
 click: function(){
 $(this).dialog('close');
 }
 },
 {
 id: "btnOne",
 text: "Print One",
 click: function () {
 SomeFunction(1);
 }
 },
 {
 id: "btnTwo",
 text: "Print Two",
 click: function(){
 SomeFunction(0);
 }
 }
 ],
 open: function () {
 if ($('#hiddenBool').val() != 'True') {
 $('#btnOne').hide();
 }
 $("#btnTwo").focus();
 }
});
answered Aug 28, 2013 at 23:52
1
  • I couldn't get $("#btnTwo").focus(); to work to focus the button. Whoops. My bad. It did! Commented Aug 18, 2015 at 19:28
6

A slight variation to use the buttons name as the selector. It reads a little better but there is obvious duplication with the button text string. Refactor to taste.

$("#confirm-dialog").dialog({
 buttons: {
 "Cancel" : function(){},
 "OK" : function(){}
 },
 open: function() {
 $(this).siblings('.ui-dialog-buttonpane').find("button:contains('OK')").focus(); 
 }
});
answered May 21, 2013 at 16:17
2

The simplest way would be to use the submit action on a form within the dialog, however:

  • I did not want to require a form within dialog (N.B. different browsers handle the enter key differently, and some do not always do a submit on enter).
  • I wanted this to work if the user clicks in the title pane or button pane prior to pressing enter.
  • I wanted to make a library method that I can use for ANY jQueryUI dialog.

The company I work for is 'EBL' and I avoid global scope...hence the prefix on the functions below:

EBL.onUiDialogOpen = function (event, ui, hideX, actionFirstButtonOnEnterKey) {
 if (hideX) {
 // There is no option to hide the 'X' so override.
 $(".ui-dialog-titlebar-close").hide();
 }
 if (actionFirstButtonOnEnterKey) {
 /* (event.target) will give the div that will become the content 
 of a UI dialog, once div is 'opened' is it surrounded by a 
 parent div that contains title and buttonpane divs as well as 
 content div - so I use .parent()
 ...The keyup function is binded to all descendants, therefore:
 -We need the e.stopPropagation() line.
 -This code is NOT what you want if you DON'T want enter 
 key to initiate first button regardless of selected control.
 */
 $(event.target).parent().bind('keydown.justWhileOpen', function (e) {
 if (e.keyCode === $.ui.keyCode.ENTER) {
 e.stopPropagation();
 $(event.target).next('.ui-dialog-buttonpane')
 .find('button:first').click();
 }
 });
 }
};

...works in combination with:

EBL.onUiDialogClose = function (event, ui) {
 // Remove keyup handler when we close dialog
 $(event.target).parent().unbind('.justWhileOpen');
};

You do not need the .onUiDialogClose if you are using a dynamically created div and destroying it afterwards.

You can see below how I use these library functions when initialising a non-dynamic dialog...

$('#divName').dialog({
 //...
 open: function (event, ui) { EBL.onUiDialogOpen(event, ui, false, true); },
 close: function (event, ui) { EBL.onUiDialogClose(event, ui); },
 //...
});

So far I have tested this in IE9 and latest chrome/firefox. You should validate the dialog as neccessary in your 'Ok' function.

answered Mar 9, 2012 at 4:07
1
  • You could hide the close-X with the following CSS, from the JQuery site: .no-close .ui-dialog-titlebar-close { display: none; } and then style the dialog like so: $( "#dialog" ).dialog({ dialogClass: "no-close", ... Commented Oct 28, 2013 at 3:28
1

I'm using version 1.10.0. I could not get it to work with open but with focus. This focuses the second button:

focus: function(){
 $(this).siblings('.ui-dialog-buttonpane').find('button:eq(1)').focus();
}
answered Jun 27, 2013 at 10:37
1
$("#logonDialog").keydown(function (event) {if (event.keyCode == 13) {
 $(this).parent().find("button:eq(0)").trigger("click");
 return false;
 }
});
Mark
8,47115 gold badges52 silver badges81 bronze badges
answered Oct 18, 2013 at 9:19
1

This worked for me within the dialog using jquery 1.10.2

dialog({
 focus: function() {
 $(this).on("keyup", function(e) {
 if (e.keyCode === 13) {
 $(this).parent().find("button:eq(1)").trigger("click");
 return false;
 }
 });
 },

more options...

answered Nov 2, 2013 at 12:47
0

This simple piece of code styles your buttons and sets the default to the last one:

 open: function(){
 $buttonPane = $(this).next();
 $buttonPane.find('button:first').addClass('accept').addClass('ui-priority-secondary');
 $buttonPane.find('button:last').addClass('cancel').addClass('ui-state-default');
 $buttonPane.find('button:last').focus();
 },
answered Sep 1, 2013 at 12:10
1
  • This answer could be improved if it was in the context of jquery ui dialog. Commented Aug 19, 2017 at 22:32
0

In my case, none of the answers worked because I called .dialog on an empty div and added my buttons dynamically, so the $(this).html() would return nothing. So I couldn't call methods like parent() or siblings() and expect something in return. What I did was select the ui-dialog-buttonpane class directly and find the button element from there

HTML

<div id = "dialogexample">
</div>

Jquery

$("#dialogexample").dialog({
 autoOpen: false,
 modal: true,
 open: function () {
 $('.ui-dialog-buttonpane').find('#otherbutton').focus();
 }
});
var buttons = {
 "MyButton" : {
 text: "Do Stuff",
 id: "dostuffbutton" 
 },
 "OtherButton" : {
 text: "Other Stuff",
 id: "otherbutton"
 }
} 
$("#dialogexample").dialog("option", "buttons", buttons);
$("#dialogexample").dialog("open"); //the second (otherbutton), instead of
 //the first (dostuffbutton) button should be focused
answered Aug 18, 2017 at 15:07
0

I know this is an old thread, but I was searching for this exact functionality and was able to implement what I think is the best solution as I found all of the above to fall short a little.

It is a combination of two answers above. Using an ID rather than relying on the find() function to find the button element always seems to be a much better choice to me.

Also explicitly looking for the enter key to be pressed allows us to set focus to whatever element we want when the dialog is opened if desired. This just seems to allow for the most flexibility while satisfying the desire of triggering a specific button as 'default' when the enter key is pressed. I have also implemented a 'cancel' default as well.

I hope this helps others looking for a good 'default' button solution for dialogs.

$("#LoginBox").dialog({
 open: function(){
 $(this).keydown(function (event) {
 if (event.keyCode == 13) {
 $("#LogInButton").trigger("click");
 return false;
 }
 if (event.keyCode == 27) {
 $("#CancelButton").trigger("click");
 return false;
 }
 });
 },
 close: function(){
 $(this).dialog("destroy");
 },
 buttons: [
 {
 id: "LogInButton",
 text: "Log In",
 click: function(){
 //button functionality goes here
 $(this).dialog("destroy");
 }
 },
 {
 id: "CancelButton",
 text: "Cancel",
 click: function(){
 $(this).dialog("destroy");
 }
 }
 ]
});
answered Oct 17, 2017 at 15:04
0

You should to use :tabbable selector and index of your button (0 is [X] button, yours started from 1)

open: function() {
 var tb = $(":tabbable", this.parentNode);
 if(tb.length>1) {
 tb[1].focus();
 }
}
answered Nov 23, 2017 at 19:26

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.