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

IT技术 javascript jquery jquery-ui
2021-03-17 12:40:07

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

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

6个回答

我不知道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");
      }
    });
  };
});
对于 Webkit(Safari/Chrome),这仅在我执行“keydown”而不是“keyup”时才有效。不确定这是否是最近的更改,或者我的页面上也有真实的表单是否重要。不过,谢谢你的提示!
2021-04-24 12:40:07
绑定到“open:”中的事件是一个坏主意。这将导致它在每次打开对话框时重新绑定,这意味着如果对话框打开两次,事件处理程序将被调用两次。
2021-04-25 12:40:07
我对这个答案投了反对票。虽然它简短而简洁,但在 Firefox 7.0.1 中,如果用户从自动完成下拉框中选择某些内容,例如之前输入的电子邮件地址,这也会触发您的“确定”按钮。
2021-05-06 12:40:07
而不是 if (e.keyCode == 13) 你可以做 if (e.keyCode === $.ui.keyCode.ENTER) 来提高可读性。
2021-05-08 12:40:07
没关系,我找到了:将“打开”添加到对话框(如关闭、模态、bgiframe 等)并将 keyup 处理程序挂在那里。
2021-05-14 12:40:07

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

$(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. 不允许像非相容元素回车键textareaselectbutton或带文字的按钮输入,想象用户点击输入上textarea,并得到越来越提交新的生产线,而不是形式!
  2. 绑定完成一次,避免使用对话框'open'回调来绑定回车键,以避免每次'打开'对话框时一次又一次地绑定相同的函数
  3. 避免更改现有代码,因为上面的一些答案建议
  4. 使用“delegate”而不是已弃用的“live”并避免使用新的“on”方法以允许使用旧版本的 jquery
  5. 因为我们使用了 delegate ,这意味着上面的代码甚至可以在初始化对话框之前编写。即使没有,你也可以把它放在头标签中$(document).ready
  6. 此外,delegate 将只绑定一个处理程序,document而不像上面的某些代码那样将处理程序绑定到每个对话框,以提高效率
  7. 即使使用动态生成的对话框,如 $('<div><input type="text"/></div>').dialog({buttons: .});
  8. 与即 7/8/9 一起工作!
  9. 避免使用慢速选择器 :first
  10. 避免使用这里的答案中的技巧来制作隐藏的提交按钮

缺点:

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

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

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

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

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

干杯。

@David 如果您使用的是 jQuery Dialog 按钮,则只需隐藏表单上的普通输入提交按钮即可。例如。可见性:隐藏;
2021-04-23 12:40:07
如果您的对话框有一个或多个文本输入字段怎么办?当用户在用户名和密码字段中时,我希望 ENTER 提交登录对话框。
2021-05-13 12:40:07

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

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

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

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

我认为那里应该有一个 .first() ,如 $('.ui-dialog').find('button').first().trigger('click'); 否则,如果有多个按钮,您将触发对话框中所有按钮的点击。
2021-04-27 12:40:07
@thejh - 不,它会为每个对话框附加一个 keyup 事件处理程序,但只有包含按下键时具有焦点的元素的对话框才会接收事件。
2021-05-15 12:40:07

您可以绑定到对话框中表单的提交事件,而不是像在这个答案中那样侦听关键代码(我无法开始工作),然后执行以下操作:

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

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

当我在同一个对话框中有三个或更多输入时,这不起作用。不知道为什么。
2021-04-26 12:40:07
这似乎是最优雅的答案。
2021-04-29 12:40:07