在 <Enter> 上提交 jQuery UI 对话框

Submit jQuery UI dialog on <Enter>

提问人:CMB 提问时间:5/15/2009 更新时间:4/14/2018 访问量:91364

问:

我有一个带有表单的jQuery UI对话框。我想模拟单击对话框的某个按钮,这样您就不必使用鼠标或选项卡。换句话说,我希望它像一个常规的 GUI 对话框一样,模拟点击“确定”按钮。

我认为这可能是对话框的简单选项,但我在jQuery UI文档中找不到它。我可以用keyup()绑定每个表单输入,但不知道是否有更简单/更干净的方法。谢谢。

javascript jquery jquery-ui

评论

0赞 Darren 3/9/2012
如果您希望避免使用表单并希望可重用的代码,我在这里提供了一个很好的答案:stackoverflow.com/a/9628800/329367

答:

0赞 sandesh247 5/15/2009 #1

如果您知道按钮元素选择器:

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

应该为你做伎俩。这将聚焦确定按钮,并输入将“单击”它,正如您所期望的那样。这与本机 UI 对话框中使用的技术相同。

4赞 tvanfosson 5/15/2009 #2

我不知道更简单,但通常您会跟踪哪个按钮具有当前焦点。如果焦点更改为其他控件,则“按钮焦点”将保留在最后焦点的按钮上。通常,“按钮焦点”将从您的默认按钮开始。按 Tab 键切换到其他按钮会更改“按钮焦点”。您必须决定导航到其他表单元素是否会再次将“按钮焦点”重置为默认按钮。您可能还需要一些视觉指示器,而不是浏览器默认值,以指示焦点按钮,因为它在窗口中失去了真正的焦点。

一旦您关闭并实现了按钮焦点逻辑,那么我可能会向对话框本身添加一个键处理程序,并让它调用与当前“焦点”按钮关联的操作。

编辑:我假设您希望在填写表单元素时能够按回车键,并优先使用“当前”按钮操作。如果你只在按钮实际聚焦时才想要这种行为,我的答案太复杂了。

154赞 Casey Williams 5/15/2009 #3

我不知道jQuery UI小部件中是否有选项,但您可以简单地将事件绑定到包含对话框的div...keypress

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

无论哪个元素在对话框中具有焦点,它都会运行,这可能是一件好事,也可能不是一件好事,具体取决于您想要什么。

如果要将其设置为默认功能,可以添加以下代码:

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

以下是它的外观的更详细视图:

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

评论

2赞 Milan Babuškov 8/31/2009
没关系,我找到了它:将“打开”添加到对话框中(如关闭、模态、bgiframe 等)并在那里挂钩 keyup 处理程序。
5赞 Nicholas Piasecki 4/17/2010
对于 Webkit (Safari/Chrome),这仅在我执行“keydown”而不是“keyup”时才有效。不确定这是最近的更改,还是我的页面上也有真实的表单是否重要。不过,感谢您的提示!
12赞 A. Murray 9/12/2011
你可以用if (e.keyCode === $.ui.keyCode.ENTER)来增加可读性,而不是if (e.keyCode == 13)。
2赞 cburgmer 3/11/2012
我对这个答案投了反对票。虽然它简短而简洁,但在 Firefox 7.0.1 中,如果用户从自动完成下拉框中选择某些内容,例如之前输入的电子邮件地址,这也会触发您的“确定”按钮。
2赞 Elezar 4/30/2014
绑定到“open:”中的事件是个坏主意。这将导致每次打开对话框时重新绑定它,这意味着如果对话框打开两次,则事件处理程序将被调用两次。
6赞 Karim 12/3/2009 #4

一种粗略但有效的方法,可以使这项工作更通用:

$.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');
                  }
             });
    });
}

然后,当您创建新对话框时,您可以执行以下操作:

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

然后像普通的jquery对话框一样使用它:

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

有一些方法可以改进它,使其在更特殊的情况下工作。使用上面的代码,它将自动选择对话框中的第一个按钮作为点击回车时触发的按钮。此外,它假设在任何给定时间只有一个活动对话框,但事实可能并非如此。但你明白了。

注意:如上所述,在回车时按下的按钮取决于您的设置。因此,在某些情况下,您可能希望在 .find 方法中使用 :first 选择器,而在其他情况下,您可能希望使用 :last 选择器。

评论

0赞 JustinStolle 5/3/2010
我认为那里应该有一个 .first(),如 $('.ui-dialog').find('button').first().trigger('click');否则,如果有多个按钮,您将触发单击对话框的所有按钮。
0赞 David Harkness 8/3/2011
@thejh - 否,它会将 keyup 事件处理程序附加到每个对话框,但只有在按下该键时包含具有焦点的元素的对话框才会接收该事件。
13赞 Mario Awad 5/14/2010 #5
$('#dialogBox').dialog('open');
$('.ui-dialog-buttonpane > button:last').focus();

它与最新版本的 JQuery UI (1.8.1) 完美配合。 您也可以使用 :first 而不是 :last,具体取决于要设置为默认按钮的按钮。

与上面选择的解决方案相比,此解决方案的优点是显示哪个按钮是用户的默认按钮。用户还可以在按钮之间按 TAB 键,按 Enter 键将单击当前处于焦点状态的按钮。

干杯。

评论

0赞 David Harkness 8/3/2011
如果您的对话框有一个或多个文本输入字段,该怎么办?我希望 ENTER 在用户位于用户名和密码字段中时提交登录对话框。
1赞 Damo 12/20/2011
@David,如果您使用的是 jQuery 对话框按钮,则只需隐藏表单上的正常输入提交按钮即可。例如。可见性:隐藏;
1赞 kevin 10/8/2010 #6

完成和完成

  $('#login input').keyup(function(e) {
      if (e.keyCode == 13) {
          $('#login form').submit();
      }
   }
2赞 Stanislav Vychegzhanin 12/23/2010 #7

我就是这样做的...... ;)希望它对某人有所帮助。

$(window).keypress(function(e) {
    if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
        $(".ui-dialog:visible").find('.ui-dialog-buttonpane').find('button:first').click();
        return false;
    }
});
0赞 LeCram 1/28/2011 #8
   $("#LogOn").dialog({
       modal: true,
       autoOpen: false,
       title: 'Please Log On',
       width: 370,
       height: 260,
       buttons: { "Log On": function () { alert('Hello world'); } },
       open: function() { $(this).parents('.ui-dialog-buttonpane button:eq(0)').focus();}
   });
2赞 timbrown 2/15/2011 #9

这应该可以触发按钮的单击处理程序的单击。此示例假定您已经在对话框中设置了表单以使用 jQuery.validate 插件。但可以很容易地适应。

open: function(e,ui) {
    $(this).keyup(function(e) {
        if (e.keyCode == 13) {
           $('.ui-dialog-buttonpane button:last').trigger('click');
        }
    });
},
buttons: {
    "Submit Form" : function() {
            var isValid = $('#yourFormsID').valid();
            // if valid do ajax call
            if(isValid){
               //do  your ajax call here. with serialize form or something...

            }
}
0赞 Robert Schmidt 4/4/2011 #10

我为这个问题找到了一个非常简单的解决方案:

var d = $('<div title="My dialog form"><input /></div>').dialog(
    buttons: [{
        text: "Ok",
        click: function(){
            // do something
            alert('it works');
        },
        className: 'dialog_default_button'
    }]
});

$(d).find('input').keypress(function(e){
    if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
        e.preventDefault();
        $('.dialog_default_button').click();
    }
});
6赞 Salida Software 5/14/2011 #11

与其像这个答案那样监听关键代码(我无法开始工作),不如在对话框中绑定到表单的 submit 事件,然后执行以下操作:

$("#my_form").parents('.ui-dialog').first().find('.ui-button').first().click();

所以,整个事情看起来像这样

$("#my_form").dialog({
  open: function(){
    //Clear out any old bindings
    $("#my_form").unbind('submit');
    $("#my_form").submit(function(){
      //simulate click on create button
      $("#my_form").parents('.ui-dialog').first().find('.ui-button').first().click();
      return false;
    });
  },
  buttons: {
    'Create': function() {
      //Do something
    },
    'Cancel': function() {
      $(this).dialog('close');
    }
  }
});

请注意,不同的浏览器对回车键的处理方式不同,有些浏览器并不总是在回车时提交。

评论

0赞 Dan 7/29/2011
这似乎是最优雅的答案。
0赞 programad 11/11/2011
当我在同一对话框中有三个或更多输入时,这不起作用。不知道为什么。
0赞 Peter 6/23/2011 #12
$('#DialogID').dialog("option", "buttons")["TheButton"].apply()

这对我来说效果很好。

评论

0赞 Dave 9/15/2011
最好包含对 $('#DialogID').dialog() 的引用作为要应用的参数。否则,$(this).close() 在 TheButton 中将没有正确的上下文。
1赞 Ben Clayton 10/10/2011 #13

我意识到已经有很多答案了,但我自然而然地认为我的解决方案是最简洁的,也可能是最短的。它的优点是它适用于将来任何时间创建的任何对话框。

$(".ui-dialog").live("keyup", function(e) {
    if (e.keyCode === 13) {
        $('.ok-button', $(this) ).first().click();
    }
});

评论

1赞 UID 10/4/2014
嘿,感谢您的更新,只是一个小问题,这里的“.ok-button”是什么?是您必须在要使用 Enter 单击的默认按钮上应用的类吗?
0赞 UID 10/4/2014
对不起,如果你发现这个问题,sily..m 在 JS/jQuery 中太新了
0赞 Be Kind To New Users 8/20/2017
@BenClayton:如果您将其放在jQueryUI对话框的上下文中,则可以改进此答案。
1赞 Tyler 12/31/2011 #14

这是我所做的:

myForm.dialog({
  "ok": function(){
    ...blah...
  }
  Cancel: function(){
    ...blah...
  }
}).keyup(function(e){
  if( e.keyCode == 13 ){
   $(this).parent().find('button:nth-child(1)').trigger("click");
  }
});

在本例中,myForm 是一个包含表单的 html 的 jQuery 对象(请注意,其中没有任何“表单”标签......如果您将它们放在整个屏幕中,则当您按“Enter”时会刷新)。

每当用户从表单中按“Enter”时,就相当于单击“确定”按钮。

这也避免了在“确定”按钮已突出显示的情况下打开表单的问题。虽然这对于没有字段的表单有好处,但如果您需要用户填写内容,那么您可能希望突出显示第一个字段。

评论

0赞 Vincent 1/6/2019
这是最合乎逻辑的解决方案。如果您使用 id 声明按钮并将选择器传递给 find(),那就更好了,但无论哪种方式都有效。+1
7赞 Nelson M 6/20/2012 #15

Ben Clayton 是最简洁、最短的,它可以在任何 jquery 对话框初始化之前放在索引页的顶部。但是,我想指出的是,“.live”已被弃用。首选操作现在是“.on”。如果希望“.on”像“.live”一样运行,则必须使用委托事件来附加事件处理程序。另外,还有其他一些事情......

  1. 我更喜欢使用ui.keycode.ENTER方法来测试回车 键,因为您不必记住实际的键代码。

  2. 使用 “$('.ui-dialog-buttonpane button:first', $(this))” 单击选择器使整个方法泛型。

  3. 您希望添加 “return false;” 以防止默认和停止 增殖。

在这种情况下...

$('body').on('keypress', '.ui-dialog', function(event) { 
    if (event.keyCode === $.ui.keyCode.ENTER) { 
        $('.ui-dialog-buttonpane button:first', $(this)).click();
        return false;
    }
});
0赞 Paul Martin 9/20/2012 #16

在IE9中,这些解决方案似乎都不适合我。我最终得到了这个..

$('#my-dialog').dialog({
    ...
    open: function () {
        $(this).parent()
               .find("button:eq(0)")
               .focus()
               .keyup(function (e) {
                   if (e.keyCode == $.ui.keyCode.ENTER) {
                       $(this).trigger("click");
                   };
               });
    }
});
67赞 Basemm 11/23/2012 #17

我总结了上面的答案,并添加了重要的东西

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

优势:

  1. 禁止在不兼容的元素(如 、 或带有类型按钮的输入)上输入键,想象一下用户单击回车并提交表单而不是换行!textareaselectbuttontextarea
  2. 绑定一次,避免使用对话框 open' 回调绑定回车键,避免每次对话框'open' 时一次又一次地绑定同一个函数
  3. 避免更改现有代码,因为上面的一些答案建议
  4. 使用“delegate”而不是已弃用的“live”,并避免使用新的“on”方法来允许使用旧版本的jquery
  5. 因为我们使用 delegate ,这意味着上面的代码甚至可以在初始化对话框之前编写。即使没有,您也可以将其放在头牌中$(document).ready
  6. 此外,委托将只绑定一个处理程序,并且不会像上面的一些代码那样将处理程序绑定到每个对话框,以提高效率document
  7. 甚至可以使用动态生成的对话框,例如$('<div><input type="text"/></div>').dialog({buttons: .});
  8. 与 ie 7/8/9 合作!
  9. 避免使用慢速选择器:first
  10. 避免使用像这里的答案那样的技巧来制作隐藏的提交按钮

弊:

  1. 将第一个按钮作为默认按钮运行,您可以在 if 语句中选择另一个按钮或调用函数eq()
  2. 所有对话框都将具有相同的行为,您可以通过使选择器更具体(即“#dialog”而不是'.ui-dialog'

我知道这个问题很老,但我也有同样的需求,所以,我分享了我使用过的解决方案。

评论

4赞 Chris O'Kelly 3/6/2013
事实上,这不是公认的答案,也没有更多的选票,这让我很难过,信息量最大,并且没有不断添加处理程序。+1
1赞 Jay Rizzi 6/19/2013
很好的答案,使用打开回调来添加绑定是您要避免的事情
1赞 Isaiyavan Babu Karan 8/3/2013
对我来说,当事件被键下并且我删除了 tagName 的所有条件并删除了点击触发器时,这起作用了
1赞 Nate Beaty 8/27/2013
我还必须更改为“keydown”才能完成这项工作(在 OS X 10.8.4、Chrome 29 和 Firefox 23 上测试)。
1赞 jinglesthula 11/19/2016
由于这是一个较旧的答案,值得注意的是,它在 jQuery 3.0 中已被弃用,因此(从 1.7 开始可用)可能是此时要走的路线。.delegate().on()
4赞 Pablo Oña 12/13/2012 #18

我找到了这个解决方案,它适用于 IE8、Chrome 23.0 和 Firefox 16.0

它基于罗伯特·施密特(Robert Schmidt)的评论。

$("#id_dialog").dialog({
    buttons: [{
        text: "Accept",
        click: function() {
            // My function
        },
        id: 'dialog_accept_button'
    }]
}).keyup(function(e) {
    if (e.keyCode == $.ui.keyCode.ENTER)
        $('#dialog_accept_button').click();
});

我希望它对任何人都有帮助。

评论

0赞 Rahul Desai 1/17/2015
谢谢!这为我节省了很多时间!:)
0赞 Julian Knight 1/17/2021
简单有效。最好的答案在这里。为什么没有将按钮设置为默认按钮的选项,我不知道。
3赞 Seifu 3/1/2013 #19

有时我们忘记了浏览器已经支持的基本功能:

<input type="submit" style="visibility:hidden" />

这将导致密钥提交表单。ENTER

-1赞 Durgaprasad Katari 9/17/2013 #20

它工作正常,谢谢!!

open: function () { debugger; $("#dialogDiv").keypress(function (e) { if (e.keyCode == 13) { $(this).parent().find("#btnLoginSubmit").trigger("click"); } }); },

评论

0赞 kleopatra 9/17/2013
嗯。。。您的帖子中有什么新内容(与之前的答案相比)吗?
0赞 LoopCoder 7/25/2014 #21

使用下面的 body,因为在 body 上添加了对话框 DIV,所以 body 现在监听键盘事件。它在 IE8、9、10、Mojila、Chrome 上进行了测试。

open: function() {
$('body').keypress(function (e) { 
     if (e.keyCode == 13) {   
     $(this).parent().find(".ui-dialog-buttonpane button:eq(0)").trigger("click");
     return false; 
     }
  }); 
}
0赞 Liam Mitchell 9/11/2014 #22

因为我没有足够的声誉来发表评论。

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

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

  if (e.which === $.ui.keyCode.ENTER && tagName !== 'textarea' && tagName !== 'select' && tagName !== 'button') {
      $(this).find('.ui-dialog-buttonset button').eq(0).trigger('click');
    return false;
  } else if (e.which === $.ui.keyCode.ESCAPE) {
      $(this).close();
  }
});

Basemm #35 修改了答案,也添加了 Escape 以关闭对话框。

-1赞 yPhil 3/1/2018 #23

为您的按钮提供类,并以通常的方式选择它们:

$('#DialogTag').dialog({
  closeOnEscape: true,
  buttons: [
    {
      text: 'Cancel',
      class: 'myCancelButton',
      click: function() {
        // Close dialog fct
      }
    },
    {
      text: 'Ok',
      class: 'myOKButton',
      click: function() {
        // OK fct
      }
    }
  ],
  open: function() {

    $(document).keyup(function(event) {

      if (event.keyCode === 13) {
        $('.myOKButton').click();
      }

    });

  }
});