jquery-ui Dialog: Make a button in the dialog the default action (Enter key)

JavascriptJqueryJquery UiModal Dialog

Javascript Problem Overview


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.

Javascript Solutions


Solution 1 - Javascript

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.

Solution 2 - Javascript

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.

Solution 3 - Javascript

try this way:

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

Solution 4 - Javascript

This other stackoverflow question should get you where you want:

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

Solution 5 - Javascript

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();
    }
});

Solution 6 - Javascript

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(); 
    }
});

Solution 7 - Javascript

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.

Solution 8 - Javascript

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();
}

Solution 9 - Javascript

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

Solution 10 - Javascript

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...

Solution 11 - Javascript

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();
      
  },

Solution 12 - Javascript

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

Solution 13 - Javascript

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");
         }
      }
   ]
});

Solution 14 - Javascript

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();
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionfguiView Question on Stackoverflow
Solution 1 - JavascriptNick CraverView Answer on Stackoverflow
Solution 2 - JavascriptEugenio MiróView Answer on Stackoverflow
Solution 3 - JavascriptmadeuzView Answer on Stackoverflow
Solution 4 - JavascriptThomasView Answer on Stackoverflow
Solution 5 - JavascriptMark BView Answer on Stackoverflow
Solution 6 - Javascriptmatt burnsView Answer on Stackoverflow
Solution 7 - JavascriptDarrenView Answer on Stackoverflow
Solution 8 - JavascriptNiklausView Answer on Stackoverflow
Solution 9 - JavascriptNaveenView Answer on Stackoverflow
Solution 10 - JavascriptuksitebuilderView Answer on Stackoverflow
Solution 11 - JavascriptMarcel VerweyView Answer on Stackoverflow
Solution 12 - JavascriptChris GongView Answer on Stackoverflow
Solution 13 - JavascriptStephenView Answer on Stackoverflow
Solution 14 - JavascriptAlekseyView Answer on Stackoverflow