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

Posted

技术标签:

【中文标题】在 <Enter> 上提交 jQuery UI 对话框【英文标题】:Submit jQuery UI dialog on <Enter> 【发布时间】:2010-10-26 12:22:22 【问题描述】:

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

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

【问题讨论】:

如果您希望避免使用表单并想要可重用的代码,我在这里提供了一个很好的答案:***.com/a/9628800/329367 【参考方案1】:

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

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

【讨论】:

没关系,我找到了:将“打开”添加到对话框(如关闭、模态、bgiframe 等)并将 keyup 处理程序挂在那里。 对于 Webkit (Safari/Chrome),这仅在我执行“keydown”而不是“keyup”时才有效。不确定这是否是最近的更改,或者我的页面上是否还有真实表格是否重要。不过,感谢您的提示! 你可以用 if (e.keyCode === $.ui.keyCode.ENTER) 代替 if (e.keyCode == 13) 来增加可读性。 我否决了这个答案。虽然它简短而整洁,但在 Firefox 7.0.1 中,如果用户从自动完成下拉框中选择某些内容,这也会触发您的“确定”按钮,例如以前输入的电子邮件地址。 在“open:”中绑定事件是个坏主意。这将导致它在每次打开对话框时重新绑定,这意味着如果对话框打开两次,事件处理程序将被调用两次。【参考方案2】:

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

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

优点:

    不允许在不兼容的元素上输入键,例如 textareaselectbutton 或带有类型按钮的输入,假设用户在 textarea 上单击输入并提交表单而不是换行! 绑定一次完成,避免使用对话框'open'回调绑定回车键,避免每次对话框'open'时重复绑定同一个函数 避免按照上述一些答案的建议更改现有代码 使用 'delegate' 而不是已弃用的 'live' 并避免使用新的 'on' 方法以允许使用旧版本的 jquery 因为我们使用了委托,这意味着甚至可以在初始化对话框之前编写上面的代码。即使没有$(document).ready,您也可以将其放入 head 标签中 此外,为了提高效率,delegate 只会将一个处理程序绑定到document,并且不会像上面的某些代码那样将处理程序绑定到每个对话框。 甚至可以使用动态生成的对话框,例如$('&lt;div&gt;&lt;input type="text"/&gt;&lt;/div&gt;').dialog(buttons: .); 与 ie 7/8/9 合作! 避免使用慢速选择器:first 避免使用类似答案here 的技巧来制作隐藏的提交按钮

缺点:

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

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

【讨论】:

这不是公认的答案并且没有更多选票的事实让我感到难过,最多信息并且不会不断添加处理程序。 +1 很好的答案,你要避免打开回调来添加绑定 对我来说,这在事件为 keydown 时有效,我删除了 tagName 的所有条件并删除了点击触发器 我还必须更改为“keydown”才能完成这项工作(在 OS X 10.8.4、Chrome 29 和 Firefox 23 上测试)。 由于这是一个较旧的答案,值得注意的是 .delegate() 在 jQuery 3.0 中已被弃用,因此 .on()(自 1.7 起可用)可能是此时的路线。【参考方案3】:
$('#dialogBox').dialog('open');
$('.ui-dialog-buttonpane > button:last').focus();

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

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

干杯。

【讨论】:

如果您的对话框有一个或多个文本输入字段怎么办?当用户在用户名和密码字段中时,我希望 ENTER 提交登录对话框。 @David 如果您使用的是 jQuery 对话框按钮,那么只需隐藏表单上的正常输入提交按钮。例如。可见性:隐藏;【参考方案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 选择器。

【讨论】:

我认为那里应该有一个 .first() ,如 $('.ui-dialog').find('button').first().trigger('click');否则,如果有多个按钮,您将触发单击对话框的所有按钮。 @thejh - 不,它为每个对话框附加一个 keyup 事件处理程序,但只有在按下键时包含焦点元素的对话框才会接收事件。【参考方案5】:

您可以在对话框中绑定到表单的提交事件,然后执行以下操作:

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

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

【讨论】:

这似乎是最优雅的答案。 当我在同一个对话框中有三个或更多输入时,这不起作用。不知道为什么。【参考方案6】:

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

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

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

    您要添加“return false;”防止违约并停止 传播。

在这种情况下...

$('body').on('keypress', '.ui-dialog', function(event)  
    if (event.keyCode === $.ui.keyCode.ENTER)  
        $('.ui-dialog-buttonpane button:first', $(this)).click();
        return false;
    
);

【讨论】:

【参考方案7】:

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

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

编辑:我假设您希望能够在填写表单元素的任何时候按 Enter 键,并优先考虑“当前”按钮操作。如果您只希望在按钮实际获得焦点时出现这种行为,那么我的回答太复杂了。

【讨论】:

【参考方案8】:

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

它基于罗伯特·施密特的评论。

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

希望对大家有帮助。

【讨论】:

谢谢!这为我节省了很多时间! :) 简单有效。最好的答案在这里。为什么在地球上没有将按钮设为默认按钮的选项,我不知道。【参考方案9】:

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

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

这将导致 ENTER 键提交表单。

【讨论】:

【参考方案10】:

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

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

【讨论】:

【参考方案11】:

这应该可以触发按钮的点击处理程序的点击。此示例假定您已经在对话框中设置了表单以使用 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...

            

【讨论】:

【参考方案12】:

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

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

【讨论】:

谢谢你的更新,只是一个小问题,这里的“.ok-button”是什么?它是你必须在你想用回车点击的默认按钮上应用的类吗? 对不起,如果你发现这个问题很愚蠢.. m 在 JS/jQuery 中太新了 @BenClayton :如果您将其放在 jQueryUI 对话框的上下文中,则可以改进此答案。【参考方案13】:

这是我所做的:

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 对象(请注意,那里没有任何“表单”标签...如果您将它们放在整个屏幕中,当您按“输入”时会刷新) .

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

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

【讨论】:

这是最合乎逻辑的解决方案。如果您使用 id 声明按钮并将选择器传递给 find() 则更好,但任何一种方式都有效。 +1【参考方案14】:

做完了

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

【讨论】:

【参考方案15】:

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

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

应该为您解决问题。正如您所期望的那样,这将聚焦 ok 按钮,然后 enter 将“单击”它。这与原生 UI 对话框中使用的技术相同。

【讨论】:

【参考方案16】:
   $("#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();
   );

【讨论】:

【参考方案17】:

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

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

【讨论】:

【参考方案18】:
$('#DialogID').dialog("option", "buttons")["TheButton"].apply()

这对我很有用..

【讨论】:

最好包含对 $('#DialogID').dialog() 的引用作为应用的参数。否则 $(this).close() 在 TheButton 内将没有正确的上下文。【参考方案19】:

这些解决方案在 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");
                   ;
               );
    
);

【讨论】:

【参考方案20】:

使用下面的body是因为在body上添加了dialog 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; 
     
  ); 

【讨论】:

【参考方案21】:

因为我没有足够的声望来发布 cmets。

$(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 以关闭对话框。

【讨论】:

【参考方案22】:

很好用,谢谢!!!

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

【讨论】:

hmm ...您的帖子中有什么新内容(与之前的答案相比)吗?【参考方案23】:

给你的按钮classes 并按照通常的方式选择它们:

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

    );

  
);

【讨论】:

以上是关于在 <Enter> 上提交 jQuery UI 对话框的主要内容,如果未能解决你的问题,请参考以下文章

使用 javascript 在 Enter 键上提交表单

通过在 struts-dojo 自动完成上按 enter 键来防止表单提交

ctrl+enter提交留言

使用 AngularJS 按 Enter 提交表单

如何在使用 Blazor <InputText> 时禁用 ENTER 键按下提交按钮

如何禁用转到下一个字段并在 Android 上的 keyCode == “enter” (13) 上提交表单